web-dev-qa-db-fra.com

Combinez calc () avec attr () en CSS

Je me demandais si je pouvais combiner la fonction calc () avec la fonction attr () pour réaliser quelque chose comme ceci:

<div class="content" data-x="1">
    This box should have a width of 100px
</div>

<div class="content" data-x="2">
    This box should have a width of 200px
</div>

<div class="content" data-x="3">
    This box should have a width of 300px
</div>

[~ # ~] css [~ # ~]

.content{
    //Fallback. If no calc is supported, just leave it at 100px
    width: 100px;
}


.content[data-x]{
    // Multiply the width of the element by the factor of data-x
    width: calc(100px * attr(data-x));
}

Le draft indique que cela devrait fonctionner, mais dans mon cas (Chrome 31.0.1650.63 m et Firefox 25.0.1), cela ne fonctionne pas. Il y a alors deux cas:

  1. Je l'ai mal fait
  2. Il n'est pas encore pris en charge

Quel est le problème?

Exemple de violon

31
Loupax

À l'heure actuelle, attr () n'est pas pris en charge par défaut dans les principaux navigateurs pour les attributs autres que "contenu". En savoir plus à ce sujet ici: https://developer.mozilla.org/en-US/docs/Web/CSS/attr

23
jede

Il semble y avoir un moyen de contourner cela en utilisant vars

.content{
    --x: 1;
    width: calc(100px * var(--x));
    background: #f00;
}

[data-x="1"] { --x: 1; }
[data-x="2"] { --x: 2; }
[data-x="3"] { --x: 3; }

/*doesn't look like this works unfortunately
[data-x] { --x: attr(data-x); }
seems to set all the widths to some really large number*/

La section commentée aurait été parfaite, et cela peut être la même raison pour laquelle votre idée n'a pas fonctionné, mais il semble que css n'effectue pas le casting automatique de Nice auquel vous pourriez être habitué en javascript ('2' * 3 //=6).
attr() renvoie une chaîne, pas un nombre, et cela peut être vu en ajoutant .content:after { content:var(--x) }; rien n'est imprimé, --x est un nombre, content accepte les chaînes.

S'il y a une fonction CSS à lancer, je pense que ce serait la clé de ce problème.


On dirait du casting (enfin, interprétation) sera une chose dans CSS4 , et ce sera aussi simple que

.content{
    width: calc(100px * attr(data-x number, 1));
    background: #f00;
}

À ce jour, aucun navigateur ne prend en charge même cette spécification expérimentale, mais je mettrai à jour quand il le fera.

18
Hashbrown

Pour le moment, la fonction attr () ne fonctionne pas dans Chrome.

Une solution presque aussi agréable consiste à utiliser des variables CSS:

<!DOCTYPE html>
<html>
  <head>
    <style>
      :root {
         --module-size: 100px;
         --data-x:1; /* Default value */
       }

      .content{
          width: calc(var(--module-size) * var(--data-x));
          border: 1px solid;
      }
    </style>
  </head>
  <body>
    <div class="content" style="--data-x:1">
        This box should have a width of 100px
    </div>

    <div class="content" style="--data-x:2">
        This box should have a width of 200px
    </div>

    <div class="content"  style="--data-x:3">
        This box should have a width of 300px
    </div>
  </body>
</html>
6
Simon Rigét