Search code examples
rshinytagsshinywidgets

How to style RShiny switchInput when it is inside a uiOutput?


I've previously used the following style tags in my UI to style a switchInput from ShinyWidgets:

#switchInput color while on
  tags$head(tags$style(HTML('.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger,
                                       .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger {
                                        background: #eef4fa;
                                        color: black;
                                        }'))),
  
  #switchInput color while off
  tags$head(tags$style(HTML('.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success,
                                       .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success {
                                        background: #fdf1f1;
                                        color: black;
                                        }'))),

However, now that I have rendered the switches as a uiOutput and then renderUI, it seems that these tags are not recognised.

How do I style the on and off versions of the switch when they are made via uiOutput rather than just put directly into the ui?

library(shiny)
library(shinyjs)
library(bslib)
library(shinyBS)
library(shinyWidgets)

ui <- fluidPage(
  
  #switchInput color while on
  tags$head(tags$style(HTML('.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger,
                                       .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger {
                                        background: #eef4fa;
                                        color: black;
                                        }'))),
  
  #switchInput color while off
  tags$head(tags$style(HTML('.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success,
                                       .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success {
                                        background: #fdf1f1;
                                        color: black;
                                        }'))),

  
  fluidRow(
    column(2,
           offset = 5,
           align = "center",
           uiOutput('log_axis_output')
    )),
    

)

server <- function(input, output) {
  
  output$log_axis_output <- renderUI({
    
    switchInput(
      inputId = "log_axis1",
      offLabel = "Log X\naxis?",
      onLabel = "Normal\nX axis",
      value = FALSE,
      offStatus = "success", 
      onStatus = "danger",
      disabled = FALSE)
    
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

Solution

  • It's not a problem with the R code. It's the problem with your CSS code.

    Your CSS selectors don't have enough priority as the original style selectors.

    to fix, change to following:

        tags$head(tags$style(HTML('.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger,
                                           .bootstrap-switch .bootstrap-switch-container .bootstrap-switch-handle-on.bootstrap-switch-danger {
                                            background: #eef4fa;
                                            color: black;
                                            }'))),
        
        #switchInput color while off
        tags$head(tags$style(HTML('.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success,
                                           .bootstrap-switch .bootstrap-switch-container .bootstrap-switch-handle-off.bootstrap-switch-success {
                                            background: #fdf1f1;
                                            color: black;
                                            }'))),
    

    I added the .bootstrap-switch-container in the middle to increase the specificity level. Read more about how to calculate CSS specificity.

    Another way is to use !important, but it is not generally recommended.

    enter image description here

    enter image description here