Tailwind 4 est à l'horizon depuis un certain temps, l'équipe ayant rendu ses progrès open source pour la première fois en mars 2024. L'un des changements les plus remarquables, à mon avis, est le changement d'une configuration basée sur JavaScript à une configuration basée sur CSS. Tailwind 4 est actuellement en version bêta, et d'après ce que j'ai compris, l'équipe est encore confrontée à certains défis, notamment avec la compatibilité Safari.
REMARQUE : plus loin dans l'article, nous supposerons que vous utilisez un framework/une bibliothèque basé sur des composants, mais les concepts abordés sont facilement transférables à d'autres approches.
J'ai entendu quelques plaintes à ce sujet, notamment de la part d'utilisateurs de TypeScript. Cependant, la feuille de route de Tailwind 4.0 inclut la prise en charge du classique tailwind.config.js comme priorité absolue :
Prise en charge des fichiers de configuration JavaScript — réintroduction de la compatibilité avec le fichier tailwind.config.js classique pour faciliter la migration vers la v4.
Cela dit, il semble que cela soit principalement destiné à des fins de migration et ne constitue peut-être pas une solution durable à long terme.
Sous le capot Tailwind 4 utilise les nouvelles règles CSS @property pour définir des propriétés personnalisées internes.
Nous utilisons @property pour définir nos propriétés personnalisées internes avec les types et contraintes appropriés
Dans l'état actuel des choses, je ne parviens pas à trouver une prise en charge décente de la mise en évidence de la syntaxe pour les règles @property dans le code VS. J'ai contacté Bluesky pour voir si quelqu'un a eu plus de chance que moi.
J'espère qu'un meilleur support @property pourra nous aider à l'avenir, nous en reparlerons plus tard.
La règle @property représente un enregistrement de propriété personnalisée directement dans une feuille de style sans avoir à exécuter de JavaScript. Des règles @property valides aboutissent à une propriété personnalisée enregistrée, ce qui revient à appeler registerProperty() avec des paramètres équivalents.
Maintenant que nous avons couvert les changements à venir dans Tailwind 4 et leur impact potentiel, prenons un moment pour parler des jetons de conception. Si vous n'êtes pas familier avec le terme, voici une explication rapide : les jetons de conception sont une méthode de stockage et de gestion des décisions de conception dans un format cohérent et réutilisable, généralement sous forme de variables. Ils représentent les propriétés visuelles clés d'un système de conception, comme les couleurs, la typographie, l'espacement, les ombres, de manière structurée. L'objectif est de centraliser ces valeurs de conception afin qu'elles puissent être facilement mises à jour, maintenues et partagées sur différentes plateformes et outils.
Les systèmes de conception sont généralement constitués de deux principaux types de valeurs : les valeurs du système et les valeurs des composants. Par exemple, les valeurs de votre système pourraient ressembler à ceci :
const SYSTEM_TOKENS: ISystemTokens = { /* ... */ COLORS: { /* ... */ GREEN: { LIGHT: "#E0E5D9", MEDIUM: "#3F6212", DARK: "#28331A", } /* ... */ }, TYPOGRAPHY: { /* ... */ } /* ... */ }
Vous pouvez ensuite référencer les valeurs de votre système dans vos jetons de composants comme ceci :
import { SYSTEM_TOKENS } from "..."; const BUTTON_VALUES: IButtonTokens = { /* ... */ COLORS: { /* ... */ BACKGROUND: SYSTEM_TOKENS.COLORS.GREEN.DARK, /* ... */ }, TYPOGRAPHY: { /* ... */ } /* ... */ }
Si vous souhaitez en savoir plus sur les systèmes de conception, cela vaut la peine d'explorer des systèmes bien connus comme Material Design.
Il y a environ une semaine, j'ai écrit un article traitant d'une approche alternative que j'utilise pour créer des variantes de composants avec Tailwind CSS. En bref, l'article explore comment nous pouvons exploiter les variables CSS aux côtés de Tailwind pour gérer des variantes complexes, en définissant les valeurs des variantes en ligne via des accessoires de composants dynamiques et un mappage de variables. Si vous êtes curieux de savoir comment je suis arrivé à cette approche, vous pouvez en savoir plus ici : Une approche différente de l'écriture de variantes de composants avec Tailwind CSS.
Nous devrions commencer par identifier les parties de notre composant qui dépendent des jetons de conception. Comme mentionné précédemment, cela inclura les couleurs, la typographie, l'espacement et toute autre valeur système fixe faisant partie intégrante de votre conception. Jetons un coup d'œil au composant Button suivant, sans jetons de conception :
<button> <p>In the example above, we can pinpoint several values that can be tokenized. Each of the following classes could correspond to a value in our design system:</p> <ul> <li>p-4</li> <li>bg-red</li> <li>text-white</li> </ul> <p>Now that we've identified the values that can be tokenised, we can categorise them into two groups: static values and dynamic values. Static values are those in your component that remain constant, while dynamic values are those that can change based on the props passed to the component. For our example we'll make the padding (p-4) static, while the text colour (text-white) and background (bg-red) should be set dynamically via a theme prop.</p> <h3> Creating the tokens </h3> <h4> Tailwind 4 config </h4> <p>First we need to define our System tokens in the new Tailwind CSS config:<br> </p> <pre class="brush:php;toolbar:false">@import "tailwindcss"; @theme { --color-white: #FFFFFF; --color-green-light: #E0E5D9; --color-green-medium: #3F6212; --color-green-dark: #28331A; --color-red-light: #F4CCCC; --color-red-medium: #D50000; --color-red-dark: #640000; --spacing-sm: 1rem; --spacing-md: 2rem; }
Ensuite, nous devons créer notre fichier system.tokens.ts :
export type TColor = "--color-white" | "--color-green-light" | "--color-green-medium" | "--color-green-dark" | "--color-red-light" | "--color-red-medium" | "--color-red-dark"; export type TSpacing = "--spacing-sm" | "--spacing-md"; interface ISystemTokens { COLORS: { WHITE: TColor; GREEN: { LIGHT: TColor; MEDIUM: TColor; DARK: TColor; }, RED: { LIGHT: TColor; MEDIUM: TColor; DARK: TColor; } }, SPACING: { SMALL: TSpacing; MEDIUM: TSpacing; } } export const SYSTEM_TOKENS: ISystemTokens { COLORS: { WHITE: "--color-white"; GREEN: { LIGHT: "--color-green-light"; MEDIUM: "--color-green-light"; DARK: "--color-green-light"; }, RED: { LIGHT: "--color-red-light"; MEDIUM: "--color-red-medium"; DARK: "--color-red-dark"; } }, SPACING: { SMALL: "--spacing-sm"; MEDIUM: "--spacing-md"; } }
Les jetons de conception de système peuvent être référencés dans des conceptions comme celle-ci :
$system.COLORS.GREEN.LIGHT.
Dans un monde idéal, nous pourrions exporter directement les types des règles @property de notre fichier CSS vers nos types TColor et TSpacing, un peu comme la façon dont les importations SCSS peuvent être transformées en JavaScript. Malheureusement, pour l’instant, à ma connaissance, cela n’est pas possible.
Maintenant que nous avons implémenté nos jetons système, nous pouvons commencer à les intégrer dans nos composants. La première étape consiste à configurer notre fichier Pour récapituler, voici comment notre composant Button a été structuré : Les jetons de conception de composants peuvent être référencés dans des conceptions comme ceci : $component.Button.THEME.PRIMARY.backgroundColor. Ma préférence pour les conventions de dénomination est d'utiliser : $component : différencier les jetons $system et $component C'est en fin de compte une question de préférence personnelle, et c'est à vous de décider ce qui fonctionne le mieux pour votre flux de travail. Comme je l'ai mentionné plus tôt dans l'article, j'ai déjà écrit sur l'exploration d'une approche différente de l'écriture de variantes de composants avec Tailwind CSS. Je ferai référence à cette approche ici, donc si vous ne l'avez pas encore lu, il peut être utile de la consulter d'abord pour comprendre le contexte derrière cette méthode. Cette partie de l'article supposera que vous utilisez un framework ou une bibliothèque Javascript pour créer vos composants. Nous devons remplacer les classes tokenisables existantes par des classes Tailwind alimentées par des variables CSS. Notez que les noms de variables correspondent à ceux de nos interfaces de jetons de composants à 2 boutons, IButtonStaticTokens et IButtonThemeTokens ; 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!
<button>
<p>Earlier, we discussed the distinction between static values (like p-4) and dynamic values (like bg-red and text-white). This distinction will guide how we organise our design tokens. Static properties, like p-4, should be grouped under STATIC, while dynamic properties, like bg-red and text-white, should be grouped under the appropriate prop identifier. In this case, since we’re controlling bg-red and text-white through a theme prop, they should be placed under the THEME section in our tokens file. For our example we'll assume 2 theme variables - PRIMARY and SECONDARY.<br>
</p>
<pre class="brush:php;toolbar:false">import { SYSTEM_TOKENS, TColor, TSpacing } from "./system.tokens.ts";
import { TTheme } from "./Button"; // PRIMARY, SECONDARY
interface IButtonStaticTokens {
padding: TSpacing;
}
interface IButtonThemeTokens {
backgroundColor: TColor;
textColor: TColor;
}
export const STATIC: IButtonStaticTokens {
padding: "--spacing-sm";
}
export const THEME: IButtonStaticTokens {
PRIMARY: {
backgroundColor: "--color-red-dark";
textColor: "--color-red-light";
},
SECONDARY: {
backgroundColor: "--color-green-dark";
textColor: "--color-green-light";
};
}
$component.
PROP_NAME : cas constant
PROP_VALUE : doit suivre le boîtier de la valeur de l'accessoire interne
Nom du jeton (backgroundColor) : Camel case*
Utiliser des jetons de conception dans les composants
Mise à jour du composant Button
<bouton>
<p>Maintenant que nous avons mis à jour nos classes, nous devons appliquer dynamiquement les styles de composants et mettre à jour les variables. Pour y parvenir, nous utiliserons une fonction variableMap sur le composant. Essentiellement, cette fonction mappe nos jetons de Button.tokens.ts aux variables CSS en ligne directement sur le composant, que nos classes peuvent ensuite référencer. Pour un exemple de carte variable, veuillez consulter la fin de cet article.<br>
</p>
<pre class="brush:php;toolbar:false"><modèle>
<bouton
:style="[variableMap(STATIC), variableMap(THEME[props.THEME])]"
>
<h2>
Conclusion
</h2>
<p>J'attends avec impatience la sortie de Tailwind 4 et les changements que l'équipe apportera d'ici là. J'ai aimé expérimenter des idées pour relever certains des défis liés aux jetons de conception, aux variantes et à la sécurité des types.</p>
<p>Il s'agit d'une approche expérimentale sur laquelle je suis sûr qu'il y aura des opinions bien arrêtées.</p>
<p>Si vous avez trouvé cet article intéressant ou utile, suivez-moi sur Bluesky (je suis le plus actif ici), Medium, Dev et/ou Twitter.</p>