R Shiny中每个页面的CSS [英] CSS for each page in R Shiny

查看:57
本文介绍了R Shiny中每个页面的CSS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一个R闪亮的应用程序,并在完成之前对其进行了样式设置.我已经编写了少量的HTML,并且希望使用CSS来更改诸如背景色之类的内容.在线咨询之后,我发现我需要使用class参数来分隔css,但是当我为每个页面指定一个类时,它根本不会带回CSS.

下面是我的R Shiny应用程序的简化版本.任何帮助将不胜感激.

 库(发光)setwd("C:\\ Users \\ FRSAWG \\ Desktop \\ Application \\ Shiny")用户<-ShinyUI(navbarPage(",tabPanel(主页",div(class ="one",div(tags $ style(#one body {background-color:blue; color:white; font-family:Arial}"),div(HTML(< h1> b< center"首页</center</b</h1"))))))tabPanel(词汇表",div(class ="two",div(tags $ style(#two body {background-color:red; color:white; font-family:Arial}"),div(HTML(< h1> b< center>词汇表//center</b</h1")))))))serv<-ShinyServer(function(input,output){})ShinyApp(用户,serv) 

作为参考,我为每个页面指定了一个两个类名.

解决方案

更新:使用Dean Attali(


我本人是CSS的新手,但是似乎可以通过稍微更改CSS标签来解决您的问题.将 #one 更改为 .one ,并删除方括号前面的 body ,将使CSS样式应用于类的div.一个.

使用选择器 #one 将更改 id (而不是类)为 one 的div的CSS样式.这是有关w3shools.com的指南的链接,该链接说明了CSS语法中不同选择器的用法

其他一些注意事项:

  • 您还可以使用 tags $ head 在以下位置组织样式标签一个地方,而不是在代码周围散布它们.(不过,这取决于个人喜好.)
  • 您可以将 class 参数传递给 tabPanel 来设置其CSS类-这样就无需内部div来设置该类.

修改后的示例代码:

 库(发光)用户<-ShinyUI(navbarPage(标签$ 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(首页",类=一个",div(HTML(< h1> b< center>首页</center</b>/b</h1"))),更多文字."),tabPanel("Glossary",class ="two",div(HTML(< h1> b< center" Glossary</center</b</h1"")),更多文字.")))serv<-ShinyServer(function(input,output){})ShinyApp(用户,serv) 

就像我提到的那样,我是CSS的新手,所以我不确定100%是否是您要查找的输出.

EDIT2 :这是一个使用软件包 shinyjs 来在所选标签页更改时更新< body> 的类的解决方案.(请注意,为了使用 shinyjs 中的功能,您需要在用户界面中包含 useShinyjs().)

想法是通过将其ID设置为 navtab ,使 navbarPage 返回当前在 input $ navtab 中处于活动状态的选项卡的名称.然后,我们可以使用软件包 shinyjs 中的 toggleClass 函数来动态更改< body> 的类,从而获得适当的CSS样式.

这不是完美的,因为类更改仅在通知服务器选项卡已更改后才发生,这有时会导致背景在更改之前闪烁.可能会有点烦人.我怀疑更好的解决方案是在单击链接更改选项卡时使用javascript更改< body> 类,但我不知道如何使用Shiny做到这一点.

这是代码:

 库(发光)图书馆(shinyjs)用户<-ShinyUI(navbarPage(title =",id ="navtab",标头=标签$ 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(主页",div(HTML(< h1> b< center>首页</center</b>/b</h1"))),更多文字."),tabPanel(词汇表",div(HTML(< h1> b< center" Glossary</center</b</h1"")),更多文字.")))serv<-ShinyServer(function(input,output,session){watchEvent(input $ navtab,{Shinyjs :: toggleClass(s​​elector ="body",class ="one",条件=(input $ navtab ==主页"))Shinyjs :: toggleClass(s​​elector ="body",class ="two",条件=(input $ navtab ==词汇表")})})ShinyApp(用户,serv) 

I've written an R shiny application and am styling it before I complete it. I've written a small amount of HTML and want to change things such as the background colour using CSS. After consulting online I found I needed to seperate my css using the class argument, however when I specify a class for each page, it brings back no CSS at all.

Below is a shortened version of my R shiny application. Any help would be greatly appreciated.

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)

For reference I've designated one and two the class names for each of the pages.

解决方案

UPDATE: Using the package shinyjs by Dean Attali (link), I wrote a helper function that you can call from R to create and run a jQuery function to modify the CSS element of a given object (or selector, in general) based on input from R syntax. You can use this to modify the CSS for your <body> when the tab changes.

This solves the problem with my previous suggestion - now there's no need to toggle the class of the body, which was sometimes causing flickering when for a split second all of the style classes for <body> were toggled off.

Here's the working example:

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)


I'm new to CSS myself, but it seems your problem can be fixed by just altering the CSS tags slightly. Changing the #one to .one and removing the body preceding the brackets will make the CSS style get applied to the divs of class one.

Using the selector #one would be changing the CSS style of a div whose id, not class, is one. Here's a link to a guide on w3shools.com explaining the use of different selectors in CSS syntax.

Some other notes:

  • You could also use a tags$head to organize your style tags in one place, instead of spreading them around the code. (This is down to personal preference, though.)
  • You can pass a class argument to tabPanel to set its CSS class - this removes the need for the inner div to set the class.

Modified example code:

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)

Like I mentioned, I'm new to CSS, so I'm not 100% sure if this is the output you are looking for, though.

EDIT2: Here's a solution using the package shinyjs to update the class of the <body> when the selected tab changes. (Note that in order to use the functions from shinyjs, you need to include useShinyjs() in your ui.)

The idea is to make navbarPage return the name of the tab that's currently active in input$navtab by setting its id to navtab. Then we can use the toggleClass function from the package shinyjs to change the class of the <body> dynamically, and thus have the appropriate CSS styling applied.

It's not perfect, since the class change only happens after the server gets notified that the tab has changed, which sometimes causes the background to flash before changing. It can get a bit annoying. I suspect a better solution would be to use javascript to change the <body> class when clicking the link to change the tab, but I couldn't figure out how to do that with Shiny.

Here's the code:

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 Shiny中每个页面的CSS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆