Ajouter un type d’unité au résultat d’un calcul

J’ai refactoring mon CSS vers une feuille de style SASS récemment. J’utilise l’ extension Mindscape Web Workbench pour VS2012, qui recrée le CSS chaque fois que vous enregistrez votre SCSS. J’ai commencé avec un code similaire à celui-ci:

/* Starting point: */ h1 { font-size: 1.5em; /* 24px ÷ 16px */ } 

Ensuite, j’ai essayé de le refactoriser en premier:

 /* Recfator: */ h1 { font-size: (24px / 16px)em; } 

Mais cela produit malheureusement:

 /* Result: */ h1 { font-size: 1.5 em; } /* doesn't work, gives "1.5 em" */ 

Remarquez l’ espace supplémentaire que je ne veux pas voir là. J’ai essayé plusieurs alternatives, en voici quelques unes:

 h1 { font-size: (24/16)em; } /* doesn't work, gives "1.5 em" */ h2 { font-size: 24 / 16em; } /* doesn't work, gives "24/16em" */ h3 { font-size: (24px / 16px) * 1em; } /* works but "* 1 em" feels unnecessary */ h4 { font-size: (24em) / 16; } /* works, but without "px" it's not really conveying what I mean to say */ 

J’ai aussi essayé ces variantes avec des variables (parce que je les veux quand même), mais cela n’a pas beaucoup changé la situation. Pour conserver les exemples de cette question, j’ai laissé de côté les variables. Cependant, j’accepterais volontiers une solution qui repose sur l’utilisation de variables (de manière propre).

J’ai parcouru la documentation SASS pertinente sur ‘/’ , et je suis conscient que c’est difficile pour SASS car le caractère ‘/’ a déjà une signification en CSS de base. De toute façon, j’espérais une solution propre. Est-ce que j’ai râté quelque chose?

PS Ce blog offre une solution, utilisant une fonction définie par l’utilisateur. Cela me semble un peu lourd, alors ça m’intéresse s’il y a des solutions “plus propres” conformes à mes tentatives ci-dessus. Si quelqu’un peut expliquer «l’approche de la fonction» est la meilleure solution (ou même la seule), alors je l’accepterai aussi comme une réponse.

PS Cette question apparentée semble être à peu près la même chose, bien que l’on veuille spéci fi quement faire d’autres calculs. La réponse acceptée est ma troisième solution (multipliée par 1em ), mais j’aimerais savoir s’il existe une méthode différente (plus propre) si je veux renoncer à la possibilité d’effectuer d’autres calculs. Peut-être que la méthode mentionnée dans cette question (“interpolation”) est utile pour moi?


Bottom line: comment pouvez-vous append le type d’unité (par exemple em ) au résultat d’un calcul dans SASS?

La seule façon d’append une unité à un nombre consiste à utiliser l’arithmétique .

Pour effectuer des opérations telles que la concaténation (par exemple, 1 + px ) ou l’interpolation (par exemple, #{1}px ), vous ne créerez qu’une chaîne qui ressemble à un nombre. Même si vous êtes absolument certain à 100% que vous n’utiliserez jamais votre valeur dans une autre opération arithmétique, vous ne devriez pas le faire .

En plus de ne pas pouvoir effectuer d’opérations arithmétiques, vous ne pourrez les utiliser avec aucune autre fonction nécessitant un nombre.

 $foo: 1; // a number $foo-percent: $foo + '%'; // a ssortingng .bar { color: darken(blue, $foo-percent); } 

$ amount: “1%” n’est pas un nombre pour “darken”

Voici un mixin que j’ai écrit dans le cadre de ma bibliothèque Flexbox mixin qui s’étouffera si vous passez une chaîne (pour ceux qui ne sont pas familiers avec Flexbox, la spécification originale n’autorise que des entiers pour la propriété box-flex . flex: auto ou flex: 30em ne peut pas être compatible avec la propriété comparable box-flex , de sorte que le mixin n’essaie pas d’essayer)

 @mixin flex($value: 0 1 auto, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) { @if $legacy and unitless(nth($value, 1)) { @include legacy-flex(nth($value, 1)); } @include experimental(flex, $value, flex-support-common()...); } @mixin legacy-flex($value: 0) { @include experimental(box-flex, $value, $box-support...); } 

Il n’y a rien à gagner en lançant vos chiffres sur des cordes. Toujours utiliser la multiplication pour append une unité:

 $foo: 1; // a number $foo-percent: $foo * 1%; // still a number! .bar { color: darken(blue, $foo-percent); } 

Sortie:

 .bar { color: #0000fa; } 

Vous pouvez essayer l’un de ces:

 font-size: $size * 1px; 

ou

 font-size: $size + unquote("px"); 

$size est le résultat de votre calcul.

Choisissez la méthode que vous préférez

 $font: 24px; $base: 16px; 

Pas de variables

 .item1 { font-size: #{(24px / 16px)}em; } 

Utiliser uniquement des variables

 .item2 { font-size: #{$font / $base}em; } 

Une variable

 .item3 { font-size: #{$font / 16px}em; } .item4 { font-size: #{24px / $base}em; } 

Sortie pour tous

 .item1 { font-size: 1.5em; } .item2 { font-size: 1.5em; } .item3 { font-size: 1.5em; } .item4 { font-size: 1.5em; } 

La méthode utilisée s’appelle interpolation # {}

Je suppose que la raison pour laquelle vous posez cette question est que, dans le contexte, 1 em = 16 px et que vous voulez utiliser cette relation pour convertir la taille de police cible de pixels en ems.

Si c’est le cas, la bonne chose à faire est de multiplier la taille de la police par le facteur d’échelle 1em / 16px, comme ceci:

 $h1-font-size: 24px; $body-font-size: 16px; $body-em-scale: 1em / $body-font-size; h1 { font-size: $h1-font-size * $body-em-scale; // -> 1.5em } 

ou juste:

 h1 { font-size: $h1-font-size * (1em / $body-font-size); // -> 1.5em } 

C’est exactement comme ça que ça marche en physique: si vous avez, disons, 50 moles d’eau, et vous voulez savoir combien ça pèse en grammes , vous multipliez la quantité d’eau que vous avez (= 50 mol) avec la masse molaire d’eau (≈ 18 g / mol) pour découvrir que votre échantillon d’eau pèse 50 mol × 18 g / mol ≈ 900 grammes. La conversion de pixels en ems dans SASS fonctionne de la même manière: commencez par déterminer le nombre d’em par pixel, dans le contexte dans lequel vous souhaitez utiliser la règle, puis multipliez la taille en px par ce rapport, exprimé en unités de em / px.


Ps. Bien sûr, si les unités que vous convertissiez avaient un ratio fixe que SASS connaissait déjà, alors vous pourriez simplement le faire automatiquement pour vous, en utilisant le “truc zéro plus”. Par exemple, si vous souhaitez convertir la taille de la police de px en cm, vous pouvez simplement faire:

 h1 { font-size: 0cm + $h1-font-size; // -> 0.635cm } 

Cela fonctionne car SASS vous permet d’append deux valeurs données dans des unités compatibles (comme px et cm) et d’exprimer le résultat dans les mêmes unités que la première valeur de la sum. La raison pour laquelle cette astuce ne fonctionne pas pour px -> em est que le facteur de conversion n’est pas fixe, mais dépend du contexte, et SASS ne sait pas comment faire la conversion automatiquement.