Search code examples
cssrshinynavbarnav

How to change text colour of links in navbar header AND links in nav pills (in shiny app)?


Here is a redacted version of my shiny app:

library(shiny)
library(bslib)

ui <- tagList(
  fluidPage(
    titlePanel(""),
    tags$head(tags$style(HTML(
      "
        .navbar-default {
            color: red !important;'
        }
        .navbar-default .navbar-nav > .active > a,
        .navbar-default .navbar-nav > li > a:hover {
            color: red !important;
        }
        .navbar-default .navbar-nav > li > a {
            color: pink !important;
        }
        "
    ))),
    
    navbarPage(
      windowTitle = "App Name",
      theme = bs_theme(bootswatch = "flatly",
                       base_font = font_google("Lato"),
                       primary = "#333F50",
                       bg = "white",
                       fg = "#D67540"),
      title = "I am the title",
      selected = "Main Tab 1",
      tabPanel(title = "Main Tab 1",
               fluidPage(
                 sidebarLayout(
                   sidebarPanel(textInput(inputId = "text_input", label = "Enter text:")),
                   mainPanel(textOutput(outputId = "text_output"))
                 )
               )
               ),
      tabPanel(title = "Main Tab 2",
               fluidPage(
                   fluidRow(
                     column(7,
                            navlistPanel(
                              tabPanel("Tab 1"),
                              tabPanel("Tab 2"),
                              tabPanel("Tab 3"),
                              widths = c(2, 10),
                              well = FALSE)
                            )))
               )
      )
    )
  )

server <- function(input, output){
  output$text_output <- renderText(input$text_input)
}

shinyApp(ui, server)

Currently the text for "Main Tab 1" and "Main Tab 2" is pink and red when hovered/selected.

Main Tab 1

I would also like to apply a similar change to "Tab 1", "Tab 2" and "Tab 3" - for these I want the text colour to change from teal to black and from white to orange when hovered/selected.

My understanding is that the !important next to the color value forces all links to inherit the same properties, but I would like different colours for the links in the navbar header and the links in the nav-pills.

I have asked a related question here: How to change text colour of navbarPage links when hovered on (in shiny app)?

How can I make this change?

Any help is much appreciated :)

Note: Colours are intentionally not aesthetic (just using these for distinction as I'm still learning)


Solution

  • Ok - I've implemented your request, but see both parts of my answer:

    Part 1 - The Solution

    To implement your requested styles, I did two things:

    1. I changed your navListPanel by inserting it into a tags$div with the class name side_panel. I housed this navlistPanel in a div with a custom class so that the CSS you wanted for the panel didn't bleed into other .nav classes, including the main .nav-header.
    tags$div(
      navlistPanel(
        tabPanel("Tab 1"),
        tabPanel("Tab 2"),
        tabPanel("Tab 3"),
        widths = c(2, 10),
        well = FALSE),
      class = "side_panel"
    )
    
    1. I then added the following CSS to your tags$style, starting each line with .side_panel to only affect the class we just created:
    .side_panel .nav-pills a:hover {
        color: black; 
        background: rgba(253,126,20, 0.8);
    }
    
    .side_panel .nav-pills .nav-link.active {
      color: black;
      background: #fd7e14; /* BS orange */
    }
    

    Achieving this result (Note: "Tab 2" is being hovered over, the screenshot didn't capture my mouse):

    enter image description here

    Part 2 - Future Styling

    As it seems like you're particular about the style of your app (don't worry, I'm obsessive about this type of styling too), you should consider two things.

    1. Rather than inserting all of your CSS at the beginning of your app, consider creating a separate style.css file located in a www folder. This www folder should be in the same directory as your app.R file. You can then inject all of this CSS into your app using shiny::includeCSS("www/style.css") (ref link).

    2. To learn how to stylize custom components of your Shiny apps in the future, you should familiarize yourself with the Inspect feature of your browser. I mostly use bs4Dash in my apps, so I wasn't as familiar with your app's html components. To find the objects and their CSS, I simply inspected the webpage (right click + inspect) and use ctrl+shift+c to click on the tabs and view their CSS. Going one step further, you can change the style of the CSS on the fly by typing in custom values.

    Good luck!