Un design system n'est pas juste une collection de boutons et de couleurs — c'est la colonne vertébrale de la logique visuelle et structurelle de votre produit. Et s'il est bien fait, on a l'impression de tricher : intuitif, évolutif et presque magique.
Ce guide est pour les développeurs front-end qui veulent implémenter un système solide comme le roc, aussi agréable à maintenir qu'à regarder. Il s'agit de performance, de clarté, et de s'assurer que personne n'écrive plus jamais margin: 42px.
SCSS vs CSS Variables : Qui fait quoi ?
Les variables CSS (--primary-color) sont dynamiques. Elles peuvent changer à l'exécution, par JS, ou dans une media query. Elles sont donc parfaites pour les thèmes, la réactivité ou les préférences utilisateur. Les variables SCSS ($primary) sont statiques à la compilation et géniales pour la logique, les maps et le confort du dev.
Notre conseil : Utilisez les variables CSS pour tout ce qui peut varier (couleurs, espacement, thèmes). Utilisez les maps SCSS + fonctions pour la logique statique.
Vous voulez tout passer en variables CSS pour la lisibilité ? Super — soyez juste cohérent. Le meilleur système est celui que vous aimerez maintenir.
Typographie : Laissez-la s'adapter
// _typography.scss
// Variables
--font-family-titles: 'Votre police custom', 'Arial', sans-serif;
$font-size-base: 1rem;
$font-sizes: (
xxxs: 0.75rem,
xxs: 0.8125rem,
xs: 0.875rem,
s: $font-size-base,
m: 1.125rem,
l: 1.25rem,
xl: 1.5rem,
xxl: 2rem,
body-s: 0.75rem;
body-m: $font-size-base;
body-l: 1.125rem;
);
$line-height-titles: 1.2;
$line-height-global: 1.5;
$font-weights: (
light: 300,
regular: 400,
medium: 500,
bold: 700
);
// Titres & Corps de base
%heading {
font-family: var(--font-family-titles);
font-weight: $boldish;
line-height: $line-height-titles;
text-transform: uppercase;
letter-spacing: 2px;
}
%body-base {
font-family: var(--font-family-base);
font-weight: $regular;
line-height: $line-height-global;
}
@mixin font-size($key, $weight: regular) {
font-size: map-get($font-sizes, $key);
font-weight: map-get($font-weights, $weight);
}
// Headings
%heading-xxl { @include font-size(xxl, bold); }
%heading-xl { @include font-size(xl, bold); }
%heading-l { @include font-size(l, medium); }
%heading-m { @include font-size(m, medium); }
%heading-s { @include font-size(s); }
%heading-xs { @include font-size(xs); }
// Body
%body-l { @include font-size(body-l); }
%body-m { @include font-size(bpdy-m); }
%body-s { @include font-size(body-s); }
// Classes utilitaires Titres & Corps
h1 { @extend %heading-xxl; }
h2 { @extend %heading-xl; }
h3 { @extend %heading-l; }
h4 { @extend %heading-m; }
h5 { @extend %heading-s; }
h6 { @extend %heading-xs; }
body { @extend %body-m; }
Boutons avec Options
.button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.75rem 1.5rem;
border-radius: 0.375rem;
border: none;
cursor: pointer;
transition: background-color 0.2s ease-in-out;
@include font-size(m);
}
.button-primary {
@extend .button;
background-color: var(--color-primary);
color: #fff;
}
.button-secondary {
@extend .button;
background-color: transparent;
color: var(--color-primary);
border: 1px solid var(--color-primary);
}
.button svg {
width: 1rem;
height: 1rem;
}
Stratégie de Layout : Structure Intelligente
La mise en page doit être contrôlée au niveau de la .section. Chaque section reçoit un padding-inline et un margin-bottom, utilisant notre système d'espacement.
$spacers: (
none: 0,
xs: 0.5rem,
s: 1rem,
m: 2rem,
l: 4rem,
xl: 6rem
);
@mixin section-spacing($padding: m, $margin: l) {
padding-inline: map-get($spacers, $padding);
margin-bottom: map-get($spacers, $margin);
}
.section {
@include section-spacing();
}
div.x {
padding-inline: map-get($spacers, s);
}
Starter Kit SCSS Final (Édition 2025)
// scss/core/_variables.scss
// Variables dynamiques (CSS)
:root {
--font-family-titles: 'Votre police titres', 'Arial', sans-serif;
--font-family-base: 'Votre police corps', 'Arial', sans-serif;
}
// Variables statiques (SCSS)
$font-sizes: (
xxxs: 0.75rem,
xxs: 0.8125rem,
xs: 0.875rem,
s: 1rem,
m: 1.125rem,
l: 1.25rem,
xl: 1.5rem,
xxl: 2rem,
body-s: 0.75rem,
body-m: 1rem,
body-l: 1.125rem
);
$line-heights: (
titles: 1.2,
global: 1.5
);
$font-weights: (
light: 300,
regular: 400,
medium: 500,
bold: 700
);
$spacers: (
none: 0,
xs: 0.5rem,
s: 1rem,
m: 2rem,
l: 4rem,
xl: 6rem
);
$colors: (
primary: #007bff,
secondary: #6c757d,
// Ajoutez d'autres couleurs au besoin
);
// scss/core/_functions.scss
@function spacing($key) {
@return map-get($spacers, $key);
}
// scss/core/_mixins.scss
@mixin font-size($key, $weight: regular) {
font-size: map-get($font-sizes, $key);
font-weight: map-get($font-weights, $weight);
}
@mixin section-spacing($padding: m, $margin: l) {
padding-inline: spacing($padding);
margin-bottom: spacing($margin);
}
// scss/core/_typography.scss
%heading {
font-family: var(--font-family-titles);
font-weight: bold;
text-transform: uppercase;
letter-spacing: 2px;
}
%body-base {
font-family: var(--font-family-base);
font-weight: $regular;
line-height: $line-height-global;
}
// Classes utilitaires
h1 { @extend %heading; @include font-size(xxl); }
h2 { @extend %heading; @include font-size(xl); }
h3 { @extend %heading; @include font-size(l, medium); }
h4 { @extend %heading; @include font-size(m, medium); }
h5 { @extend %heading; @include font-size(s); }
h6 { @extend %heading; @include font-size(xs); }
body { @extend %body-base; @include font-size(body-m); }
// scss/components/_buttons.scss
@use 'core' as *;
.button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.75rem 1.5rem;
border-radius: 0.375rem;
border: none;
cursor: pointer;
transition: background-color 0.2s ease-in-out;
@include font-size(m);
}
.button-primary {
@extend .button;
background-color: map-get($colors, primary);
color: #fff;
}
.button-secondary {
@extend .button;
background-color: transparent;
color: map-get($colors, primary);
border: 1px solid map-get($colors, primary);
}
.button svg {
width: 1rem;
height: 1rem;
}
// scss/components/_layout.scss
.section {
@include section-spacing();
}
// scss/main.scss
@use 'core/index' as *;
@use 'components/buttons';
@use 'components/layout';
Cette structure assure lisibilité, performance et maintenabilité à long terme. C'est léger, mais profond.
En bref ? Un bon design system ne crie pas. Il chuchote : "t'inquiète, je gère". Utilisez des placeholders, employez les mixins comme votre sauce secrète préférée, commentez tout comme si vous écriviez une lettre d'amour à votre futur vous, et construisez quelque chose que même un développeur grincheux un lundi matin appréciera. Rappelez-vous, rien ne sert de créer des systèmes trop complexes juste pour le show. Certes, ça impressionne au début, mais si ce n'est pas maintenable, les devs se perdent, l'onboarding devient un labyrinthe, et bientôt votre design system ressemble à ce cousin qui apporte trop de jeux de société compliqués aux repas de famille — bien intentionné mais totalement déroutant.