The primary color of my Single Page Application is programmatically client-side defined. The problem is that is it used in many places in my code.
Eg. on load, I have (in SCSS):
body {
background-color: #XXXXXX;
}
.btn-primary {
background-color: #XXXXXX;
}
.content ul li a {
color: #XXXXXX;
border: thin solid #XXXXXX;
&:hover {
background-color: #XXXXX;
color: white;
}
}
And I need to replace#XXXXXX
to #YYYYYY
everywhere, on the client side.
The different options I see are:
Something like:
body {
background-color: #XXXXXX;
.btn-primary {
background-color: #XXXXXX;
}
.content ul li a {
color: #XXXXXX;
border-color: #XXXXXX;
&:hover {
background-color: #XXXXX;
}
}
&.other-color {
background-color: #YYYYYY;
.btn-primary {
background-color: #YYYYYY;
}
.content ul li a {
color: #YYYYYY;
border-color: #YYYYYY;
&:hover {
background-color: #YYYYYY;
}
}
}
}
+ Pro It will eventually work
- Con Not DRY at all!
#XXXXXX
and replace with #YYYYYY
in the DOM.+ Pro Seems clean to me
- Con Not sure it is doable
#XXXXXX
and replace with #YYYYYY
in the CSS file.+ Pro Should do the job
- Con Not sure it is doable. And it doesn't feel like the right way to do it.
application.css
to application-other-color.css
and use it accordingly.+ Pro Pretty easy to implement (compared to the other solutions)
- Con The user needs to load different assets, which is not optimum for a SPA
Has anyone faced this issue before? Is there any better solution than those two? If not, which one would you suggest? Did I miss some pros/cons?
Basically, #1, but I would structure it differently. It's best to separate these if they are indeed different states/classes, and name them semantically.
That way, if you decide, for example, that .body-content--error
also needs to have green text, or whatever, you can easily edit it in. Now you just need to set the javascript to switch classes, which is simple.
This is actually very DRY code, in that .body-content
and .body-content--error
are different states of the same element. In fact, with the code below, you can set the class of body
to class="body-content body-content--error"
and inherit all of the .body-content
CSS, and just change the background-color
with .body-content--error
.
$primary-color: #XXXXXX;
$error-color: #YYYYYY;
// Body content
.body-content {
background-color: $primary-color;
margin: 10px;
padding: 10px;
}
.body-content--error {
background-color: $error-color;
}
//Button (primary)
.btn-primary {
background-color: $primary-color;
}
.btn-primary--error {
background-color: $error-color;
}
// Links in the .content list
.content-list-link {
color: $primary-color;
border-color: $primary-color;
&:hover {
background-color: $primary-color;
}
}
.content-list-link--error {
color: $error-color;
border-color: $error-color;
&:hover {
background-color: $error-color;
}
}
CSS variables seem the perfect solution:
body {
--my-color: red; /* Set some value */
background-color: var(--my-color); /* Use the value in the variable */
}
.btn-primary {
background-color: var(--my-color); /* Use the inherited value */
}
Then, changing the colors is simple:
document.body.style.setProperty('--my-color', newColor);
document.querySelector('button').onclick = function() {
var rndcolor = '#' + ('00000' + Math.floor(Math.random() * 256 * 256 * 256).toString(16)).slice(-6);
document.body.style.setProperty('--my-color', rndcolor);
};
body {
--my-color: red;
background-color: var(--my-color);
}
.content {
background-color: #fff;
padding: 20px;
}
.btn-primary {
background-color: var(--my-color);
}
.content a {
color: var(--mycolor);
border: thin solid var(--my-color);
}
.content a:hover {
background-color: var(--my-color);
color: white;
}
<div class="content">
<button class="btn-primary">Click me to change color</button>
<a>I have a border</a>
</div>
The problem is that CSS variables are not widely supported yet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With