Réduire la répétition des styles avec des fonctions CSS

Fonctionnalités Web : @function

La gestion de feuilles de style volumineuses entraîne souvent une logique répétitive, en particulier lorsqu'il s'agit de jetons de système de conception tels que des dégradés ou des modèles de mise en page responsifs.

La règle CSS @function vous permet d'encapsuler cette logique dans des fonctions réutilisables et paramétrées, ce qui rend votre CSS plus facile à gérer, plus cohérent et plus DRY (Don't Repeat Yourself).

Syntaxe de @function

Une fonction personnalisée est définie à l'aide de la règle @function suivie d'un nom avec tiret et d'une liste de paramètres. La fonction renvoie une valeur à l'aide de la propriété result.

@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
  /* Logic goes here */
  result: var(--input1);
}

Concepts clés

  • Paramètres : doivent commencer par un double tiret (--).
  • Valeurs par défaut : vous pouvez fournir des valeurs par défaut à l'aide d'un signe deux-points (:).
  • Résultat : la propriété result détermine la valeur renvoyée par la fonction. La dernière result déclarée dans le corps de la fonction l'emporte.
  • Portée : les paramètres et les variables définis dans la fonction ont une portée locale.
  • Types : vous pouvez exiger que les paramètres et la valeur renvoyée correspondent à un type CSS avec une notation entre crochets (par exemple, <color>) et autoriser plusieurs types avec la fonction type (par exemple, type(<number> | <percentage>)).

Exemples pratiques

1. Jetons du système de conception (dégradés)

Assurez des dégradés de couleurs cohérents dans votre application en encapsulant la logique de dégradé. --angle fournit une valeur par défaut pour assurer la cohérence, qui peut être remplacée.

@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
  result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}

.card {
  background: --fancy-gradient(#ed73d7, #5d87e9);
}

2. Logique de mise en page conditionnelle

Vous pouvez utiliser @media ou d'autres requêtes directement dans une fonction pour renvoyer différentes valeurs en fonction de l'environnement. Lorsque vous utilisez une logique conditionnelle dans une fonction, notez que @function ne renvoie pas la première valeur de result, mais suit plutôt la cascade CSS et renvoie la dernière valeur qui correspond en fonction de la taille de l'écran, de la taille du conteneur ou d'une autre requête.

@function --grid-template(--count <number>){
  /* MANDATORY: Put default value first. */
  result: 1fr; /* Default: stack */
  @media (min-width: 800px) {
    result: repeat(var(--count), 1fr); /* Grid on larger screens */
  }
}

main {
  display: grid;
  grid-template-columns: --grid-template(2);
}

Bonnes pratiques

  • Utilisez des noms avec tirets : ajoutez toujours le préfixe -- aux noms et paramètres de vos fonctions.
  • Fournir des valeurs par défaut : rendez vos fonctions plus robustes en fournissant des valeurs par défaut pertinentes.
  • Faites simple : utilisez des fonctions pour la logique qui est réellement répétée ou complexe. Ne compliquez pas inutilement les paires propriété-valeur simples.
  • Utilisez des types : assurez-vous que vos paramètres et vos valeurs de retour sont des types attendus.
  • Envisagez des alternatives précompilées : pour les fonctions qui ne dépendent pas des entrées utilisateur, des requêtes média ou d'autres variantes côté client, envisagez d'utiliser un précompilateur CSS pour éviter d'effectuer des tâches inutiles sur le client.

Stratégies de remplacement

Dans les navigateurs qui ne sont pas compatibles avec les fonctions CSS, les valeurs définies à l'aide de fonctions CSS ne seront pas valides. Pour assurer la compatibilité avec d'autres navigateurs, indiquez d'abord une valeur de remplacement pour la propriété. Cette valeur sera remplacée dans les navigateurs compatibles avec la fonction CSS.

.card {
  /* Provide fallback, in this case a solid color. */
  background: #5d87e9;
  background: --fancy-gradient(#ed73d7, #5d87e9);
}

main {
  /* Provide fallback, in this case a simple stacked default. */
  grid-template-columns: 1fr;
  grid-template-columns: --grid-template(2);
}

Si vous devez réduire la répétition des styles tout en prenant en charge d'autres navigateurs, envisagez d'utiliser un précompilateur CSS avec des fonctions, comme Sass.