[dark mode] Several themes hardcode direct CSS properties that bypass Bootstrap 5.3's dark mode variable remapping
Bootstrap 5.3 implements dark mode by remapping CSS variables (e.g. --bs-body-color, --bs-alert-bg, --bs-btn-color) when [data-bs-theme="dark"] is set on a parent element. This only works if the rendered value flows through a variable — a direct hardcoded CSS property like color: #212529 is invisible to the variable system and stays unchanged regardless of the active theme.
Several Bootswatch themes add custom CSS rules in their overrides block that write hardcoded hex values directly onto Bootstrap component selectors without providing a [data-bs-theme="dark"] counterpart. When dark mode is enabled, these values produce invisible or unreadable text.
Version: 5.3.8 Bootstrap version: 5.3.x Affects dark mode: Yes — light → dark switch only
Affected themes and specific rules
Zephyr
/* Custom block — no [data-bs-theme="dark"] counterpart */
.btn-secondary,
.btn-light,
.btn-outline-secondary,
.btn-outline-light {
color: #212529; /* near-black; invisible on dark backgrounds */
}Also: .badge.bg-secondary, .badge.bg-light { color: #212529 }
Brite
/* All .btn-outline-* variants */
.btn-outline-primary { color: #000; }
.btn-outline-secondary { color: #000; }
.btn-outline-success { color: #000; }
.btn-outline-info { color: #000; }
.btn-outline-warning { color: #000; }
.btn-outline-danger { color: #000; }
.btn-outline-light { color: #000; }
.btn-outline-dark { color: #000; }
/* Also: .btn-link { color: #000 } */Pulse
.btn-secondary { color: #17141f; background-color: #fff; } /* near-black on white; both wrong in dark mode */
.btn-secondary:hover { color: #23202a; background-color: #ededed; }Also: .badge.bg-light { color: #17141f }
Minty
.btn-light, .btn-light:hover { color: #5a5a5a; }
.btn-outline-primary { color: #78c2ad; }
.btn-outline-secondary { color: #888; }
/* ... all .btn-outline-* variants have hardcoded palette colors */Simplex
.btn-outline-secondary { color: #bbb; border-color: #bbb; }
.text-secondary { color: #777 !important; }Flatly, Litera, Lumen, Materia, Minty, Sandstone — all override .alert-* with direct background-color values:
/* Example from Flatly */
.alert-primary { background-color: #2c3e50; }
.alert-secondary { background-color: #95a5a6; }
.alert-success { background-color: #18bc9c; }
/* ... all variants */Bootstrap's .alert component renders background-color: var(--bs-alert-bg), which correctly remaps in dark mode. The direct override wins over the variable reference, breaking dark mode alerts across these themes.
Lux, Lumen, Materia, Yeti — .text-secondary with !important:
/* Lux */ .text-secondary { color: #55595c !important; }
/* Lumen */ .text-secondary { color: #555 !important; }
/* Materia */.text-secondary { color: #bbb !important; } /* actually fine in dark mode but fights --bs-secondary-color */
/* Yeti */ .text-secondary { color: #888; }Lux
.table-light { color: #55595c; } /* dark text on dark background when Bootstrap flips table-light in dark mode */12+ themes — .badge.bg-light / .badge.bg-secondary with hardcoded dark text values (#212529, #343a40, #333, etc.)
Expected behavior
In dark mode, all text should be readable against dark backgrounds. The fix for each case is either:
- Remove the direct property override and rely on Bootstrap's CSS variable (preferred), or
- Add a
[data-bs-theme="dark"]counterpart that remaps to an appropriate light value, e.g.:[data-bs-theme="dark"] .btn-outline-secondary { color: var(--bs-secondary-text-emphasis); }
Actual behavior
Button labels, alert text, and badge text are invisible or have very low contrast when dark mode is active.
To reproduce
- Load any Bootswatch 5.3.8 theme listed above via the npm package
- Set
[data-bs-theme="dark"]on<html> - Render a
btn btn-outline-secondary, an.alert-danger, or a.badge.bg-light - Observe invisible or near-invisible text
Additional context
A workaround is to override the affected selectors in application CSS:
[data-bs-theme="dark"] .btn-secondary,
[data-bs-theme="dark"] .btn-light { color: var(--bs-body-color) !important; }
[data-bs-theme="dark"] .alert-primary,
[data-bs-theme="dark"] .alert-danger /* etc. */ {
background-color: var(--bs-alert-bg) !important;
color: var(--bs-alert-color) !important;
}This confirms the root cause: redirecting back to Bootstrap's variable system immediately fixes the issue.
Source: thomaspark/bootswatch