bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

navbar - dark theme

Open pinggi opened this issue 8 months ago • 3 comments

Prerequisites

Describe the issue

I defined colors for navbar...

$navbar-light-color: #000;
$navbar-dark-color: #fff;

...then compiled the bootstrap theme and used it on a page with data-bs-theme="dark" attribute on html element.

<html data-bs-theme="dark">
<body>
<nav class="navbar">...</nav>
</body>
</html>

The dark theme was applied to the page but not to the navbar.

Reduced test cases

I had to add the attribute directly to the navbar to apply the dark theme to it.

<html data-bs-theme="dark">
<body>
<nav class="navbar" data-bs-theme="dark">...</nav>
</body>
</html>

I think it's because _navbar.scss contains this code generating the css variables:

.navbar-dark,
.navbar[data-bs-theme="dark"] {
  // scss-docs-start navbar-dark-css-vars
  --#{$prefix}navbar-color: #{$navbar-dark-color};
  --#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color};
  --#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color};
  --#{$prefix}navbar-active-color: #{$navbar-dark-active-color};
  --#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color};
  --#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color};
  --#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color};
  --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
  // scss-docs-end navbar-dark-css-vars
}

I fixed this in my project by copying the section that generates .navbar css variables to my custom theme:

$prefix: bs-;
:root[data-bs-theme="dark"] { // <--- [data-bs-theme="dark"] moved from .navbar to :root 
  .navbar-dark,
  .navbar {
    --#{$prefix}navbar-color: #{$navbar-dark-color};
    --#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color};
    --#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color};
    --#{$prefix}navbar-active-color: #{$navbar-dark-active-color};
    --#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color};
    --#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color};
    --#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color};
    --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
  }
}

With that change the navbar changes color mode together with other components, so reacts on the changes to data-bs-theme attribute of html element.

The app is a react app where the html element isn't part of the react tree, while the navbar is. So only the attribute of the html element defines the color mode and it's changed by DOM function directly. I don't want to update the react content only because of the navbar.

What operating system(s) are you seeing the problem on?

Windows

What browser(s) are you seeing the problem on?

Firefox

What version of Bootstrap are you using?

5.3.3

pinggi avatar Mar 21 '25 17:03 pinggi

The same goes for dropdown menus. They ignore the dark color mode set by <html data-bs-theme="dark">.

They have the same light and dark variables

dropdown-light-*
dropdown-dark-*

but the dark theme is applied on them only when .dropdown-menu-dark class is added.

pinggi avatar Mar 24 '25 15:03 pinggi

Hi Team,

I don't know the history of navbar but it seems to work differently than say buttons or forms when it comes to themes. Attached is a idea for "to make navbar more like the other components". This should solve the various issues i've seen with navbar et al.

In _navbar.scss

  1. Pull out all color items from the .navbar rule and put them into a new rule :root, [data-bs-theme=light]. This extends what's in _variables.scss.
+:root,
+[data-bs-theme=light] {
+  --#{$prefix}navbar-color: #{$navbar-light-color};
+  --#{$prefix}navbar-hover-color: #{$navbar-light-hover-color};
+  --#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color};
+  --#{$prefix}navbar-active-color: #{$navbar-light-active-color};
+  --#{$prefix}navbar-brand-color: #{$navbar-light-brand-color};
+  --#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color};
+  --#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color};
+}
 
 .navbar {
   // scss-docs-start navbar-css-vars
   --#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)};
   --#{$prefix}navbar-padding-y: #{$navbar-padding-y};
-  --#{$prefix}navbar-color: #{$navbar-light-color};
-  --#{$prefix}navbar-hover-color: #{$navbar-light-hover-color};
-  --#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color};
-  --#{$prefix}navbar-active-color: #{$navbar-light-active-color};
   --#{$prefix}navbar-brand-padding-y: #{$navbar-brand-padding-y};
   --#{$prefix}navbar-brand-margin-end: #{$navbar-brand-margin-end};
   --#{$prefix}navbar-brand-font-size: #{$navbar-brand-font-size};
-  --#{$prefix}navbar-brand-color: #{$navbar-light-brand-color};
-  --#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color};
   --#{$prefix}navbar-nav-link-padding-x: #{$navbar-nav-link-padding-x};
   --#{$prefix}navbar-toggler-padding-y: #{$navbar-toggler-padding-y};
   --#{$prefix}navbar-toggler-padding-x: #{$navbar-toggler-padding-x};
   --#{$prefix}navbar-toggler-font-size: #{$navbar-toggler-font-size};
   --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)};
-  --#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color};
   --#{$prefix}navbar-toggler-border-radius: #{$navbar-toggler-border-radius};
   --#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width};
   --#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition};
@@ -266,8 +269,7 @@
   @include deprecate("`.navbar-light`", "v5.2.0", "v6.0.0", true);
 }
  1. Simplify the rule for navrbar dark theme. Currently it scopes to a class AND theme .navbar[data-bs-theme="dark"]. This seems overly specific and other components don't do this. They just live in the global [data-bs-theme="dark"] rule. So let's do that here: (NOTE: unclear what to do with .navbar-dark )
-.navbar-dark,
-.navbar[data-bs-theme="dark"] {
+[data-bs-theme="dark"] {
   // scss-docs-start navbar-dark-css-vars
   --#{$prefix}navbar-color: #{$navbar-dark-color};
   --#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color};

That's it!

One can make changes to the navbar outside of SCSS by making a new style or sep file with

[data-bs-theme="dark"] {
--bs-navbar-color: #ff0000;
}

and boom, red navbar text. Previously this did not work (it worked for other dark variables but not navbar).

  • There are a few other components with this problem.
  • It's simple. No global changes or changes to _variables.css. Each change is only in the component's file.
  • Low probability of breaking anything
  • It seems like a good interim solution for the v5.X line while v6 is being worked out.
  • I'm happy to make a PR if you think this is a good direction.

regards,

N

p.s. I deleted this comment previously by mistake

client9 avatar Mar 31 '25 23:03 client9

.navbar[data-bs-theme="dark"] { // scss-docs-start navbar-dark-css-vars --#{$prefix}navbar-color: #{$navbar-dark-color}; --#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color}; --#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color}; --#{$prefix}navbar-active-color: #{$navbar-dark-active-color}; --#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color}; --#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color}; --#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color}; --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)}; // scss-docs-end navbar-dark-css-vars }

prakurwankhade avatar May 20 '25 06:05 prakurwankhade