cssrshinyradio-buttonquarto

How to change default radioButtons() color from blue to gold in a Quarto Shiny dashboard?


I'm building a Quarto dashboard with Shiny runtime and using a plain radioButtons() control in the sidebar:

---
title: "Quarto Dashboard with Radio Buttons"
format:
  html:
    theme: cosmo
runtime: shiny
execute:
  echo: false
include-before-body:
  - text: |
      <link rel="stylesheet" href="www/my_css.css">
---
```{r}
shiny::radioButtons(
  inputId = "choice",
  label = "Select an option:",
  choices = list(
   "Option A" = "A",
    "Option B" = "B",
    "Option C" = "C"
  ),
  selected = "A"
)
```

By default, the selected circle and label highlight are rendered in Bootstrap's primary blue. I'd like to change this to gold, but there doesn't appear to be any argument in radioButtons() (and I can’t switch to groupedButtons) that controls the color.

enter image description here

I've tried adding a custom CSS file:

CSS file

/* www/custom.css */
.radio input[type="radio"]:checked + label::before {
  border-color: gold !important;
  background-color: gold !important;
}

… but it still shows the default blue. What CSS selectors or Quarto/Shiny settings can I use to override the blue and render the radio button in gold?

Desired output:

enter image description here


Solution

  • You can wrap the buttons with fluidPage and add your own style within. Here I followed this great tutorial and added some animations too ;) - added some notes to the css on what it does. Play around with the values and see what they do!

    out

    ---
    title: "Quarto Dashboard with Radio Buttons"
    format:
      html:
        theme: cosmo
    runtime: shiny
    execute:
      echo: false
    ---
    
    ```{r, echo=FALSE}
    library(shiny)
    
    fluidPage(
      radioButtons(
        inputId = "choice",
        label = "Select an option:",
        choices = list(
          "Option A" = "A",
          "Option B" = "B",
          "Option C" = "C"
        )
      ),
      tags$style(HTML(
        '
        input[type="radio"] {
          appearance: none;        /* your browser determines the button style usually, turn it off here */
          -webkit-appearance: none;
          width: 20px;
          height: 20px;
          border: 1px solid black; /* border around circle */
          border-radius: 50%;      /* radius 50% for circle */
          background-color: gold;  /* color! :) */
          position: relative;
          cursor: pointer;         /* your mouse pointer shape on hover */
          vertical-align: middle;
        }
    
        input[type="radio"]::before {
          content: "";  /* needed for animation */
          display: block;
          position: absolute;
          top: 50%;       /* positioning of inner circle */
          left: 50%;
          width: 6px;     /* inner circle diameter */
          height: 6px;    /* inner circle diameter */
          background-color: white;
          border-radius: 50%;
          transform: translate(-50%, -50%) scale(0);
          transition: transform 150ms ease-in-out; /* animation time */
        }
    
        input[type="radio"]:checked::before {
          transform: translate(-50%, -50%) scale(1);
        }
        '
      ))
    )
    
    
    ```
    

    Further resources:

    Edit 1

    I tried to apply css via yaml-header. But somehow the css loaded via yaml is not applied at all to the quarto-dashboard. I also tried

    format:
      html:
        theme: cosmo
        css: custom.css
    

    but that failed too. I believe it has to do with how shiny works within quarto dashboard. If you still want to refer to an external css you can use includeCSS("custom.css") within the fluidpage and place the "custom.css" within the same folder as your .qmd:

    ---
    title: "Quarto Dashboard with Radio Buttons"
    format:
      html:
        theme: cosmo
    runtime: shiny
    execute:
      echo: false
    ---
    ```{r, echo=FALSE}
    library(shiny)
    fluidPage(
      includeCSS("custom.css"),
      radioButtons(
        inputId = "choice",
        label = "Select an option:",
        choices = list(
          "Option A" = "A",
          "Option B" = "B",
          "Option C" = "C"
        )
      )
    )
    ```
    

    out