javascript - Définir plusieurs valeurs pour un attribut CSS


Est-il possible de définir deux valeurs pour un seul attribut sur un ID CSS, par exemple

hauteur : 12em ; hauteur : 12rem ;

pour un identifiant unique ? Je sais qu'il est possible de le faire avec CSS, mais je veux changer la hauteur via javascript, et avoir les deux valeurs sur un seul attribut, afin que 'em' fonctionne comme une solution de repli pour les navigateurs ne supportant pas 'rem'.

Exemple :

function updateHeight() {
  var testElem = document.getElementById("testId");
  testElem.style.height = "12em";
  testElem.style.height = "12rem";
  //testElem.style.height = "12em; 12rem;"; doesn't work, applies "12em"
}
#testId {
  height: 8em;
  height: 8rem;
  background-color: black;
  color: white;
}
<!DOCTYPE html>
<html>

<head>
  <title>Test</title>
  <meta charset="utf-8" />
</head>

<body>
  <div id="testId">
    BlaBla
  </div>
  <button onclick="updateHeight()">Bla</button>
</body>

</html>

Réponse #1

Vous pouvez utiliser une classe à la place

function updateHeight() {
  var testElem = document.getElementById("testId");
  testElem.classList.add('high');
}
#testId {
  height: 8em;
  height: 8rem;
  background-color: black;
  color: white;
}

#testId.high { /* remember that ID is more specific than class */
  height: 12em;
  height: 12rem;
}
<!DOCTYPE html>
<html>

<head>
  <title>Test</title>
  <meta charset="utf-8" />
</head>

<body>
  <div id="testId">
    BlaBla
  </div>
  <button onclick="updateHeight()">Bla</button>
</body>

</html>

Ou si la valeur est dynamique, vous devrez probablement insérer une balise de style pour pouvoir prendre en charge la cascade CSS

function updateHeight() {

  var value    = 12; // or something dynamic
  var styles   = '#testId {height: '+value+'em; height: '+value+'rem;}';
  var tag      = document.createElement('style');

  tag.innerHTML = styles;

  document.querySelector('head').appendChild(tag);

}
#testId {
  height: 8em;
  height: 8rem;
  background-color: black;
  color: white;
}
<!DOCTYPE html>
<html>

<head>
  <title>Test</title>
  <meta charset="utf-8" />
</head>

<body>
  <div id="testId">
    BlaBla
  </div>
  <button onclick="updateHeight()">Bla</button>
</body>

</html>

Réponse #2

Oui, vous le pouvez. Cela est défini par la cascade CSS :

Chaque déclaration de propriété appliquée à un élément contribue à une valeur déclarée pour cette propriété associée à l’élément.

Ces valeurs sont ensuite traitées par la cascade pour choisir une seule « valeur gagnante ».

La valeur en cascade représente le résultat de la cascade : c'est la valeur déclarée qui l'emporte dans la cascade (elle est triée en premier dans le résultat de la cascade).

Alors, si vous utilisez

height: 8em;
height: 8rem;

Il y aura 2 valeurs déclarées pour la propriété height : 8em et 8rem. Cette dernière prévaudra dans la cascade, devenant la valeur en cascade.

Si un navigateur ne supporte pas l’un d’eux, l’autre sera la seule valeur déclarée, donc elle l’emportera dans la cascade.

Si un navigateur ne prend en charge aucun d'entre eux, le résultat de la cascade sera la liste vide, et il n'y aura pas de valeur en cascade. La valeur spécifiée sera le résultat des processus de valeur par défaut (la valeur initiale dans ce cas, car height n'est pas une propriété héritée).

Cependant, avec JavaScript, il y a un problème. setProperty, utilisé en arrière-plan par les propriétés IDL en camel case dans .style, utilise l'algorithme de définition d'une déclaration CSS, ce qui écrase les déclarations existantes :

  1. Si property correspond exactement (respectant la casse) au nom d’une propriété dans une déclaration CSS de declarations, laissez declaration être cette déclaration CSS.

  2. Sinon, ajoutez une nouvelle déclaration CSS avec le nom de propriété property à declarations et laissez declaration être cette déclaration CSS.

Il existe quelques solutions de contournement :

  • Utilisez cssText au lieu des attributs IDL en camel case :

    testElem.style.cssText += "; height: 12em; height: 12rem; ";
    
  • Vérifiez le style après l'avoir défini. Si vous obtenez la chaîne vide, cela signifie qu'il n'a pas été reconnu.

    testElem.style.height = "12rem";
    if(!testElem.style.height) testElem.style.height = "12em";
    
  • Ne définissez pas les styles dans la déclaration de style en ligne. Créez plutôt une nouvelle feuille de style, ou ajoutez une classe à l’élément pour déclencher du CSS à partir d’une feuille de style existante.