Récemment, j'ai écrit une boucle SASS très basique qui offre plusieurs cours de rembourrage et de marge. Rien de spécial, juste une carte SASS avec 11 valeurs d'espacement, des boucles sont utilisées pour créer la classe de rembourrage et de marges de chaque côté. Comme nous le verrons, cela fonctionne, mais finira par produir une bonne quantité de CSS. Nous le refactora pour personnaliser les propriétés à l'aide de CSS et rendre le système plus concis.
Voici l'implémentation originale de SASS:
<code>$space-stops: ( '0': 0, '1': 0.25rem, '2': 0.5rem, '3': 0.75rem, '4': 1rem, '5': 1.25rem, '6': 1.5rem, '7': 1.75rem, '8': 2rem, '9': 2.25rem, '10': 2.5rem, ); @each $key, $val in $space-stops { .p-#{$key} { padding: #{$val} !important; } .pt-#{$key} { padding-top: #{$val} !important; } .pr-#{$key} { padding-right: #{$val} !important; } .pb-#{$key} { padding-bottom: #{$val} !important; } .pl-#{$key} { padding-left: #{$val} !important; } .px-#{$key} { padding-right: #{$val} !important; padding-left: #{$val} !important; } .py-#{$key} { padding-top: #{$val} !important; padding-bottom: #{$val} !important; } .m-#{$key} { margin: #{$val} !important; } .mt-#{$key} { margin-top: #{$val} !important; } .mr-#{$key} { margin-right: #{$val} !important; } .mb-#{$key} { margin-bottom: #{$val} !important; } .ml-#{$key} { margin-left: #{$val} !important; } .mx-#{$key} { margin-right: #{$val} !important; margin-left: #{$val} !important; } .my-#{$key} { margin-top: #{$val} !important; margin-bottom: #{$val} !important; } }</code>
Ce code fonctionne bien et génère toutes les classes d'utilité requises. Cependant, il peut également devenir rapidement gonflé. Dans mon cas, ils sont environ 8,6 Ko lorsqu'ils sont non compressés et moins de 1 Ko après la compression. (Brotli est de 542 octets, GZIP est de 925 octets.)
Puisqu'ils sont très répétitifs, la compression fonctionne très bien, mais je ne peux toujours pas me débarrasser du sentiment que toutes ces classes sont redondantes. De plus, je n'ai même pas fait de points d'arrêt petits / moyens / grands qui sont assez typiques pour ce type de classe d'assistance.
Voici un exemple artificiel d'une version réactive après avoir ajouté une petite / moyenne / grande classe. Nous réutiliserons la carte d'état d'espace $ définie plus tôt et mettrons le code en double dans le mixin
<code>@mixin finite-spacing-utils($bp: '') { @each $key, $val in $space-stops { .p-#{$key}#{$bp} { padding: #{$val} !important; } .pt-#{$key}#{$bp} { padding-top: #{$val} !important; } .pr-#{$key}#{$bp} { padding-right: #{$val} !important; } .pb-#{$key}#{$bp} { padding-bottom: #{$val} !important; } .pl-#{$key}#{$bp} { padding-left: #{$val} !important; } .px-#{$key}#{$bp} { padding-right: #{$val} !important; padding-left: #{$val} !important; } .py-#{$key}#{$bp} { padding-top: #{$val} !important; padding-bottom: #{$val} !important; } .m-#{$key}#{$bp} { margin: #{$val} !important; } .mt-#{$key}#{$bp} { margin-top: #{$val} !important; } .mr-#{$key}#{$bp} { margin-right: #{$val} !important; } .mb-#{$key}#{$bp} { margin-bottom: #{$val} !important; } .ml-#{$key}#{$bp} { margin-left: #{$val} !important; } .mx-#{$key}#{$bp} { margin-right: #{$val} !important; margin-left: #{$val} !important; } .my-#{$key}#{$bp} { margin-top: #{$val} !important; margin-bottom: #{$val} !important; } } } @include finite-spacing-utils; @media (min-width: 544px) { @include finite-spacing-utils($bp: '_sm'); } @media (min-width: 768px) { @include finite-spacing-utils($bp: '_md'); } @media (min-width: 1024px) { @include finite-spacing-utils($bp: '_lg'); }</code>
Il est environ 41,7 Ko lorsqu'il est non compressé (Brotli est d'environ 1 Ko et GZIP est d'environ 3 Ko). Il se compresse toujours bien, mais c'est un peu ridicule.
Je sais que data-*
peut être référencé à partir de CSS à l'aide de la fonction [attr()
, donc je me demande s'il est possible d'utiliser les attributs data-*
margin: calc(attr(data-m) * 0.25rem)
data-m="1"
calc()
attr()
data-m="1@md"
Cela peut être très puissant.
Mais la fin de l'histoire est: vous ne pouvez pas (actuellement) utiliser attr()
avec n'importe quel attribut sauf content
. Dommage. Mais lors de la recherche d'informations attr()
et calc()
, j'ai trouvé ce commentaire intéressant de Simon Rigérit sur Stack Overflow, qui suggère de définir les variables CSS directement dans les propriétés de style en ligne. Ahhh!
Par conséquent, les éléments suivants peuvent être effectués:<div style="--p: 4;"> , puis dans CSS:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> <code>:root { --p: 0; } [style*='--p:'] { padding: calc(0.25rem * var(--p)) !important; }</code></pre><div class="contentsignin">Copier après la connexion</div></div>
<p> Dans <code>padding: 1rem !important;
style="--p: 4;"
… Maintenant, vous avez un assistant monstre de classe utilitaire d'espacement infiniment évolutif.
Voici à quoi il pourrait ressembler dans CSS:
<code>:root { --p: 0; --pt: 0; --pr: 0; --pb: 0; --pl: 0; --px: 0; --py: 0; --m: 0; --mt: 0; --mr: 0; --mb: 0; --ml: 0; --mx: 0; --my: 0; } [style*='--p:'] { padding: calc(0.25rem * var(--p)) !important; } [style*='--pt:'] { padding-top: calc(0.25rem * var(--pt)) !important; } [style*='--pr:'] { padding-right: calc(0.25rem * var(--pr)) !important; } [style*='--pb:'] { padding-bottom: calc(0.25rem * var(--pb)) !important; } [style*='--pl:'] { padding-left: calc(0.25rem * var(--pl)) !important; } [style*='--px:'] { padding-right: calc(0.25rem * var(--px)) !important; padding-left: calc(0.25rem * var(--px)) !important; } [style*='--py:'] { padding-top: calc(0.25rem * var(--py)) !important; padding-bottom: calc(0.25rem * var(--py)) !important; } [style*='--m:'] { margin: calc(0.25rem * var(--m)) !important; } [style*='--mt:'] { margin-top: calc(0.25rem * var(--mt)) !important; } [style*='--mr:'] { margin-right: calc(0.25rem * var(--mr)) !important; } [style*='--mb:'] { margin-bottom: calc(0.25rem * var(--mb)) !important; } [style*='--ml:'] { margin-left: calc(0.25rem * var(--ml)) !important; } [style*='--mx:'] { margin-right: calc(0.25rem * var(--mx)) !important; margin-left: calc(0.25rem * var(--mx)) !important; } [style*='--my:'] { margin-top: calc(0.25rem * var(--my)) !important; margin-bottom: calc(0.25rem * var(--my)) !important; }</code>
Ceci est très similaire à la première boucle SASS ci-dessus, mais il n'y a pas de boucles 11 - mais elle est infinie. Il est environ 1,4 Ko non compressé, Brotli est de 226 octets et GZIP est de 284 octets.
Si vous voulez étendre cela à un point d'arrêt, le message malheureux est que vous ne pouvez pas mettre le caractère "@" dans le nom de la variable CSS (bien qu'il soit étrangement autorisé à utiliser des emojis et d'autres caractères UTF-8). Vous pourriez donc être en mesure de définir des noms de variables comme P_SM ou SM_P. Vous devez ajouter des variables CSS supplémentaires et des requêtes multimédias pour gérer tout cela, mais elle ne se développera pas de façon exponentielle comme le nom de classe CSS traditionnel créé à l'aide d'une boucle Sass pour la boucle.
Ce qui suit est la version réactive équivalente. Nous utiliserons à nouveau Sass Mixin pour réduire la duplication:
<code>:root { --p: 0; --pt: 0; --pr: 0; --pb: 0; --pl: 0; --px: 0; --py: 0; --m: 0; --mt: 0; --mr: 0; --mb: 0; --ml: 0; --mx: 0; --my: 0; } @mixin infinite-spacing-utils($bp: '') { [style*='--p#{$bp}:'] { padding: calc(0.25rem * var(--p#{$bp})) !important; } [style*='--pt#{$bp}:'] { padding-top: calc(0.25rem * var(--pt#{$bp})) !important; } [style*='--pr#{$bp}:'] { padding-right: calc(0.25rem * var(--pr#{$bp})) !important; } [style*='--pb#{$bp}:'] { padding-bottom: calc(0.25rem * var(--pb#{$bp})) !important; } [style*='--pl#{$bp}:'] { padding-left: calc(0.25rem * var(--pl#{$bp})) !important; } [style*='--px#{$bp}:'] { padding-right: calc(0.25rem * var(--px#{$bp})) !important; padding-left: calc(0.25rem * var(--px)#{$bp}) !important; } [style*='--py#{$bp}:'] { padding-top: calc(0.25rem * var(--py#{$bp})) !important; padding-bottom: calc(0.25rem * var(--py#{$bp})) !important; } [style*='--m#{$bp}:'] { margin: calc(0.25rem * var(--m#{$bp})) !important; } [style*='--mt#{$bp}:'] { margin-top: calc(0.25rem * var(--mt#{$bp})) !important; } [style*='--mr#{$bp}:'] { margin-right: calc(0.25rem * var(--mr#{$bp})) !important; } [style*='--mb#{$bp}:'] { margin-bottom: calc(0.25rem * var(--mb#{$bp})) !important; } [style*='--ml#{$bp}:'] { margin-left: calc(0.25rem * var(--ml#{$bp})) !important; } [style*='--mx#{$bp}:'] { margin-right: calc(0.25rem * var(--mx#{$bp})) !important; margin-left: calc(0.25rem * var(--mx#{$bp})) !important; } [style*='--my#{$bp}:'] { margin-top: calc(0.25rem * var(--my#{$bp})) !important; margin-bottom: calc(0.25rem * var(--my#{$bp})) !important; } } @include infinite-spacing-utils; @media (min-width: 544px) { @include infinite-spacing-utils($bp: '_sm'); } @media (min-width: 768px) { @include infinite-spacing-utils($bp: '_md'); } @media (min-width: 1024px) { @include infinite-spacing-utils($bp: '_lg'); }</code>
Environ 6,1 kb n'est pas compressé, le brotli est de 428 octets et GZIP est de 563 octets.
Je pense qu'écrire comme<div style="--px:2; --my:4;"> Est-ce que ce HTML est agréable à l'œil, ou bon développeur ergonomique ... non, pas spécial. Mais cette approche est-elle possible dans certains cas, comme si vous (pour une raison quelconque) avez-vous besoin de très peu de CSS, ou si vous n'avez pas du tout besoin de fichiers CSS externes? Oui, bien sûr, je pense que cela peut. Il convient de souligner ici que les variables CSS attribuées dans les styles en ligne ne fuient pas. Ils n'agissent que sur l'élément actuel et ne modifient pas la valeur de la variable globale. Dieu merci! Une chose étrange que j'ai trouvée jusqu'à présent est que Devtools (au moins dans Chrome, Firefox et Safari) ne rapportera pas les styles en utilisant cette technique dans l'onglet Styles de calcul.<p> Il convient également de mentionner que j'ai utilisé les propriétés traditionnelles de rembourrage et de marge ainsi que -top,-droite, -bottom et -left, mais vous pouvez utiliser des propriétés logiques équivalentes telles que le bloc-bloc et le padding-inline. En mélangeant sélectivement les propriétés logiques et traditionnelles, il est même possible de réduire quelques octets. De cette façon, j'ai réussi à compresser Brotli à 400 octets et à GZIP à 521 octets.</p>
<h3> Autres cas d'utilisation</h3>
<p> Cela semble s'adapter mieux aux proportions incrémentielles linéaires (c'est pourquoi le rembourrage et la marge semblent être un bon cas d'utilisation), mais je peux voir que cela pourrait fonctionner pour la largeur et la hauteur (nombre de colonnes et / ou de largeur) dans un système de grille. <strong>Peut-être que</strong> cela fonctionne pour la typographie (mais peut-être pas).</p>
<p> Je suis très préoccupé par la taille des fichiers, mais il peut y avoir d'autres utilisations ici auxquelles je ne pensais pas. Peut-être que <strong>vous</strong> n'écrirez pas votre code de cette façon, mais l'outil CSS critique pourrait refacter le code pour utiliser cette méthode.</p>
<h3> Approfondir</h3>
<p> Lorsque je creuse plus profondément, j'ai constaté qu'Ahmad était parlé de mixage <code>calc()
avec des affectations variables CSS dans les styles en ligne, en particulier pour les tailles d'avatar. L'article de Miriam Suzanne sur Smashing Magazine en 2019 n'utilise pas calc()
mais partage des fonctionnalités incroyables qui peuvent être réalisées en utilisant des affectations variables dans les styles en ligne.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!