15

I would like to customize a shiny application using tabsetPanels so that the selected panel appears in a black background with white text, and the unselected tabs show a white background with black text.

For example, In the application below, when the "Hello" tab is selected, I would like "Hello" to be in white text on a black background. But I still want the background of the panel content (the input field) to remain white.

The closest thing I've been able to find come from this question: Tab Box CSS for shinydashboard

Applying that code yields a colored background all the way across the tabsetPanel, but I still can't find a way to modify this to change the background of only the tabs. Furthermore, nothing I change in the .nav-tabs-custom css seems to take any effect whatsoever.

I'm continually tempted to try applying changes to the tab-pane tag CSS, but that pushes changes into the body of the tab, not the title box.

Any ideas on what I could change to get the title boxes to change background color?

ui <- shinyUI(
  fluidPage(
    tags$style(".nav-tabs {
  background-color: #006747;
    }

.nav-tabs-custom .nav-tabs li.active:hover a, .nav-tabs-custom .nav-tabs li.active a {
background-color: transparent;
border-color: transparent;
}

.nav-tabs-custom .nav-tabs li.active {
    border-top-color: #FFF;
}"),
    tabsetPanel(
      tabPanel(
        title = "Hello",
        textInput(inputId = "text", label = "Input")
      ),
      tabPanel(
        title = "World"
      )
    )
  )
)

server <- shinyServer(function(input, output, session){


})

shinyApp(ui=ui, server=server)
Community
  • 1
  • 1
Benjamin
  • 16,897
  • 6
  • 45
  • 65

2 Answers2

34

The above example is broken apparently (from version 0.14.0), probably due to a Shiny css change. Additionally the title of the post promises more than the actual question and solution actually covered. So I wrote a new more comprehensive example.

  • It sets the default tab background to be aqua and black text.
  • It sets the color of several tabs to be explicit colors (when they are not active) with white text.
  • It sets the active tab background to be black with white text.

Whether or not all these colors are a good idea from a UI point of view is another question...

Here is the code:

library(shiny)
ui <-shinyUI(fluidPage(
  h1("Colored Tabs"),
  tags$style(HTML("
    .tabbable > .nav > li > a                  {background-color: aqua;  color:black}
    .tabbable > .nav > li > a[data-value='t1'] {background-color: red;   color:white}
    .tabbable > .nav > li > a[data-value='t2'] {background-color: blue;  color:white}
    .tabbable > .nav > li > a[data-value='t3'] {background-color: green; color:white}
    .tabbable > .nav > li[class=active]    > a {background-color: black; color:white}
  ")),
  tabsetPanel(
    tabPanel("t0",h2("normal tab")),
    tabPanel("t1",h2("red tab")),
    tabPanel("t2",h2("blue tab")), 
    tabPanel("t3",h2("green tab")),
    tabPanel("t4",h2("normal tab")),
    tabPanel("t5",h2("normal tab"))
  )
))
server <- function(input, output) {}
shinyApp(ui=ui,server=server)

Here is a screen shot:

enter image description here

And in case this breaks again, and the code has to be adjusted, here is the current css/html that is producing this:

<body>
  <div class="container-fluid">
    <h1>Colored Tabs</h1>
    <style>
    .tabbable > .nav > li > a                  {background-color: aqua;  color:black}
    .tabbable > .nav > li > a[data-value='t1'] {background-color: red;   color:white}
    .tabbable > .nav > li > a[data-value='t2'] {background-color: blue;  color:white}
    .tabbable > .nav > li > a[data-value='t3'] {background-color: green; color:white}
    .tabbable > .nav > li[class=active]    > a {background-color: black; color:white}
  </style>
    <div class="tabbable">
      <ul class="nav nav-tabs">
        <li class="active">
          <a href="#tab-5851-1" data-toggle="tab" data-value="t0">t0</a>
        </li>
        <li>
          <a href="#tab-5851-2" data-toggle="tab" data-value="t1">t1</a>
        </li>
        <li>
          <a href="#tab-5851-3" data-toggle="tab" data-value="t2">t2</a>
        </li>
        <li>
          <a href="#tab-5851-4" data-toggle="tab" data-value="t3">t3</a>
        </li>
        <li>
          <a href="#tab-5851-5" data-toggle="tab" data-value="t4">t4</a>
        </li>
        <li>
          <a href="#tab-5851-6" data-toggle="tab" data-value="t5">t5</a>
        </li>
      </ul>
      <div class="tab-content">
        <div class="tab-pane active" data-value="t0" id="tab-5851-1">
          <h2>normal tab</h2>
        </div>
        <div class="tab-pane" data-value="t1" id="tab-5851-2">
          <h2>red tab</h2>
        </div>
        <div class="tab-pane" data-value="t2" id="tab-5851-3">
          <h2>blue tab</h2>
        </div>
        <div class="tab-pane" data-value="t3" id="tab-5851-4">
          <h2>green tab</h2>
        </div>
        <div class="tab-pane" data-value="t4" id="tab-5851-5">
          <h2>normal tab</h2>
        </div>
        <div class="tab-pane" data-value="t5" id="tab-5851-6">
          <h2>normal tab</h2>
        </div>
      </div>
    </div>
  </div>
</body>
Mike Wise
  • 22,131
  • 8
  • 81
  • 104
  • Do you happen to recall in which version of shiny this change was made? – Benjamin Apr 04 '17 at 08:59
  • No idea really. And now seeing how recent the jenesalsquoi's answer is, I wonder if this is even the whole story. – Mike Wise Apr 04 '17 at 09:11
  • 2
    I just systematically went through all of the versions since 0.13.0 (the version I am currently using in my production environment). The entire 13 series works with the @jenesalsquoi's answer, but your answer is needed starting in the 14 series. Would you mind adding a note to your answer indicating that this is the correct answer for 0.14 and higher? – Benjamin Apr 04 '17 at 11:12
  • Thanks for doing that. I looked at the source and couldn't figure out why it changed since "tabbable" has been in there for years. – Mike Wise Apr 04 '17 at 11:15
  • 1
    It was selfishly motivated. I'm going to be updating my libraries in a couple months, and I'll need to include these changes in my implementation plan. This proved to be very timely for me. I'm glad you came across it. – Benjamin Apr 04 '17 at 11:17
  • I tried to answer this question (http://stackoverflow.com/questions/43131595/how-to-change-each-tab-background-color-on-tabpanels-in-r-shiny#comment73466224_43131595) and it got duphammered out from under me because of the question and answer here. That was my motivation. – Mike Wise Apr 04 '17 at 11:20
  • Has to be `tabsetPanel` does not play well with `shinydashboard::tabBox/shiny::tabPanel` – kraggle Aug 23 '23 at 17:08
8

EDIT: for shiny versions >= 0.14 see here.

If you select the link with an 'active' class as an immediate descendant of the nav I think you can get what you're after. The UI would look like

ui <- shinyUI(
    fluidPage(
        tags$style(HTML("
        .tabs-above > .nav > li[class=active] > a {
           background-color: #000;
           color: #FFF;
        }")),
        tabsetPanel(
            tabPanel(
                title = "Hello",
                textInput(inputId = "text", label = "Input")
            ),
            tabPanel(
                title = "World"
            )
        )
    )
)

enter image description here

Community
  • 1
  • 1
Rorschach
  • 31,301
  • 5
  • 78
  • 129
  • 1
    That does it! For my future reference, I can customize the unselected tabs with `.tabs-above > .nav > li > a`. Thanks so much. – Benjamin Jan 27 '16 at 01:12
  • Thanks very usefull I want to do it for a shinydashboard have i to create a fluidpage ? – Mostafa90 Feb 23 '17 at 18:15
  • 1
    @DimitriPetrenko I haven't used shiny in a while, you may want to ask a new question – Rorschach Feb 23 '17 at 19:06
  • I find the solution thanks :) in the tabBox argument we have to add `value = pills` – Mostafa90 Feb 24 '17 at 10:23
  • 4
    This no longer works. Seems like the "tabs-above" class has changed its name to "tabbable" now - changing that class selector fixes it. – Mike Wise Apr 03 '17 at 15:55
  • This works in 0.13.0 - 0.13.2. I assume it will work in earlier versions, but I haven't tested it. – Benjamin Apr 04 '17 at 11:12