web-dev-qa-db-fra.com

Comment éditer une variable CSS avec JS?

J'ai ces variables CSS pour contrôler les couleurs de mon projet afin que je puisse faire des thèmes. 

html {
    --main-background-image: url(../images/starsBackground.jpg);
    --main-text-color: #4CAF50;
    --main-background-color: rgba(0,0,0,.25);
    --beta-background-color: rgba(0,0,0,.85);
}

Cependant, peu importe comment j'essaie de changer l'attribut (les deux lignes commentées sont essayées séparément), le plus proche que je reçois est de ne pas retourner un attribut valide.

function loadTheme() {
    var htmlTag = document.getElementsByTagName("html");
    var yourSelect = document.getElementById( "themeSelect" );
    var selectedTheme = ( yourSelect.options[ yourSelect.selectedIndex ].value );
    // htmlTag[0].setAttribute('--main-text-color', '#FFCF40');
    // $("html").css("--main-text-color","#FFCF40");
}

the error message

24
David Richards

Il est possible de changer les variables CSS en utilisant la propriété el.style.cssText, ou les méthodes el.style.setProperty ou el.setAttribute. Dans vos extraits de code, el.setAttribute est utilisé de manière incorrecte, ce qui est à l'origine de l'erreur que vous avez rencontrée. Voici la bonne façon:

var html = document.getElementsByTagName('html')[0];
html.style.cssText = "--main-background-color: red";

ou

var html = document.getElementsByTagName('html')[0];
html.style.setProperty("--main-background-color", "green");

ou

var html = document.getElementsByTagName('html')[0];
html.setAttribute("style", "--main-background-color: green");

Démo

La démonstration suivante définit une couleur d'arrière-plan à l'aide d'une variable CSS, puis la modifie à l'aide de l'extrait de code JS 2 secondes après son chargement. 

window.onload = function() {
  setTimeout(function() {
    var html = document.getElementsByTagName('html')[0];
    html.style.cssText = "--main-background-color: red";
  }, 2000);
};
html {
    --main-background-image: url(../images/starsBackground.jpg);
    --main-text-color: #4CAF50;
    --main-background-color: rgba(0,0,0,.25);
    --beta-background-color: rgba(0,0,0,.85);
}

body {
  background-color: var(--main-background-color);
}

Cela ne fonctionnera que dans les navigateurs supportant évidemment les variables CSS. 

19
Brett DeWoody

Si vous utilisez :root:

:root {
    --somevar: black;
}

Ce sera documentElement.

document.documentElement.style.setProperty('--somevar', 'green');
14
Blauhirn

La solution native

Les méthodes standard permettant d'obtenir/de définir les variables CSS3 sont .setProperty() et .getPropertyValue().

Si vos variables sont globales (déclarées dans :root), vous pouvez utiliser ce qui suit pour obtenir et définir leurs valeurs.

// setter
document.documentElement.style.setProperty('--myVariable', 'blue');
// getter
document.documentElement.style.getPropertyValue('--myVariable');

Cependant, le getter ne renverra que la valeur d'un var, s'il a été défini, en utilisant .setProperty(). Si a été défini via la déclaration CSS, retournera undefined. Vérifiez-le dans cet exemple:

let c = document.documentElement.style.getPropertyValue('--myVariable');
alert('The value of --myVariable is : ' + (c?c:'undefined'));
:root{ --myVariable : red; }
div{ background-color: var(--myVariable); }
  <div>Red background set by --myVariable</div>

Pour éviter ce comportement inattendu, vous devez utiliser la méthode getComputedStyle() avant d'appeler .getPropertyValue(). Le getter ressemblera alors à ceci:

getComputedStyle(document.documentElement,null).getPropertyValue('--myVariable');

À mon avis, l'accès aux variables CSS devrait être plus simple, rapide, intuitif et naturel ...


Mon approche personnelle

J'ai implémenté CSSGlobalVariablesa un assistant javascript minuscule (<3 Ko) qui détecte et intègre automatiquement dans un objet toutes les variables globales CSS actives d'un document, pour un accès et une manipulation plus faciles.

// set a new value to --myVariable
cssVar.myVariable = 'red';
// get the value of --myVariable
console.log( cssVar.myVariable );

Toute modification appliquée aux propriétés de l'objet est automatiquement traduite en variables CSS. 

Disponible dans: https://github.com/colxi/css-global-variables

7
colxi

Vous pouvez ajouter quelque chose comme ci-dessous (sans utiliser de variables de classe)

function loadTheme() {
  var htmlTag = document.getElementById("myDiv");
  var yourSelect = document.getElementById("themeSelect");
  var selectedTheme = (yourSelect.options[yourSelect.selectedIndex].value);
  console.log("selected theme: " + selectedTheme);

  // reset class names
  htmlTag.className = '';
  // add selected theme
  htmlTag.className = 'theme' + selectedTheme;
}
.theme1 {
  color: blue;
}
.theme2 {
  color: red;
}
<div id="myDiv">
  test
</div>
<select id="themeSelect" onChange="loadTheme()">
  <option value="1">Theme 1</option>
  <option value="2">Theme 2</option>
</select>

1
ochi

Il serait probablement plus facile de définir dans votre CSS des classes contenant les différents styles de thème (.theme1 {...}, .theme2 {...}, etc.), puis de modifier la classe avec JS en fonction de la valeur sélectionnée.

0
johnniebenson