Reputation: 727
I am working on an Angular application that uses Bootstrap for styling. I want to allow users to select a theme color, and dynamically update the Bootstrap primary color (--bs-primary) at runtime without reloading the page.
Currently, Bootstrap’s primary color is defined in SCSS like this:
$primary: #0d6efd;
@import "bootstrap/scss/bootstrap";
However, this approach requires recompilation, and I need a way to change the primary color dynamically via JavaScript or TypeScript.
What I Have Tried CSS Variables I attempted to override the Bootstrap primary color using CSS variables:
:root {
--bs-primary: #{$primary};
}
But this does not seem to work for all Bootstrap components like buttons and alerts.
Using JavaScript to Update Variables I also tried updating CSS variables dynamically in TypeScript:
changeThemeColor(color: string): void {
document.documentElement.style.setProperty('--bs-primary', color);
const primaryRgb = this.hexToRgb(color);
if (primaryRgb) {
document.documentElement.style.setProperty('--bs-primary-rgb', `${primaryRgb.r}, ${primaryRgb.g}, ${primaryRgb.b}`);
}
}
However, this change above its only the span with text-primary
that gets to reflect the changes of the new color and the button does not
<span class="text-primary">Primary Text</span>
<button class="btn btn-primary">Primary Button</button>
Upvotes: 1
Views: 59
Reputation: 57986
These are the styles of the btn-primary
, As you can see they are not derived from variables but defined directly.
.btn-primary {
--bs-btn-color: #fff;
--bs-btn-bg: #0d6efd;
--bs-btn-border-color: #0d6efd;
--bs-btn-hover-color: #fff;
--bs-btn-hover-bg: rgb(11.05, 93.5, 215.05);
--bs-btn-hover-border-color: rgb(10.4, 88, 202.4);
--bs-btn-focus-shadow-rgb: 49, 132, 253;
--bs-btn-active-color: #fff;
--bs-btn-active-bg: rgb(10.4, 88, 202.4);
--bs-btn-active-border-color: rgb(9.75, 82.5, 189.75);
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
--bs-btn-disabled-color: #fff;
--bs-btn-disabled-bg: #0d6efd;
--bs-btn-disabled-border-color: #0d6efd;
}
You can still override them with the below method. The font color of the first button is derived from '--bs-primary-rgb'
so you can override this using your method.
The code will look something like below:
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
imports: [CommonModule],
template: `
<span class="text-primary">Primary Text</span>
<button class="btn btn-primary" [ngStyle]="color ? {
'--bs-primary-rgb': color,
'--bs-btn-bg': color,
'--bs-btn-border-color': color,
} : {}">Primary Button</button>
<button (click)="changeThemeColor('#DFDFDF')"> change color</button>
`,
})
export class App {
color: string | undefined;
changeThemeColor(color: string): void {
this.color = color;
['--bs-primary-rgb'].forEach((item: string) => {
document.documentElement.style.setProperty(item, color);
});
}
}
bootstrapApplication(App);
Upvotes: 1