La Matrice Data-Driven

Comment un attribut HTML pilote toute la géométrie CSS sans JavaScript

Pour qui ? À toute personne qui a lu l'article du concept de base sur la Matrice 4×4 (et qui se demande comment le navigateur sait quelle lettre dessiner sans une seule ligne de JavaScript).

Prérequis : comprendre le principe de clip-path: polygon() et des variables CSS --A-x1 à --D-x4. Si ces notions sont floues, commence par la page du concept de la matrice.

Ce qu'on revoit : utiliser un attribut data-* comme signal CSS pour sélectionner, configurer et afficher un composant entier, une lettre.

Table des matières

1. Le Problème : comment passer d'un attribut à une forme ?

Dans la Matrice, chaque lettre est un polygone différent. Le L est fait de 6 points, le N de 10 points, le O de 16 points avec une fente invisible. Comment dire au navigateur lequel afficher ?

Les solutions naïves ont toutes un défaut :

L'objectif est d'avoir un seul type d'élément, un seul attribut, 26 formes possibles.

2. Le Concept : l'attribut comme source de vérité

RAPPEL : En HTML, un attribut data-* est une donnée attachée à un élément. Le navigateur l'ignore pour le rendu, mais CSS peut le lire avec le sélecteur d'attribut [attr="valeur"].

C'est exactement ce dont on a besoin : stocker la lettre voulue dans le HTML, et laisser CSS décider de la forme à afficher en fonction de cette valeur.

<!-- HTML : on déclare la donnée -->
<div data-matrice-char="L" role="img" aria-label="Lettre L"> </div>

<!-- CSS : on réagit à la donnée -->
[data-matrice-char="L"]::after {
  clip-path: polygon(
    var(--A-x1) var(--R1-y1), ...
  );
}

L'élément <div> est une coquille vide. Sa seule responsabilité est de porter l'attribut data-matrice-char. CSS fait le reste : il choisit le bon clip-path, définit les variables de la grille, et affiche la lettre via un pseudo-élément ::after.

C'est le principe data-driven : la donnée (le caractère) pilote le rendu (la géométrie), sans couche logique intermédiaire.

3. Le Code : anatomie d'un composant data-driven

la syntaxe

Je me suis rendu compte que je n'ai pas vraiment expliqué le [data-*]. Le sélecteur d'attribut CSS s'écrit entre crochets. La valeur doit correspondre exactement à l'attribut HTML :

/* Sélecteur générique : tout élément portant data-matrice-char, peu importe sa valeur */
[data-matrice-char] { ... }

/* Sélecteur spécifique : uniquement la lettre L */
[data-matrice-char="L"]::after { ... }

les conditions d'utilisation

On utilise data-matrice-char dès qu'un élément HTML doit afficher une lettre de la Matrice. Une règle par valeur possible, une seule source de vérité par lettre.

l'implémentation complète

Le composant se construit en trois couches CSS :

variables et pseudo-élément

Tous les éléments [data-matrice-char] partagent les mêmes variables de grille et le même pseudo-élément ::after qui porte la forme :

[data-matrice-char] {
  --size: 240px;
  --offset: 12px;
  --bg: var(--clr-brand);

  /* Grille 4×4 dérivée de --offset */
  --cell-size: calc(
    (var(--size) - (3 * var(--offset))) / 4
  );
  --inner-size: calc(
    var(--cell-size) - (2 * var(--offset))
  );

  /* Repères X — 4 colonnes × 4 points */
  --A-x1: 0px;
  --A-x2: var(--offset);
  --A-x3: calc(var(--cell-size) - var(--offset));
  --A-x4: var(--cell-size);
  /* ...idem pour B, C, D */

  width: var(--size);
  height: var(--size);
  position: relative;
}

[data-matrice-char]::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--bg);
  /* clip-path défini par lettre */
}

La couche spécifique : le polygone par lettre

Chaque valeur d'attribut déclenche son propre clip-path. Le sélecteur [data-matrice-char="X"]::after ne s'applique qu'à cette lettre précise. Exemple avec le T :

[data-matrice-char="T"]::after {
  clip-path: polygon(
    /* Barre horizontale */
    var(--A-x1) var(--R1-y1),
    var(--D-x4) var(--R1-y1),
    var(--D-x4) var(--R1-y2),
    var(--B-x3) var(--R1-y2),
    /* Fût central */
    var(--B-x3) var(--R4-y4),
    var(--B-x2) var(--R4-y4),
    var(--B-x2) var(--R1-y2),
    var(--A-x1) var(--R1-y2)
  );
}

Aucune coordonnée n'est codée en dur. Tous les points sont des variables CSS calculées depuis --offset. Modifier une seule valeur suffit à redessiner la lettre entière.

Les classes modificatrices

La forme est figée par l'attribut. La matière est libre : on la change avec une classe CSS additionnelle sans toucher au polygone :

/* Couleur analogue */
[data-matrice-char].accent {
  --bg: var(--clr-analogue);
}

/* Fond inversé + ombre drop */
[data-matrice-char].inverted {
  --bg: var(--clr-text);
  filter: drop-shadow(
    8px 8px 0 var(--clr-brand)
  );
}

/* Texture pointillée */
[data-matrice-char].texture::after {
  background-image: radial-gradient(
    var(--clr-text) 2px,
    var(--clr-brand) 2px
  );
  background-size: 8px 8px;
}

Pourquoi ce choix plutôt qu'un autre

Un attribut data-* est une métadonnée sémantique. Il décrit ce qu'est l'élément, pas comment il doit s'afficher. CSS lit cette métadonnée et décide du rendu. C'est une séparation nette des responsabilités :

HTML
Porte la donnée : data-matrice-char="A". Porte l'accessibilité : role="img", aria-label="Lettre A".
CSS
Réagit à la donnée. Calcule la géométrie. Applique la matière (couleur, texture).
JavaScript
Absent. Il n'y a rien à orchestrer. Le navigateur gère tout nativement.

4. Démo : l'alphabet en action

Le même élément HTML, le même attribut, des valeurs différentes. Chaque lettre ci-dessous n'est qu'un <div data-matrice-char="X"> :

Forme par défaut

Classe .accent

Classe .inverted

Classe .texture

Le HTML de chaque démo est identique à une lettre près :

<div data-matrice-char="L" role="img" aria-label="Lettre L"></div>

Changer "L" en "O" change la forme. Ajouter class="inverted" change la matière. Les deux dimensions sont indépendantes et orthogonales.

5. Les Règles

Un attribut = une lettre, toujours

La valeur de data-matrice-char est exactement le caractère affiché. Pas d'abréviation, pas de code arbitraire. data-matrice-char="A" affiche un A.

Le rôle ARIA est obligatoire

Un élément vide sans texte est invisible pour les lecteurs d'écran. On ajoute systématiquement role="img" et aria-label="Lettre X" Il serait temps que TOUT le monde le fasse (ptn).

Zéro coordonnée codée en dur

Chaque point du clip-path est une variable CSS. Les valeurs brutes en pixels n'ont pas leur place dans les polygones. Si --offset change, tout se recalcule.

Forme et matière sont séparées

L'attribut contrôle la forme via [data-matrice-char="X"]::after. La matière est contrôlée par une classe modificatrice indépendante (.accent, .inverted, .texture). Ces deux couches ne se mélangent pas.

Aucun JavaScript

La sélection de la forme, le calcul des coordonnées et l'application des variantes sont entièrement réalisés en CSS. Aucun script ne lit ou ne modifie l'attribut.
je vais le répéter et le répéter encore. Aucun JavaScript ne lit ou ne modifie l'attribut data-matrice-char. Le navigateur gère tout nativement. C'est la définition même du pattern data-driven.

Les animations

Si une animation est nécessaire sur le composant (changement de couleur, apparition), elle utilise Les même valeurs que n'importe quelle animation dans le CSS il faut ajouter une règle steps() comme timing function. C'est expliqué et documenté à la fin, dans l'article typographie réactive.

6. Conclusion

L'attribut data-matrice-char est une interface entre le HTML et le CSS. Il dit quoi afficher. CSS décide comment.

Ce pattern data-driven a trois avantages concrets :

Un attribut. Un sélecteur. Une lettre.

7. La Suite

Ce pattern data-driven est la base sur laquelle reposent les expériences suivantes :

Les prochaines explorations possibles à partir de ce système :