cssrshinyquartobslib

How to horizontally align values across bslib::value_box() elements?


I'm building a Quarto dashboard with Shiny, using the bslib::value_box() component to display five value boxes in a single row. Each box has a title and a value, which is dynamically rendered using Shiny.

Everything works fine functionally — the values and titles render correctly — but I'm having trouble with visual alignment. I want the values in each box to appear on the same horizontal line across all boxes, regardless of the text length or digits. Right now, some values sit higher or lower than others.

I’ve tried customizing the layout using SCSS, but nothing has successfully aligned the values.

Below is a simplified example that demonstrates the issue. My actual project follows the same setup.

---
title: "Value Box Alignment Example"
format:
  dashboard:
    expandable: false
server: shiny
---

```{r}
#| label: load-packages
#| context: setup
#| message: false

library(shiny)
library(bslib)
```

## Sidebar {.sidebar}

## Main body

### Value boxes {height="20%"}

```{r}
value_box(
title = "Cases",
value = textOutput("cases_val"),
theme = "teal"
)
```

```{r}
value_box(
title = "Some very long text dajsndasndonasddsadasd",
value = textOutput("deaths_val"),
theme = "teal"
)
```

```{r}
value_box(
title = "Recovered",
value = textOutput("recovered_val"),
theme = "teal"
)
```

```{r}
value_box(
title = "Vaccinated",
value = textOutput("vax_val"),
theme = "teal"
)
```

```{r}
value_box(
title = "Tests",
value = textOutput("tests_val"),
theme = "teal"
)
```

### Row {height="80%"}

```{r}
#| context: server

output$cases_val <- renderText({ "123" })
output$deaths_val <- renderText({ "4" })
output$recovered_val <- renderText({ "12,345" })
output$vax_val <- renderText({ "85%" })
output$tests_val <- renderText({ "999,999" })

```

Solution

  • Loop via JS trough all value box titles, collect their heights, and apply the maximum of the heights to all value box titles:

    enter image description here

    ---
    title: "Value Box Alignment Example"
    format:
      dashboard:
        expandable: false
    server: shiny
    include-before-body:
      text: |
        <script>
          $(document).ready(function() {
            var heights= $('.value-box-title').map(function() {
              return $(this).height();
            }).get();
            $('.value-box-title').css('height', Math.max(...heights));
          })
        </script>
    ---
    
    ```{r}
    #| label: load-packages
    #| context: setup
    #| message: false
    
    library(shiny)
    library(bslib)
    ```
    
    ## Sidebar {.sidebar}
    
    ## Main body
    
    ### Value boxes {height="20%"}
    
    ```{r}
    value_box(
      title = "Cases",
      value = textOutput("cases_val"),
      theme = "teal"
    )
    ```
    
    ```{r}
    value_box(
      title = "Some very very long text dajsndasndonasddsadasd",
      value = textOutput("deaths_val"),
      theme = "teal"
    )
    ```
    
    ```{r}
    value_box(
      title = "Recovered",
      value = textOutput("recovered_val"),
      theme = "teal"
    )
    ```
    
    ```{r}
    value_box(
      title = "Vaccinated",
      value = textOutput("vax_val"),
      theme = "teal"
    )
    ```
    
    ```{r}
    value_box(
      title = "Tests",
      value = textOutput("tests_val"),
      theme = "teal"
    )
    ```
    
    ### Row {height="80%"}
    
    ```{r}
    #| context: server
    
    output$cases_val <- renderText({ "123" })
    output$deaths_val <- renderText({ "4" })
    output$recovered_val <- renderText({ "12,345" })
    output$vax_val <- renderText({ "85%" })
    output$tests_val <- renderText({ "999,999" })
    ```