CSS R Shiny 中的每个页面
CSS for each page in R Shiny
我已经编写了一个 R 闪亮的应用程序,并在完成它之前对其进行了样式设置。我已经写了少量 HTML 并想使用 CSS 更改背景颜色等内容。
在网上咨询后,我发现我需要使用 class 参数来分隔我的 css,但是当我为每个页面指定一个 class 时,它根本不会返回任何 CSS。
下面是我的 R shiny 应用程序的简化版本。任何帮助将不胜感激。
library(shiny)
setwd("C:\Users\FRSAWG\Desktop\Application\Shiny")
user <- shinyUI(navbarPage("",
tabPanel("Home Page",
div(class="one",
div(tags$style("#one body{background-color:blue;color:white;font-family:Arial}"),
div(HTML("<h1><b><center>Home Page</center></b></h1>"))))),
tabPanel("Glossary",
div(class="two",
div(tags$style("#two body{background-color:red;color:white;font-family:Arial}"),
div(HTML("<h1><b><center>Glossary</center></b></h1>")))))
))
serv <- shinyServer(function(input, output) {})
shinyApp(user, serv)
作为参考,我为每个页面指定了 一个 和 两个 class 个名称。
更新: 使用 Dean Attali (link) 的包 shinyjs
,我编写了一个辅助函数,您可以从 R 调用它来创建和运行 一个 jQuery 函数,用于根据 R 语法的输入修改给定对象(或一般选择器)的 CSS 元素。当标签更改时,您可以使用它来修改<body>
的CSS。
这解决了我之前建议的问题 - 现在无需切换主体的 class,这有时会在一瞬间所有样式 classes 时导致闪烁<body>
已关闭。
这是工作示例:
library(shiny)
library(shinyjs)
## Modify the CSS style of a given selector
modifyStyle <- function(selector, ...) {
values <- as.list(substitute(list(...)))[-1L]
parameters <- names(values)
args <- Map(function(p, v) paste0("'", p,"': '", v,"'"), parameters, values)
jsc <- paste0("$('",selector,"').css({", paste(args, collapse = ", "),"});")
shinyjs::runjs(code = jsc)
}
# UI for the app
user <- shinyUI(
navbarPage(title = "", id = "navtab",
header = div(useShinyjs()),
tabPanel("Home Page",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
)
)
# Server for the app
serv <- shinyServer(function(input, output, session) {
observeEvent(input$navtab, {
currentTab <- input$navtab # Name of the current tab
if (currentTab == "Home Page") {
modifyStyle("body", background = "blue", color = "white", 'font-family' = "Arial")
}
if (currentTab == "Glossary") {
modifyStyle("body", background = "red", color = "white", 'font-family' = "Arial")
}
})
})
shinyApp(user, serv)
我自己是 CSS 的新手,但您的问题似乎可以通过稍微更改 CSS 标签来解决。将 #one
更改为 .one
并删除括号前的 body
将使 CSS 样式应用于 class 的 div one
.
使用选择器 #one
会改变 div 的 CSS 样式,其 id,而不是 class,是 one
。这是 link 到 a guide on w3shools.com 解释了 CSS 语法中不同选择器的使用。
一些其他注意事项:
- 您也可以使用
tags$head
来组织您的样式标签
一个地方,而不是将它们散布在代码周围。 (不过,这取决于个人喜好。)
- 您可以将
class
参数传递给 tabPanel
以设置其 CSS class - 这消除了内部 div 设置class.
修改后的示例代码:
library(shiny)
user <- shinyUI(navbarPage(
tags$head(
tags$style(HTML(".one {background-color: blue; color: white; font-family: Arial}")),
tags$style(HTML(".two {background-color: red; color: white; font-family: Arial}"))
),
tabPanel("Home Page", class = "one",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary", class = "two",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
))
serv <- shinyServer(function(input, output) {})
shinyApp(user, serv)
就像我提到的,我是 CSS 的新手,所以我不能 100% 确定这是否是您正在寻找的输出。
EDIT2: 这里有一个解决方案,使用包 shinyjs
在所选选项卡更改时更新 <body>
的 class。 (请注意,为了使用 shinyjs
中的函数,您需要在 ui 中包含 useShinyjs()
。)
想法是通过将其 ID 设置为 navtab
,使 navbarPage
return 成为当前在 input$navtab
中活动的选项卡的名称。然后我们可以使用包 shinyjs
中的 toggleClass
函数来动态更改 <body>
的 class,从而应用适当的 CSS 样式。
它并不完美,因为 class 更改仅在服务器收到选项卡已更改的通知后发生,这有时会导致背景在更改前闪烁。它可能会有点烦人。我怀疑更好的解决方案是在单击 link 更改选项卡时使用 javascript 更改 <body>
class,但我不知道该怎么做闪亮的。
代码如下:
library(shiny)
library(shinyjs)
user <- shinyUI(
navbarPage(title = "", id = "navtab",
header = tags$head(
useShinyjs(),
tags$style(HTML(".one {background: blue; color: white; font-family: Arial}")),
tags$style(HTML(".two {background: red; color: white; font-family: Arial}"))
),
tabPanel("Home Page",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
)
)
serv <- shinyServer(function(input, output, session) {
observeEvent(input$navtab, {
shinyjs::toggleClass(selector = "body", class = "one",
condition = (input$navtab == "Home Page"))
shinyjs::toggleClass(selector = "body", class = "two",
condition = (input$navtab == "Glossary"))
})
})
shinyApp(user, serv)
我已经编写了一个 R 闪亮的应用程序,并在完成它之前对其进行了样式设置。我已经写了少量 HTML 并想使用 CSS 更改背景颜色等内容。 在网上咨询后,我发现我需要使用 class 参数来分隔我的 css,但是当我为每个页面指定一个 class 时,它根本不会返回任何 CSS。
下面是我的 R shiny 应用程序的简化版本。任何帮助将不胜感激。
library(shiny)
setwd("C:\Users\FRSAWG\Desktop\Application\Shiny")
user <- shinyUI(navbarPage("",
tabPanel("Home Page",
div(class="one",
div(tags$style("#one body{background-color:blue;color:white;font-family:Arial}"),
div(HTML("<h1><b><center>Home Page</center></b></h1>"))))),
tabPanel("Glossary",
div(class="two",
div(tags$style("#two body{background-color:red;color:white;font-family:Arial}"),
div(HTML("<h1><b><center>Glossary</center></b></h1>")))))
))
serv <- shinyServer(function(input, output) {})
shinyApp(user, serv)
作为参考,我为每个页面指定了 一个 和 两个 class 个名称。
更新: 使用 Dean Attali (link) 的包 shinyjs
,我编写了一个辅助函数,您可以从 R 调用它来创建和运行 一个 jQuery 函数,用于根据 R 语法的输入修改给定对象(或一般选择器)的 CSS 元素。当标签更改时,您可以使用它来修改<body>
的CSS。
这解决了我之前建议的问题 - 现在无需切换主体的 class,这有时会在一瞬间所有样式 classes 时导致闪烁<body>
已关闭。
这是工作示例:
library(shiny)
library(shinyjs)
## Modify the CSS style of a given selector
modifyStyle <- function(selector, ...) {
values <- as.list(substitute(list(...)))[-1L]
parameters <- names(values)
args <- Map(function(p, v) paste0("'", p,"': '", v,"'"), parameters, values)
jsc <- paste0("$('",selector,"').css({", paste(args, collapse = ", "),"});")
shinyjs::runjs(code = jsc)
}
# UI for the app
user <- shinyUI(
navbarPage(title = "", id = "navtab",
header = div(useShinyjs()),
tabPanel("Home Page",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
)
)
# Server for the app
serv <- shinyServer(function(input, output, session) {
observeEvent(input$navtab, {
currentTab <- input$navtab # Name of the current tab
if (currentTab == "Home Page") {
modifyStyle("body", background = "blue", color = "white", 'font-family' = "Arial")
}
if (currentTab == "Glossary") {
modifyStyle("body", background = "red", color = "white", 'font-family' = "Arial")
}
})
})
shinyApp(user, serv)
我自己是 CSS 的新手,但您的问题似乎可以通过稍微更改 CSS 标签来解决。将 #one
更改为 .one
并删除括号前的 body
将使 CSS 样式应用于 class 的 div one
.
使用选择器 #one
会改变 div 的 CSS 样式,其 id,而不是 class,是 one
。这是 link 到 a guide on w3shools.com 解释了 CSS 语法中不同选择器的使用。
一些其他注意事项:
- 您也可以使用
tags$head
来组织您的样式标签 一个地方,而不是将它们散布在代码周围。 (不过,这取决于个人喜好。) - 您可以将
class
参数传递给tabPanel
以设置其 CSS class - 这消除了内部 div 设置class.
修改后的示例代码:
library(shiny)
user <- shinyUI(navbarPage(
tags$head(
tags$style(HTML(".one {background-color: blue; color: white; font-family: Arial}")),
tags$style(HTML(".two {background-color: red; color: white; font-family: Arial}"))
),
tabPanel("Home Page", class = "one",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary", class = "two",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
))
serv <- shinyServer(function(input, output) {})
shinyApp(user, serv)
就像我提到的,我是 CSS 的新手,所以我不能 100% 确定这是否是您正在寻找的输出。
EDIT2: 这里有一个解决方案,使用包 shinyjs
在所选选项卡更改时更新 <body>
的 class。 (请注意,为了使用 shinyjs
中的函数,您需要在 ui 中包含 useShinyjs()
。)
想法是通过将其 ID 设置为 navtab
,使 navbarPage
return 成为当前在 input$navtab
中活动的选项卡的名称。然后我们可以使用包 shinyjs
中的 toggleClass
函数来动态更改 <body>
的 class,从而应用适当的 CSS 样式。
它并不完美,因为 class 更改仅在服务器收到选项卡已更改的通知后发生,这有时会导致背景在更改前闪烁。它可能会有点烦人。我怀疑更好的解决方案是在单击 link 更改选项卡时使用 javascript 更改 <body>
class,但我不知道该怎么做闪亮的。
代码如下:
library(shiny)
library(shinyjs)
user <- shinyUI(
navbarPage(title = "", id = "navtab",
header = tags$head(
useShinyjs(),
tags$style(HTML(".one {background: blue; color: white; font-family: Arial}")),
tags$style(HTML(".two {background: red; color: white; font-family: Arial}"))
),
tabPanel("Home Page",
div(HTML("<h1><b><center>Home Page</center></b></h1>")),
"More text."
),
tabPanel("Glossary",
div(HTML("<h1><b><center>Glossary</center></b></h1>")),
"More text."
)
)
)
serv <- shinyServer(function(input, output, session) {
observeEvent(input$navtab, {
shinyjs::toggleClass(selector = "body", class = "one",
condition = (input$navtab == "Home Page"))
shinyjs::toggleClass(selector = "body", class = "two",
condition = (input$navtab == "Glossary"))
})
})
shinyApp(user, serv)