CSS Layout Solver
Étape 1 — Diagnostiquer avant de coder
Avant toute solution, collecter :
- Ce que l'utilisateur voit : screenshot ou description du bug (débordement, mauvais alignement, collapse, etc.)
- Ce qu'il attend : maquette ou description du résultat cible
- Contexte DOM : nesting, nombre d'enfants, largeur/hauteur connue ou dynamique
Questions de triage rapide :
- Le problème est-il unidimensionnel (ligne OU colonne) → Flexbox
- Le problème est-il bidimensionnel (lignes ET colonnes) → Grid
- Le composant doit-il réagir à sa propre taille (pas au viewport) → Container Queries
- Y a-t-il un overflow ou un z-index suspect → Diagnostic stacking context
Étape 2 — Critères de choix de technique
| Besoin |
Technique |
Éviter |
| Centrer un élément (1D) |
display:flex; align-items:center; justify-content:center |
margin:auto seul sans contexte flex/grid |
| Grille fixe (colonnes répétées) |
grid-template-columns: repeat(3, 1fr) |
float + clearfix |
| Colonnes de taille variable |
grid-template-columns: auto 1fr auto |
display:table-cell |
| Layout responsive sans media query |
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) |
media queries manuelles |
| Taille fluide entre deux bornes |
clamp(1rem, 2.5vw, 2rem) |
valeurs px fixes |
| Composant réutilisable responsive |
@container |
media query sur viewport |
| Sticky header/footer |
position:sticky; top:0 |
position:fixed (sort du flux) |
Étape 3 — Snippets copiables par cas fréquent
Centrage universel (Flex)
.wrapper {
display: flex;
align-items: center; /* axe transversal */
justify-content: center; /* axe principal */
min-height: 100dvh; /* dvh : tient compte des barres mobiles */
}
Grille responsive sans media query
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
gap: 1.5rem;
}
/* min(100%, 280px) évite l'overflow sur petits écrans */
Holy Grail layout (header / sidebar / main / footer)
.page {
display: grid;
grid-template:
"header header" auto
"nav main " 1fr
"footer footer" auto
/ 220px 1fr;
min-height: 100dvh;
}
header { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
footer { grid-area: footer; }
Sidebar fixe + contenu fluide (Flex)
.layout {
display: flex;
gap: 1rem;
}
.sidebar { flex: 0 0 260px; } /* ne grandit pas, ne rétrécit pas */
.content { flex: 1 1 0; } /* prend tout l'espace restant */
Fluid typography
:root {
--text-base: clamp(1rem, 0.5rem + 1.5vw, 1.25rem);
--text-xl: clamp(1.5rem, 1rem + 2.5vw, 2.5rem);
}
Dark mode via custom properties
:root {
--bg: #ffffff;
--fg: #111111;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #111111;
--fg: #f0f0f0;
}
}
body { background: var(--bg); color: var(--fg); }
Container Query (composant card auto-adaptatif)
.card-wrapper {
container-type: inline-size;
}
@container (min-width: 400px) {
.card { flex-direction: row; }
}
Étape 4 — Déboguer les problèmes classiques
Overflow mystérieux
- Ajouter temporairement
* { outline: 1px solid red; } pour visualiser les boîtes.
- Chercher un enfant avec
width: 100vw, min-width non contraint, ou texte sans overflow-wrap: break-word.
- Sur mobile :
html, body { overflow-x: hidden; } masque le symptôme mais ne corrige pas la cause — trouver l'élément coupable.
z-index qui ne fonctionne pas
- Un
z-index n'a d'effet que si position ≠ static.
- Tout élément avec
transform, opacity < 1, filter, will-change ou isolation:isolate crée un stacking context : les z-index enfants sont confinés à ce contexte.
- Diagnostic : inspecter l'arbre dans DevTools → onglet "Layers".
Margin collapse
- Se produit uniquement entre blocs dans le flux normal (pas en flex/grid).
- Solution : passer le parent en
display:flex ou ajouter padding: 1px / overflow:hidden sur le parent.
Flex enfant qui rétrécit indésirable
.enfant {
flex-shrink: 0; /* interdit le rétrécissement */
/* ou : flex: 0 0 auto; */
}
height:100% sans effet
/* Le parent doit avoir une hauteur explicite ou être en grid/flex avec align-stretch */
.parent { height: 400px; /* ou min-height */ }
.enfant { height: 100%; }
Étape 5 — Responsive : media queries bien ciblées
/* Mobile-first : base = petit écran */
.grid { grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .grid { grid-template-columns: repeat(3, 1fr); } }
Préférer les breakpoints basés sur le contenu (quand le layout casse) aux breakpoints device (320, 768, 1024 sont des conventions, pas des règles).
Étape 6 — Performance rendering
| Propriété à animer |
Coût |
Recommandation |
transform, opacity |
Composite (GPU) |
Toujours préférer |
background-color, color, border |
Paint |
Acceptable ponctuellement |
width, height, margin, top |
Layout (reflow) |
Éviter en animation |
/* Animation performante */
.card:hover {
transform: translateY(-4px);
transition: transform 200ms ease-out;
}
/* will-change : seulement si l'animation est fréquente et mesurée */
.animated { will-change: transform; }
Anti-patterns et pièges (2026)
!important en cascade : symptôme d'un problème de spécificité. Utiliser @layer pour contrôler la priorité proprement.
position:fixed pour un sticky : sort du flux, pose des problèmes dans les conteneurs transform. Utiliser position:sticky.
vh sur mobile : les barres de navigation du navigateur font varier 100vh. Utiliser 100dvh (dynamic viewport height, supporté depuis 2023).
float pour le layout : obsolète. Réservé aux textes qui enveloppent une image (float:left sur l'image).
- Trop de media queries manuelles :
auto-fit + minmax + clamp couvrent 80% des besoins sans breakpoints.
- Nesting Flexbox sans raison : un
display:grid à la racine suffit souvent pour éviter plusieurs couches Flexbox.
@layer oublié : en 2026, tout projet sérieux utilise @layer (reset, base, components, utilities) pour éviter les guerres de spécificité.
@layer reset, base, components, utilities;
@layer components {
.btn { padding: 0.5rem 1rem; }
}
@layer utilities {
.mt-4 { margin-top: 1rem; }
}
Checklist de livraison
Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.
1---2name: dev-css-layout-solver3description: Résout les problèmes de layout CSS avec Flexbox, Grid et techniques modernes. Se déclenche avec "CSS", "layout", "Flexbox", "Grid", "centrer", "aligner", "responsive", "mon layout est cassé", "overflow", "z-index". Also triggers on "CSS layout issue", "flexbox centering", "grid layout", "why is my div misaligned".4---56# CSS Layout Solver78## Étape 1 — Diagnostiquer avant de coder910Avant toute solution, collecter :11- **Ce que l'utilisateur voit** : screenshot ou description du bug (débordement, mauvais alignement, collapse, etc.)12- **Ce qu'il attend** : maquette ou description du résultat cible13- **Contexte DOM** : nesting, nombre d'enfants, largeur/hauteur connue ou dynamique1415Questions de triage rapide :161. Le problème est-il unidimensionnel (ligne OU colonne) → Flexbox172. Le problème est-il bidimensionnel (lignes ET colonnes) → Grid183. Le composant doit-il réagir à sa propre taille (pas au viewport) → Container Queries194. Y a-t-il un overflow ou un z-index suspect → Diagnostic stacking context2021---2223## Étape 2 — Critères de choix de technique2425| Besoin | Technique | Éviter |26|---|---|---|27| Centrer un élément (1D) | `display:flex; align-items:center; justify-content:center` | `margin:auto` seul sans contexte flex/grid |28| Grille fixe (colonnes répétées) | `grid-template-columns: repeat(3, 1fr)` | `float` + clearfix |29| Colonnes de taille variable | `grid-template-columns: auto 1fr auto` | `display:table-cell` |30| Layout responsive sans media query | `grid-template-columns: repeat(auto-fit, minmax(240px, 1fr))` | media queries manuelles |31| Taille fluide entre deux bornes | `clamp(1rem, 2.5vw, 2rem)` | valeurs px fixes |32| Composant réutilisable responsive | `@container` | media query sur viewport |33| Sticky header/footer | `position:sticky; top:0` | `position:fixed` (sort du flux) |3435---3637## Étape 3 — Snippets copiables par cas fréquent3839### Centrage universel (Flex)40```css41.wrapper {42 display: flex;43 align-items: center; /* axe transversal */44 justify-content: center; /* axe principal */45 min-height: 100dvh; /* dvh : tient compte des barres mobiles */46}47```4849### Grille responsive sans media query50```css51.grid {52 display: grid;53 grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));54 gap: 1.5rem;55}56/* min(100%, 280px) évite l'overflow sur petits écrans */57```5859### Holy Grail layout (header / sidebar / main / footer)60```css61.page {62 display: grid;63 grid-template:64 "header header" auto65 "nav main " 1fr66 "footer footer" auto67 / 220px 1fr;68 min-height: 100dvh;69}70header { grid-area: header; }71nav { grid-area: nav; }72main { grid-area: main; }73footer { grid-area: footer; }74```7576### Sidebar fixe + contenu fluide (Flex)77```css78.layout {79 display: flex;80 gap: 1rem;81}82.sidebar { flex: 0 0 260px; } /* ne grandit pas, ne rétrécit pas */83.content { flex: 1 1 0; } /* prend tout l'espace restant */84```8586### Fluid typography87```css88:root {89 --text-base: clamp(1rem, 0.5rem + 1.5vw, 1.25rem);90 --text-xl: clamp(1.5rem, 1rem + 2.5vw, 2.5rem);91}92```9394### Dark mode via custom properties95```css96:root {97 --bg: #ffffff;98 --fg: #111111;99}100@media (prefers-color-scheme: dark) {101 :root {102 --bg: #111111;103 --fg: #f0f0f0;104 }105}106body { background: var(--bg); color: var(--fg); }107```108109### Container Query (composant card auto-adaptatif)110```css111.card-wrapper {112 container-type: inline-size;113}114@container (min-width: 400px) {115 .card { flex-direction: row; }116}117```118119---120121## Étape 4 — Déboguer les problèmes classiques122123### Overflow mystérieux1241. Ajouter temporairement `* { outline: 1px solid red; }` pour visualiser les boîtes.1252. Chercher un enfant avec `width: 100vw`, `min-width` non contraint, ou texte sans `overflow-wrap: break-word`.1263. Sur mobile : `html, body { overflow-x: hidden; }` masque le symptôme mais ne corrige pas la cause — trouver l'élément coupable.127128### z-index qui ne fonctionne pas129- Un `z-index` n'a d'effet que si `position` ≠ `static`.130- Tout élément avec `transform`, `opacity < 1`, `filter`, `will-change` ou `isolation:isolate` **crée un stacking context** : les z-index enfants sont confinés à ce contexte.131- Diagnostic : inspecter l'arbre dans DevTools → onglet "Layers".132133### Margin collapse134- Se produit uniquement entre blocs dans le flux normal (pas en flex/grid).135- Solution : passer le parent en `display:flex` ou ajouter `padding: 1px` / `overflow:hidden` sur le parent.136137### Flex enfant qui rétrécit indésirable138```css139.enfant {140 flex-shrink: 0; /* interdit le rétrécissement */141 /* ou : flex: 0 0 auto; */142}143```144145### height:100% sans effet146```css147/* Le parent doit avoir une hauteur explicite ou être en grid/flex avec align-stretch */148.parent { height: 400px; /* ou min-height */ }149.enfant { height: 100%; }150```151152---153154## Étape 5 — Responsive : media queries bien ciblées155156```css157/* Mobile-first : base = petit écran */158.grid { grid-template-columns: 1fr; }159160@media (min-width: 640px) { .grid { grid-template-columns: repeat(2, 1fr); } }161@media (min-width: 1024px) { .grid { grid-template-columns: repeat(3, 1fr); } }162```163164Préférer les **breakpoints basés sur le contenu** (quand le layout casse) aux breakpoints device (320, 768, 1024 sont des conventions, pas des règles).165166---167168## Étape 6 — Performance rendering169170| Propriété à animer | Coût | Recommandation |171|---|---|---|172| `transform`, `opacity` | Composite (GPU) | Toujours préférer |173| `background-color`, `color`, `border` | Paint | Acceptable ponctuellement |174| `width`, `height`, `margin`, `top` | Layout (reflow) | Éviter en animation |175176```css177/* Animation performante */178.card:hover {179 transform: translateY(-4px);180 transition: transform 200ms ease-out;181}182/* will-change : seulement si l'animation est fréquente et mesurée */183.animated { will-change: transform; }184```185186---187188## Anti-patterns et pièges (2026)189190- **`!important` en cascade** : symptôme d'un problème de spécificité. Utiliser `@layer` pour contrôler la priorité proprement.191- **`position:fixed` pour un sticky** : sort du flux, pose des problèmes dans les conteneurs `transform`. Utiliser `position:sticky`.192- **`vh` sur mobile** : les barres de navigation du navigateur font varier `100vh`. Utiliser `100dvh` (dynamic viewport height, supporté depuis 2023).193- **`float` pour le layout** : obsolète. Réservé aux textes qui enveloppent une image (`float:left` sur l'image).194- **Trop de media queries manuelles** : `auto-fit` + `minmax` + `clamp` couvrent 80% des besoins sans breakpoints.195- **Nesting Flexbox sans raison** : un `display:grid` à la racine suffit souvent pour éviter plusieurs couches Flexbox.196- **`@layer` oublié** : en 2026, tout projet sérieux utilise `@layer` (reset, base, components, utilities) pour éviter les guerres de spécificité.197198```css199@layer reset, base, components, utilities;200@layer components {201 .btn { padding: 0.5rem 1rem; }202}203@layer utilities {204 .mt-4 { margin-top: 1rem; }205}206```207208---209210## Checklist de livraison211212- [ ] Code testé dans Chrome DevTools (responsive mode)213- [ ] Compatibilité vérifiée sur Can I Use si propriété récente214- [ ] Aucune valeur magique px sans commentaire justificatif215- [ ] Variables CSS pour les valeurs répétées (couleurs, espacements)216- [ ] Fallback indiqué si la propriété n'est pas universelle (ex. `dvh` → fallback `vh`)217218219## Communication Rules — MANDATORY220221- Ultra-concise. No filler, no preamble, no pleasantries.222- Never say "happy to help", "sure!", "great question", "let me", or similar.223- Tool first, talk second. Act before explaining.224- Result first. Lead with outcome, not process.225- Stop when done. No summary, no recap, no trailing commentary.226- No politeness wrappers. Direct and blunt.227- Minimum words. If one word works, do not use ten.228- No unsolicited explanations.229- No emoji unless asked.