Des propriétés personnalisées très, très, très personnalisées

Retrouvez les slides en ligne sur
ffoodd.fr/paris-web.2020
et en version « commentée »
ffoodd.fr/paris-web.2020/verbose.

Les concepts-clés

À digérer avant de jouer avec les propriétés personnalisées :

  • La cascade ;
  • L’héritage ;
  • Les stratégies de repli ;
  • Les particularités.

Venez, on va bien rigoler !

Si, si, promis…

Cascade

Hop, galipette !

La cascade est l’algorithme décidant quel style est finalement appliqué.

Les propriétés personnalisées respectent la cascade, au même titre que les autres propriétés.

Galipette réalisée par un professionnel, ne tentez pas ça chez vous.

L’héritage (Mitsouko)

C’est comme ça-aaaaaa

L’héritage intervient quand la cascade n’aboutit à aucune valeur.

  1. Toutes les propriétés ne sont pas héritées !
  2. Les propriétés personnalisées sont héritées.

Valeur de repli

Quand une valeur n’est pas supportée, elle est ignorée et la cascade puis l’héritage interviennent.

Cascade

                
main {
  color: red;
  color: color(display-p3 1 .5 0);
}
              

Héritage

                
html {
  color: red;
}

main {
  color: color(display-p3 1 .5 0);
}
              

Les particularités

Une sorte de définition

Les propriétés personnalisées :

  • peuvent avoir plusieurs valeurs au même moment ;
  • sont déclaratives, comme l’ensemble de CSS ;
  • ne sont pas affectées par la propriéte all.

Rien à voir avec les variables Sass, donc !

Les capacités

Qu’est-ce qu’on va bien pouvoir faire de ça ?

Une palette de couleurs

Sara Soueidan explique l’utilisation des propriétés personnalisées combinées à hsl() pour gérer une palette de couleurs — et Una Kravets pousse la réflexion encore plus loin.

              
:root {
  --hue: 240;
  --lightness: 30%;
}

main {
  color: hsl(var(--hue), 100%, var(--lightness));
}
            
              
@media screen and (min-width: 32em) {
  :root {
    --lightness: 40%;
  }
}

@media screen and (prefers-color-scheme: dark) {
  :root {
    --lightness: 80%;
  }
}
            

De la configuration globale

Je s’appelle :root

Vous pouvez utiliser les propriétés personnalisées comme une API de surface avec vos styles :

                
:root {
  --enable-shadows: none;
}

.component {
  box-shadow: var(--enable-shadows, 0 .5rem 1rem #000);
}
              
Mark Otto propose des options globales pour (dés)activer des éléments de styles.
                
:root {
  --duration: 1;
}

.foobar {
  transition-duration: calc(var(--duration) * 250ms);
}
              
Hugo Giraudel suggère de réduire les animations globalement en se basant sur une unique propriété personnalisée.

Une cascade personnalisée

Hop, sans les mains

Miriam Suzanne a conceptualisé les cascades personnalisées, une imbrication de propriétés personnalisées via les valeurs de replis.

                  
button {
  background: var(--btn-bg--state,
    var(--btn-bg,
      var(--btn-bg--type,
        var(--btn-bg--default)
      )
    )
  );
}
            
                  
[disabled] {
  --btn-bg--state: darkgray;
}

.warn {
  --btn-bg--type: maroon;
}
            

Convertir un entier en chaîne

Ce n’est que du CSS

Cassie Evans utilise les compteurs CSS pour afficher un entier dans la propiété content.

                
.icon {
  --number-var: 23;
}

.icon::before {
  counter-reset: number var(--number-var);
  content: counter(number);
}
          

Ce n’est que du CSS, mais y’a quand même des données typées.

De la pseudo-logique

Ce n’est toujours que du CSS

Roman Komarov propose d’utiliser des propriétés personnalisées pseudo-booléennes pour qu’une propriété bascule d’une valeur calculée à une autre. Ana Tudor décortique des exemples concrets de ce qu’elle baptise DRY switching.

              
:root {
  --is-big: 0;
}

.is-big {
  --is-big: 1;
}
            
              
.block {
  padding: calc(
    25px * var(--is-big) +
    10px * (1 - var(--is-big))
  );
}
            

Du responsive sans @media

Alias, ton univers impitoya-ableuh

James Atherton utilise une astuce qu’il nomme space toggler pour se passer des media queries dans son CSS — ou presque.

              
:root {
  --media-lte-sm: initial;
}

div {
  --small-borders: var(--media-lte-sm) 2px;
  border: var(--small-borders, 15px) solid;
}
            
              
@media (min-width: 56.25em) {
  :root {
    --media-lte-sm: ;
  }
}
            

Styler votre shadow DOM

Une variable pour les gouverner tous, et dans les ténèbres les lier…

Pousser des styles vers le shadow DOM est impossible… mais hériter des propriétés personnalisées fonctionne ! Sarah Dayan donne un exemple de symbôle SVG multicolore conçu pour appeler des propriétés personnalisées définies hors de l’hôte.

              
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
  <symbol id="my-first-icon" viewBox="0 0 20 20">
    <path fill="var(--color-1, red)" d="…"/>
    <path fill="var(--color-2, blue)" d="…"/>
    <path fill="var(--color-3, green)" d="…"/>
  </symbol>
</svg>

<svg class="icon icon-colors">
  <use xlink:href="#my-first-icon"/>
</svg>

            
              
.icon-colors {
  --color-1: #c13127;
  --color-2: #ef5b49;
  --color-3: #cacaea;
}

            

Des styles réactifs

Dans chaarts, je mets en place divers type de graphiques de données en CSS, qui dépendent de propriétés personnalisées déclarées côté HTML.

Autrement dit, ces graphiques réagissent à des changements de données en temps réels si vous mettez à jour les propriétés personnalisées en JavaScript — de préférence à l’aide de la méthode .setProperty.

              
<table class="chaarts radar"
       style="--scale: 20; --step: 5; --items: 7;
       --1: 14; --2: 11; --3: 13; --4: 16; --5: 10;
       --6: 12; --7: 4; --8: var(--1);">
  […]
    <td><span>14</span></td>
  […]
</table>

            
              
.chaarts[class*="radar"] td:nth-of-type(2) span {
  --position: calc(100% - (var(--3) * 100% / (var(--scale) * var(--ratio))));
  clip-path: polygon(
    100% var(--position),
    calc(100% - (var(--2) * 100% / var(--scale))) 100%,
    100% 100%
  );
}

            
Niveau d’intérêt par domaine, sur 20
Accessibilité Référencement Performance Compatibilité Sécurité Qualité de code Test
14 11 13 16 10 12 4

Factoriser votre code

DRY

Si la même valeur à rallonge est utilisée plusieurs fois, simplifiez-vous la vie : utilisez des propriétés personnalisées !

            
:root {
  --stripes: url("data:image/svg+xml,%3Csvg width='6' height='6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
}

tr:nth-child(odd) {
  background: white var(--stripes);
}

.hero {
  background: rebeccapurple var(--stripes);
}

          

Conclusion

Les fausses bonnes idées

Ça envoie du rêve, mais…

Pensez à vos utilisateurs avant tout.

Merci

Et à bientôt

Crédits