Answer to the three core questions
1. What happens when a custom property and its corresponding Sass variable are both defined?
When Bootstrap’s compiled CSS uses var(--bs‑primary) (which is the case for most tokens in 5.3+), the runtime value of the custom property overrides the static value that was baked in by Sass. The cascade resolves var() at the time the rule is applied, so the custom property wins if it is defined on a selector that is at least as specific as the rule that uses it.
In contrast, if the CSS rule contains a hard‑coded value (e.g., #0d6efd instead of var(--bs‑primary)), the Sass‑derived value remains authoritative and cannot be overridden by setting the custom property.
2. How can developers guarantee consistent runtime theme overrides across all Bootstrap components without recompiling the source?
1. Identify the token you want to override (commonly --bs‑primary, --bs‑secondary, etc.).
2. After Bootstrap’s JavaScript has initialized, set the property on :root via CSS or JavaScript:
document.documentElement.style.setProperty('--bs-primary', '#ff5722');
3. Verify that the component’s CSS uses var(--bs‑primary) by inspecting the computed style. If the rule is hard‑coded, you must write a supplemental rule that targets the component and sets the property with higher specificity or !important.
4. Repeat for any other tokens you wish to change.
3. Is there a documented approach to force Bootstrap to rely exclusively on CSS custom properties for theme values?
Bootstrap does not provide a switch to replace all hard‑coded values with var(). The framework’s Sass layer is still required for build‑time logic (e.g., generating utilities, responsive breakpoints). However, you can achieve a near‑exclusive runtime approach by:
- Using the latest Bootstrap 5.3+ build, which exposes the majority of theme tokens as CSS custom properties.
- Adding a global
:root stylesheet that sets every exposed token to the desired value.
- Overriding any remaining hard‑coded values with targeted CSS rules.
In short, you can rely on CSS custom properties for most runtime theming, but you cannot eliminate the Sass layer entirely without rebuilding Bootstrap.
Explanation of the precedence relationship
Bootstrap’s Sass variables (e.g., $primary) are compiled into static CSS values. When the compiled stylesheet contains var(--bs‑primary), the custom property value is resolved at runtime. If the custom property is defined after the stylesheet loads, its value overrides the static value for all rules that reference it. If a rule contains a hard‑coded value, the static value is final and cannot be overridden by the custom property.
Because the cascade applies the most specific rule that matches, setting the custom property on :root is usually sufficient. If you encounter components that still use the old color, check whether their CSS has a more specific selector or a hard‑coded value.
Diagnostic question
Do you know whether your project uses Bootstrap 5.3 or newer? Earlier releases expose fewer tokens as custom properties, which may require additional manual overrides.