javascript - Ändra programmatiskt huvudsaklig färg som används på flera ställen i CSS
Huvudfärgen för min Single Page Application är programmässigt definierad på klientsidan. Problemet är att den används på många ställen i min kod.
Eg. vid laddning, jag har (i 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;
}
}
Och jag behöver ersätta#XXXXXX med #YYYYYY överallt, på klientsidan.
De olika alternativ jag ser är:
1. isolera den färgrelaterade CSS:en och omge den med en klass
Något som:
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 Det kommer så småningom att fungera
- Nackdel Inte DRY alls!
2. Använder en smutsig JS som skulle undersöka varje förekomst av #XXXXXX och ersätta med #YYYYYY i DOM:en.
+ Pro Verkar rent för mig
- Nackdel Osäker på om det går att göra
3. Använda en smutsig JS som skulle inspektera varje förekomst av #XXXXXX och ersätta med #YYYYYY i CSS-filen.
+ Pro Bör göra jobbet
- Nackdel Inte säker på att det går att göra. Och det känns inte som rätt sätt att göra det på.
4. Kompilera flera gånger application.css till application-other-color.css och använd den därefter.
+ Fördel Ganska enkelt att implementera (jämfört med de andra lösningarna)
- Nackdel Användaren behöver ladda olika resurser, vilket inte är optimalt för en SPA
Har någon stött på det här problemet tidigare? Finns det någon bättre lösning än de två? Om inte, vilken skulle du föreslå? Missade jag några fördelar/nackdelar?
Svar #1
CSS-variabler verkar vara den perfekta lösningen:
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 */
}
Då är det enkelt att ändra färgerna:
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>Problemet är att CSS-variabler ännu inte har bred stöd.
Svar #2
I princip #1, men jag skulle strukturera det annorlunda. Det är bäst att separera dessa om de faktiskt är olika tillstånd/klasser, och ge dem semantiska namn.
På det sättet, om du till exempel bestämmer dig för att .body-content--error också behöver ha grön text, eller vad som helst, kan du enkelt redigera det. Nu behöver du bara ställa in javascriptet för att byta klasser, vilket är enkelt.
Detta är faktiskt väldigt DRY-kod, eftersom .body-content och .body-content--error är olika tillstånd av samma element. Faktum är att med koden nedan kan du sätta klassen på body till class="body-content body-content--error" och ärva all CSS från .body-content, och bara ändra background-color med .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;
}
}
