Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Improve navbar compatiblity for Bootstrap 5 and light/dark modes #1145

Open
wants to merge 16 commits into
base: feat/navbar-options-bs5
Choose a base branch
from

Conversation

gadenbuie
Copy link
Member

@gadenbuie gadenbuie commented Dec 3, 2024

This PR is a second third take at #1135, and now the second part of a two-part PR. #1146 covers the markup and this PR covers the Sass changes.

There are a few things happening in the two PRs. The primary goal is to bring bslib in line with Bootstrap 5's expectations around how the navbar background color is controlled, while adding appropriate controls for the following scenarios:

  1. By default a navbar that follows the current light/dark color mode.
  2. Globally set the navbar backround for both light/dark mode with $navbar-bg.
  3. Individually set light and dark navbar backgrounds with $navbar-light-bg and $navbar-dark-bg.
  4. Individually set the background color of a navbar with navbar_options(bg = "...").
  5. Individually set the background of a navbar with BS 5 markup, e.g. navbar_options(class = "bg-primary", type = "dark").

In general, for most BS 5+ users, I'd recommend using the last two options.

1. Navbar background follows light/dark color mode

library(shiny)
pkgload::load_all()
shiny::devmode(TRUE)

VERSION <- 5

ui <- page_navbar(
  title = "My Simple App",
  theme = bs_theme(
    preset = "shiny",
    version = VERSION,
  ),
  nav_panel(
    "Home",
    h2("Welcome to the Home Page"),
    if (VERSION >= 5) {
      bslib::input_dark_mode()
    }
  ),
  nav_panel(
    "About",
    h2("About navbars")
  )
)

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

}

shinyApp(ui, server)

2. Globally fix navbar colors, regardless of color mode

library(shiny)
pkgload::load_all()
shiny::devmode(TRUE)

VERSION <- 5

ui <- page_navbar(
  title = "My Simple App",
  theme = bs_theme(
    preset = "shiny",
    version = VERSION,
    navbar_bg = "#732400",
  ),
  nav_panel(
    "Home",
    h2("Welcome to the Home Page"),
    if (VERSION >= 5) {
      bslib::input_dark_mode()
    }
  ),
  nav_panel(
    "About",
    h2("About navbars")
  )
)

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

}

shinyApp(ui, server)

3. Individually choose navbar colors in light/dark mode

library(shiny)
pkgload::load_all()
shiny::devmode(TRUE)

VERSION <- 5

ui <- page_navbar(
  title = "My Simple App",
  theme = bs_theme(
    preset = "shiny",
    version = VERSION,
    navbar_light_bg = "#b2d8ff",
    navbar_dark_bg = "#00165d",
  ),
  nav_panel(
    "Home",
    h2("Welcome to the Home Page"),
    if (VERSION >= 5) {
      bslib::input_dark_mode()
    }
  ),
  nav_panel(
    "About",
    h2("About navbars")
  )
)

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

}

shinyApp(ui, server)

4. Locally set navbar colors using navbar_options(bg=)

library(shiny)
pkgload::load_all()
shiny::devmode(TRUE)

VERSION <- 5

ui <- page_navbar(
  title = "My Simple App",
  theme = bs_theme(
    preset = "shiny",
    version = VERSION,
  ),
  navbar_options = navbar_options(bg = "#732400"),
  nav_panel(
    "Home",
    h2("Welcome to the Home Page"),
    if (VERSION >= 5) {
      bslib::input_dark_mode()
    }
  ),
  nav_panel(
    "About",
    h2("About navbars")
  )
)

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

}

shinyApp(ui, server)

5. Locally set navbar colors using BS 5's recommended approach

library(shiny)
pkgload::load_all()
shiny::devmode(TRUE)

VERSION <- 5

ui <- page_navbar(
  title = "My Simple App",
  theme = bs_theme(
    preset = "shiny",
    version = VERSION,
  ),
  navbar_options = navbar_options(
    class = "bg-primary",
    type = "dark"
  ),
  nav_panel(
    "Home",
    h2("Welcome to the Home Page"),
    if (VERSION >= 5) {
      bslib::input_dark_mode()
    }
  ),
  nav_panel(
    "About",
    h2("About navbars")
  )
)

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

}

shinyApp(ui, server)

Notes

Following bs-theme color mode by default

Bootstrap 5 primarily wants to have stable navbar colors, but we both -- bslib and pkgdown -- independently developed an approach where the navbar changes colors in light and dark mode. I've patched the BS 5 navbars Sass files to accommodate this.

The biggest source of added complexity in this change is that both [data-bs-theme="dark"] .navbar and [data-bs-theme="light"] .navbar[data-bs-theme="dark"] should result in a dark navbar style, but [data-bs-theme="light"] .navbar.bg-primary[data-bs-theme="dark"] should be a dark navbar (i.e. light text) with a primary-colored background.

These three scenarios required careful construction of selectors, rule ordering, and selector specificity management. In other words, it's why we use :where() and separately define [data-bs-theme="light"] .navbar and .navbar[data-bs-theme="light"].

Localized >>> global changes

Setting $navbar-bg globally changes both light and dark themes, and for all navbars. It's convenient but introduces a downside that the data-bs-theme attribute on the .navbar loses meaning.

For the same reason, users will want to use light colors (that result in black contrast text) for $navbar-light-bg and dark colors (that result in white contrast text) for $navbar-dark-bg.

New CSS variables, old classes

The old .navbar-default and .navbar-inverse classe are maintained for BS 4 compatibility with BS 3 styles. They are now empty classes for BS 5, but still included in the markup in case there are users who rely on them. (They should probably transition away from that, though.)

We also still use --bslib-navbar-default-bg and --bslib-navbar-inverse-bg CSS variables, but I've added --bslib-navbar-light-bg and --bslib-navbar-dark-bg in front of both variables so that they can be set client-side without Sass.

This rule only changes the background color of the navbar,
which is not enough to fully restyle the navbar in dark mode.
It might work in the default cases, but it certainly does not
work if users have set $navbar-dark-bg or $navbar-light-bg
to appropriate values. Note that Bootstrap expects the navbar
colors to be static (i.e. the same in light and dark mode), so if
we want to support different navbar colors we'll need to
implement something better.
Bootstrap has the navbar toggler icon follow the global color mode, which makes the icon invisible when placed on a light background in dark mode. Outside of this rule, Bootstrap expects the navbar color to be consistent in light and dark mode.
…ty possible

Otherwise they get in the way of local classes, e.g. `bg-blue` or `bg-primary`,
which are the primary mechanism for setting navbar color in BS5

https://getbootstrap.com/docs/5.3/components/navbar/#color-schemes
@gadenbuie gadenbuie force-pushed the feat/bs5-navbar-bg-dark-light branch from ed14acf to fd2e808 Compare December 4, 2024 15:42
@gadenbuie gadenbuie changed the base branch from main to feat/navbar-options-bs5 December 4, 2024 15:42
@cpsievert
Copy link
Collaborator

Before I dive into this, I just did a quick run of these examples with main, and it seems 1-3 currently work the way we want them to? I can see though that, for 4, the navbar color doesn't change depending on the color mode.

@gadenbuie
Copy link
Member Author

Before I dive into this, I just did a quick run of these examples with main, and it seems 1-3 currently work the way we want them to?

The first option only works in the Shiny preset and it works in a way that it breaks the second option. #1135 shows the problematic behavior.

@gadenbuie gadenbuie force-pushed the feat/bs5-navbar-bg-dark-light branch from c1e2ec7 to 533fa64 Compare December 4, 2024 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants