🇫🇷 Français · English
Ce repo contient ma solution au défi Testimonials grid section de Frontend Mentor.
🎯 Objectif personnel : maîtriser CSS grid et les classes de pseudos-éléments de Tailwind V4.
Reproduire la section de témoignages en respectant le design et en garantissant :
- un HTML sémantique et accessible ;
- une grille responsive fidèle au layout desktop (choix de 4 colonnes) ;
- un code clair et maintenable avec Tailwind v4.
npm install
npm run dev # serveur local
npm run build # build de production (dossier dist/)
npm run preview # prévisualisation du build- HTML5 sémantique (
main,ul/li,figure/figcaption/imgpour les témoignages) - Tailwind CSS v4 (approche CSS-first avec
@themepour définir des tokens) - Mobile-first workflow
- Polices locales WOFF2 (Barlow Semi Condensed 500/600) +
font-display: swap - Vite (build performant, purge console/debugger, assets fingerprintés)
- Netlify (headers de sécurité & cache via
netlify.toml)
Le composant entier est un groupe de citations attribuées. Le choix sémantique qui me paraît le plus pertinent est donc :
- un landmark
<section>avec un intitulé unique, référencé pararia-labelledby; - une liste
<ul>d’items<li>pour représenter l’ensemble des témoignages ; - chaque item est une figure autonome (
<figure>) qui regroupe :- l’attribution dans
<figcaption>(avatar, nom, statut) ; - la citation dans
<blockquote>(titre/catchphrase + texte détaillé).
- l’attribution dans
Ce schéma exprime explicitement « un ensemble de témoignages, chacun étant une citation avec son auteur », ce qui aide les lecteurs d’écran, la navigation par structure et reste portable (chaque figure peut vivre ailleurs dans le document si besoin).
<section aria-labelledby="testimonials-heading">
<h1 id="testimonials-heading" class="sr-only"></h1>
<ul>
<li>
<figure>
<figcaption>
<img />
<div>
<h2></h2>
<p></p>
</div>
</figcaption>
<blockquote>
<p></p>
<p></p>
</blockquote>
</figure>
</li>
<!-- ... -->
</ul>
</section>Justification sémantique
<blockquote>porte la sémantique de citation ;<figcaption>attribue la citation à son auteur et lie visuellement/structurellement l’avatar + le nom ;<ul>annonce bien « plusieurs témoignages » (navigation par listes) ;aria-labelledbyrelie le titre de section à son contenu.
ℹ️
figuren’est pas réservé aux images : il sert à regrouper un contenu autonome (photo, tableau, code, citation…). Ici, il renforce le lien sémantique citation + attribution sans surcharger la hiérarchie des titres.
Le layout desktop demande 4 colonnes avec des cartes qui s’étendent sur plusieurs colonnes/rangées. La grille repose sur le DOM mobile‑first (1 colonne) et des placements explicites au breakpoint xl.
<ul
class="grid grid-cols-1 gap-8 md:grid-cols-2 md:grid-rows-[auto_auto] xl:auto-rows-fr xl:grid-cols-4"
>
<!-- Daniel (large, 2 colonnes) -->
<li class="xl:col-span-2">...</li>
<!-- Jonathan (en haut, col 3) -->
<li class="xl:col-start-3">...</li>
<!-- Jeanette (bas, col 1) -->
<li class="xl:col-start-1 xl:row-start-2">...</li>
<!-- Patrick (large en bas, 2 colonnes, démarre col 2) -->
<li class="xl:col-span-2 xl:col-start-2 xl:row-start-2">...</li>
<!-- Kira (haute, à droite, 2 rangées) -->
<li class="xl:col-start-4 xl:row-span-2">...</li>
</ul>Points pratiques
xl:auto-rows-frcrée des rangées de hauteur uniforme ; couplé àh-fullsur chaquefigure, les cartes occupent toute la cellule.- On conserve l’ordre DOM logique (utile aux technologies d’assistance) et on n’utilise les
col-start/row-spanqu’au desktop.
- Groupe sémantique de témoignages : vraie
<ul>de<li>(navigation par listes dans les lecteurs d’écran). - Citation attribuée :
<blockquote>+<figcaption>dans une<figure>autonome. - Ordre DOM = ordre visuel (important pour une grille responsive).
- Tailwind v4 JIT → CSS minimal.
- Polices WOFF2 +
preloadciblé +swap. - Vite :
sourcemap: false,drop: ["console","debugger"],assetsInlineLimit: 0pour éviter l’inlining d’assets. - Netlify : cache long sur assets fingerprintés/polices, en-têtes de sécurité pour la version en prod publiée pour la preview.
- Semantic HTML5 markup
- CSS custom properties (via tokens Tailwind v4 dans
@theme) - Mobile-first workflow
- Vite (bundler/build)
- Tailwind CSS v4
- Netlify (hébergement & headers)
- Qu’un
<figure>ne sert pas uniquement aux images : c’est un conteneur sémantique pour un contenu autonome accompagné d’une légende/attribution via<figcaption>. Dans le cas d’un témoignage, regrouper<blockquote>+ attribution dansfigurerenforce la relation logique et améliore l’accessibilité. - La modélisation d’un groupe de témoignages en liste réelle (
<ul>→<li>) facilite la navigation et la compréhension du contenu par les technologies d’assistance. - La mise en page grid avec placements explicites (
col-span,col-start,row-span) est parfaitement lisible avec Tailwind v4 et reste fidèle au mobile‑first.
- Tailwind v4 –
@theme& tokens : https://tailwindcss.com/docs/theme - MDN –
<figure>&<figcaption> - MDN –
<blockquote> - Tailwind v4 – Grid columns / rows / placement
- Website (preview) — https://www.julienborgeon.fr
Merci à Frontend Mentor pour le design du challenge et à la communauté pour les retours.
Un clin d’œil aux ressources MDN & Tailwind pour la clarté de leur doc.
└── 📁testimonials-grid-section
└── 📁.vscode
├── settings.json
└── 📁public
└── 📁assets
├── bg-pattern-quotation.svg
├── favicon-32x32.png
├── image-daniel.jpg
├── image-jeanette.jpg
├── image-jonathan.jpg
├── image-kira.jpg
├── image-patrick.jpg
└── 📁fonts
├── barlow-semi-condensed-v15-latin-500.woff2
├── barlow-semi-condensed-v15-latin-600.woff2
└── 📁src
├── main.css
├── .gitattributes
├── .gitignore
├── .prettierrc
├── index.html
├── netlify.toml
├── package-lock.json
├── package.json
├── README.en.md
├── README.md
└── vite.config.js