Préparation d'entretien 100% Gratuit angularforall.com

Entretien CSS Senior — Architecture et Performance

Css Senior Quiz-Css-Senior Bem Itcss Oocss Container-Queries Css-Layer Cascade-Layers Css-Houdini Performance-Css Accessibilite Entretien-Css-Senior Qcm-Css-Avance
Sénior 🔀 Mixte 20 questions ⏱ 15 min
📝

Entretien CSS Senior — Architecture et Performance

20 questions CSS niveau senior : BEM, ITCSS, CSS Houdini, containment, @layer, container queries, performances, accessibilité. Pour réussir un entretien développeur CSS Senior.

20 questions ⏱ ~15 min Niveau Sénior

Partager

Banque de révision : les 55 questions corrigées

Voici l'intégralité des 55 questions de « Entretien CSS Senior — Architecture et Performance », chacune avec sa bonne réponse et son explication. Le quiz interactif ci-dessus en tire une sélection aléatoire à chaque tentative — utilisez cette liste complète pour réviser.

  • Block Element Modifier — une convention de nommage CSS qui améliore la lisibilité, la réutilisabilité et évite les conflits de noms (bonne réponse)
  • Browser Engine Model — un modèle pour optimiser le rendu CSS dans différents navigateurs
  • Bootstrap Enhanced Module — une surcouche de Bootstrap pour les projets enterprise
  • Basic Element Markup — une approche qui simplifie les sélecteurs CSS en les limitant à un seul niveau
Explication : BEM (Block Element Modifier) est une méthodologie de nommage : .block, .block__element, .block--modifier. Avantages : sélecteurs plats (faible spécificité), auto-documentés, modulaires, évite les collisions de noms. Exemple : .card, .card__title, .card--featured.
Explique comment BEM résout le problème de spécificité en évitant les sélecteurs imbriqués. Mentionne les alternatives : OOCSS, SMACSS, Atomic CSS, et pourquoi on choisit l'un plutôt que l'autre.

  • La propriété contain qui isole les effets de rendu d'un élément pour permettre au navigateur d'optimiser les recalculs (bonne réponse)
  • La propriété overflow qui contient le contenu dans ses dimensions
  • Un module CSS pour créer des widgets autonomes sans styles extérieurs
  • La technique de chargement différé des feuilles de style
Explication : La propriété contain indique au navigateur qu'un sous-arbre DOM est indépendant du reste. Valeurs : layout (layout interne isolé), style (styles compteurs isolés), paint (pas de peinture hors limites), size (taille indépendante du contenu). contain: content = layout + style + paint. Réduit le scope des recalculs.
Cas d'usage concret : un widget de commentaires avec contain: content — si le DOM interne change, le navigateur ne recalcule que ce sous-arbre. Critique pour les performances des listes longues.

  • :where() a une spécificité plus élevée que :is()
  • :where() a toujours une spécificité de 0 ; :is() hérite de la spécificité la plus haute de ses arguments (bonne réponse)
  • Elles ont la même spécificité — exactement 0,0,1,0
  • :where() double la spécificité de ses arguments
Explication : C'est une différence fondamentale : :where() a toujours une spécificité de 0, quelle que soit la complexité de ses arguments. :is() prend la spécificité de l'argument le plus spécifique. Ex : :is(#id, .class) a une spécificité d'ID. :where(#id, .class) a une spécificité de 0.
:where() est idéal pour les resets CSS — styles de base facilement surchargeables sans utiliser !important. :is() est utile pour éviter la répétition de sélecteurs complexes sans perdre la spécificité.

  • Augmenter la durée de l'animation et utiliser linear comme timing function
  • Animer uniquement transform et opacity — ces propriétés sont traitées sur le thread compositing du GPU (bonne réponse)
  • Utiliser !important sur les propriétés animées pour garantir leur priorité
  • Définir animation-iteration-count: infinite pour rendre l'animation fluide
Explication : Les propriétés transform et opacity peuvent être animées sur le thread compositor (GPU), séparément du thread principal JS. Les autres propriétés comme width, height, top, left déclenchent layout + paint sur le thread principal = jank. La règle d'or : animate transform and opacity only.
Mentionne le pipeline de rendu : JavaScript → Style → Layout → Paint → Composite. Animer transform/opacity saute les étapes Layout et Paint. Outils : Chrome DevTools → Performance pour identifier les frame drops.

  • Définit la taille CSS intrinsèque de l'élément pour éviter le layout shift quand content-visibility saute le rendu (bonne réponse)
  • Cache le contenu en dessous d'une certaine taille
  • Contrôle la visibilité du contenu lors du chargement automatique
  • Optimise la taille du cache pour les ressources CSS
Explication : content-visibility: auto saute le rendu des éléments hors écran (gains de performance importants). Mais quand l'élément n'est pas rendu, sa taille est 0 — ce qui cause du layout shift (CLS). contain-intrinsic-size donne au navigateur une estimation de la taille pour maintenir le scroll cohérent.

  • Un framework CSS qui génère automatiquement des styles optimisés
  • Un ensemble d'APIs bas niveau qui exposent le moteur CSS du navigateur, permettant aux développeurs d'étendre CSS nativement (bonne réponse)
  • Une bibliothèque d'animations CSS avancées basée sur WebGL
  • Un système de variables CSS compatible avec Sass et Less
Explication : CSS Houdini expose le pipeline de rendu CSS aux développeurs. APIs clés : Paint API (dessiner dans une image CSS via Canvas), Layout API (créer des algoritmes de mise en page custom), Animation Worklet (animations sur le compositor), Typed OM (CSS Object Model typé, plus performant). Permet de créer des propriétés CSS custom avec logique.
La Paint API est la plus disponible aujourd'hui — elle permet de dessiner des backgrounds complexes (ex: triangles, patterns) qui s'adapten à la taille de l'élément, accessibles via background: paint(mon-worklet).

  • Des propriétés CSS calculées automatiquement par le navigateur selon la logique de mise en page
  • Des propriétés qui utilisent des directions logiques (start/end/inline/block) au lieu de directions physiques (left/right/top/bottom) pour le support RTL (bonne réponse)
  • Des propriétés CSS conditionnelles appliquées selon des règles logiques JavaScript
  • Des propriétés CSS héritées automatiquement de manière logique dans l'arbre DOM
Explication : Les CSS logical properties remplacent les directions physiques par des directions logiques liées à la direction d'écriture. margin-inline-start remplace margin-left en LTR et margin-right en RTL automatiquement. Autres exemples : block-size (= height), inline-size (= width), padding-block-start (= padding-top en LTR).
Essentielles pour l'internationalisation (i18n). Si tu builds pour des langues RTL (arabe, hébreu), utiliser les logical properties évite d'écrire des sélecteurs [dir="rtl"] séparément.

  • En définissant les variables dans un fichier JSON importé par JavaScript, puis injecté dans le style
  • En déclarant toutes les variables sur :root avec une nomenclature hiérarchique (--color-primary-500), et en créant des tokens sémantiques qui référencent les tokens primitifs (bonne réponse)
  • En utilisant les custom properties uniquement pour les couleurs, et Sass pour les espacements et typographie
  • En définissant une classe .design-tokens sur body et en déclarant toutes les variables à l'intérieur
Explication : Un système de tokens robuste utilise deux niveaux : tokens primitifs (--color-blue-500: #3b82f6) et tokens sémantiques (--color-action: var(--color-blue-500)). Les composants n'utilisent que les tokens sémantiques. Pour le dark mode, on redéfinit uniquement les tokens sémantiques dans @media (prefers-color-scheme: dark) ou via une classe.
Structure recommandée : categories (color, spacing, typography, shadow, border), puis tier (primitive → semantic → component). Les tokens peuvent être exportés depuis Figma via des plugins comme Tokens Studio.

  • transform: translate3d(0, 0, 0) ou translateZ(0) (bonne réponse)
  • animation-mode: gpu
  • render: hardware-accelerated
  • perspective: 1px
Explication : transform: translateZ(0) (ou translate3d(0,0,0)) est le "hack GPU" historique — il force la promotion de l'élément sur le thread compositor en créant un layer. Aujourd'hui, will-change: transform est la méthode officielle. Le hack est encore utilisé pour compatibilité mais crée un layer permanent (consomme de la mémoire GPU).

  • Le chemin de fichier CSS qui doit être chargé en priorité par le navigateur
  • La séquence de calculs que le navigateur effectue pour convertir HTML+CSS+JS en pixels : parsing → CSSOM → render tree → layout → paint (bonne réponse)
  • L'ordre dans lequel les propriétés CSS sont appliquées sur un élément
  • Le mode de rendu rapide activé par preload CSS
Explication : Le Critical Rendering Path : 1) Parser HTML → DOM, 2) Parser CSS → CSSOM, 3) Combiner DOM + CSSOM → Render Tree, 4) Layout (calcul des tailles/positions), 5) Paint (pixels), 6) Composite. Le CSS est render-blocking : le navigateur ne peut pas afficher tant que tout le CSS n'est pas parsé. D'où l'importance du Critical CSS inliné et du media sur les CSS non-critiques.
Optimisations : inliner le Critical CSS, charger le CSS non-critique avec <link rel="preload" as="style"> + onload, utiliser media="print" pour différer puis changer en all.

  • Crée des calques de z-index pour organiser les éléments positionnés
  • Définit des couches de cascade explicites avec un ordre de priorité contrôlable (bonne réponse)
  • Charge les styles en couches pour améliorer les performances
  • Isole les styles d'un composant web en créant un Shadow DOM CSS
Explication : @layer (Cascade Layers) permet de définir des couches de cascade avec une priorité explicite. Exemple : @layer reset, base, components, utilities;. Les styles dans utilities l'emportent sur components, peu importe la spécificité. Révolutionne la gestion des overrides — plus besoin de !important pour les utilitaires.
Tailwind CSS v4 utilise @layer. Les styles hors couche ont la priorité la plus haute par défaut. Un style dans une couche déclarée en dernier bat un style dans une couche déclarée en premier, quelle que soit la spécificité.

  • Dupliquer toutes les règles CSS avec le sélecteur body.dark-mode en préfixe
  • Utiliser filter: invert(1) sur le body pour inverser tous les couleurs
  • Définir des tokens sémantiques en custom properties sur :root, les redéfinir dans @media (prefers-color-scheme: dark) ou .dark-theme, et appliquer uniquement les tokens dans les composants (bonne réponse)
  • Utiliser JavaScript pour changer toutes les propriétés CSS inline lors du toggle
Explication : La meilleure approche : 1) Déclarer les tokens sur :root (valeurs light). 2) Redéfinir les tokens dans @media (prefers-color-scheme: dark) ET dans une classe .dark-theme (pour toggle manuel). 3) Tous les composants utilisent uniquement les tokens. Avantage : changer le thème = modifier ~20 variables, pas des centaines de règles.
Pour la persistance du toggle manuel, sauvegarde la préférence en localStorage et applique la classe au <html> avant le render (pas après, pour éviter le flash). Le sélecteur :root sur <html> permet d'éviter des conflits de spécificité.

  • Crée une grille imbriquée indépendante dans un élément de grille
  • Permet à un élément de grille enfant d'utiliser les tracks de la grille parent pour aligner ses propres enfants (bonne réponse)
  • Divise automatiquement les cellules de grille en sous-cellules
  • Hérite les colonnes de la grille parente mais crée de nouvelles rangées
Explication : subgrid comme valeur de grid-template-columns ou grid-template-rows permet à un élément de grille d'adopter les tracks définis par la grille parent. Ses enfants peuvent alors s'aligner sur la grille grand-parent. Résout élégamment le problème d'alignement dans les cartes avec des éléments à des hauteurs différentes.
Cas d'usage classique : une grille de cartes dont les titres, corps et boutons doivent s'aligner entre les cartes. Avant subgrid, il fallait des hacks JS ou des hauteurs fixes.

  • L'accessibilité CSS concerne uniquement les contrastes de couleurs vérifiés par des outils automatisés
  • Des techniques CSS qui assurent la lisibilité, la navigation clavier, le support des technologies d'assistance et le respect des préférences utilisateur (bonne réponse)
  • L'ajout de aria- attributes via CSS pour les lecteurs d'écran
  • L'optimisation des fichiers CSS pour les connexions lentes
Explication : L'accessibilité CSS inclut : :focus-visible (focus ring visible pour clavier, pas pour souris), @media (prefers-reduced-motion) (désactive animations pour les utilisateurs sensibles), contraste de couleurs (WCAG AA = 4.5:1), outline: none dangereux sans alternative, .sr-only pour masquer visuellement mais garder pour lecteurs d'écran, taille de texte minimum 16px.
Mentionne :focus-visible vs :focus — utilise :focus-visible pour afficher l'outline uniquement lors de la navigation clavier, préservant l'UX souris tout en étant accessible.

  • Elles sont identiques — perspective-origin est le nom CSS3 de transform-origin
  • transform-origin définit le point de pivot des transformations 2D/3D ; perspective-origin définit le point de fuite de la perspective 3D (bonne réponse)
  • transform-origin s'applique aux enfants, perspective-origin au conteneur
  • perspective-origin contrôle la distance de la caméra, transform-origin l'angle
Explication : transform-origin définit le point de pivot des transformations (rotations, échelles). Défaut : center center. perspective-origin sur le conteneur perspective définit le point de fuite de la scène 3D — d'où "regarde" l'observateur. Ces deux propriétés combinent pour créer des effets 3D convaincants.

  • En minimisant uniquement la taille des fichiers CSS avec gzip
  • En analysant : sélecteurs coûteux, propriétés déclenchant reflow/repaint, layers excessifs, CSS inutilisé, blocking render (bonne réponse)
  • En utilisant exclusivement des classes utilitaires Tailwind pour éviter tout CSS custom
  • En limitant le CSS à 3 fichiers maximum par page
Explication : Audit CSS complet : 1) Coverage (Chrome DevTools) → identifier le CSS inutilisé. 2) Performance panel → repérer les reflows coûteux. 3) Layers panel → détecter les layers GPU non justifiés. 4) Selector performance → éviter les sélecteurs universels (*) en combinaison avec descendants. 5) render-blocking CSS → inliner le critical, différer le reste.
Métriques clés : First Contentful Paint (FCP), Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS). Le CSS impact surtout FCP et CLS. PurgeCSS ou Tailwind's purge supprime le CSS inutilisé en production.

  • Réduit la consommation CPU en simplifiant les règles CSS
  • Cible les utilisateurs qui ont activé l'option "réduire les animations" dans leur OS (bonne réponse)
  • Désactive toutes les animations CSS sur les appareils à faible batterie
  • Applique des animations plus légères sur les connexions lentes
Explication : prefers-reduced-motion: reduce cible les utilisateurs ayant activé la préférence de réduction de mouvement dans leur OS (ex: "Réduire le mouvement" sur macOS/iOS). Ces utilisateurs peuvent avoir des problèmes vestibulaires (vertiges), épilepsie, etc. Bonne pratique : désactiver ou ralentir les animations dans ce contexte.
Pattern recommandé : définir les animations par défaut, puis les désactiver dans la media query. Ex : @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }.

  • Object Oriented CSS — sépare la structure (layout) de l'apparence (skin) et encourage des classes réutilisables comme des objets (bonne réponse)
  • Optimized Object CSS — une variante de BEM avec une spécificité réduite
  • Output Object CSS — un générateur CSS automatique pour les composants orientés objet
  • OOCSS et BEM sont identiques, seule la notation change
Explication : OOCSS (Nicole Sullivan) pose deux principes : 1) Séparer la structure (layout, dimensions) de l'apparence (couleurs, bordures). 2) Séparer le contenant du contenu (éviter les sélecteurs contextuels comme .sidebar .btn). OOCSS favorise des classes utilitaires réutilisables. BEM est plus prescriptif sur le nommage et l'organisation en blocks.
Tailwind CSS est philosophiquement proche d'OOCSS (classes utilitaires composables). BEM est plus adapté aux équipes qui préfèrent des composants encapsulés avec une nomenclature explicite.

  • Vérifie si un fichier CSS est correctement supporté par le navigateur
  • Applique des styles conditionnellement selon le support d'une propriété CSS par le navigateur (bonne réponse)
  • Déclare les navigateurs supportés par la feuille de style
  • Charge un fichier CSS alternatif si le principal ne se charge pas
Explication : @supports (Feature Queries) permet de tester si le navigateur supporte une propriété CSS : @supports (display: grid) { .container { display: grid; } }. On peut aussi nier : @supports not (display: grid) { } ou combiner : @supports (display: grid) and (gap: 20px) { }. La base du Progressive Enhancement en CSS.

  • Utiliser uniquement des polices système (system-ui) — elles ne causent jamais de CLS
  • Combiner font-display: swap avec size-adjust, ascent-override, descent-override pour aligner la police de remplacement sur la police finale (bonne réponse)
  • Charger toutes les polices en précharge synchrone dans le head pour garantir leur disponibilité
  • Définir une hauteur fixe sur tous les textes pour éviter les sauts lors du chargement de la police
Explication : Le CLS lié aux polices vient du fait que la police de remplacement a des métriques différentes. Solution moderne : font-display: swap + descripteurs size-adjust, ascent-override, descent-override dans @font-face pour ajuster métriquement la police de remplacement. Résultat : quasi zéro CLS lors du swap.
L'outil "Fontaine" ou "next/font" génère automatiquement ces ajustements. C'est devenu une pratique Core Web Vitals critique pour les sites à fort trafic.

  • Définit l'élément à exactement 16px de large et 9px de haut
  • Force l'élément à maintenir un rapport largeur/hauteur de 16:9, en calculant automatiquement la hauteur selon la largeur (bonne réponse)
  • Scale l'élément à 16% de largeur et 9% de hauteur
  • Crée un viewport de 1920×1080px à l'intérieur de l'élément
Explication : aspect-ratio maintient un rapport largeur/hauteur défini. Si la largeur est 800px, la hauteur sera automatiquement calculée à 450px (800 × 9/16). Remplace avantageusement le vieux hack padding-top. Fonctionne aussi avec aspect-ratio: 1 pour un carré. Très utile pour les placeholders d'images et les vidéos responsives.

  • Le contexte dans lequel le CSS en blocs est formaté — un espace de mise en page isolé qui contient ses flottants et prévient certains comportements (bonne réponse)
  • Le mode de formatage par défaut de tous les éléments block
  • Un mode CSS spécial activé par display: block-context
  • La région de la page où le CSS en mode blocs est appliqué en priorité
Explication : Un BFC est un mini-layout indépendant. Il se crée avec : float (non-none), position: absolute/fixed, display: inline-block/flex/grid/table/flow-root, overflow (non-visible), contain: layout/paint. Effets : contient ses flottants (clearfix), empêche le margin collapse avec ses enfants, évite le chevauchement avec des flottants sibling.
La méthode moderne pour créer un BFC sans effets secondaires est display: flow-root. Comprendre les BFC est essentiel pour débugguer les problèmes de margin collapse et de clearfix.

  • linear
  • ease (bonne réponse)
  • ease-in
  • step-start
Explication : La valeur par défaut est ease — l'animation démarre lentement, accélère, puis ralentit en fin. Les valeurs communes : linear (vitesse constante), ease-in (accélère), ease-out (décélère — naturel pour les sorties), ease-in-out, cubic-bezier() (courbe personnalisée). Pour les animations d'UI, ease-out est souvent le plus naturel.

  • En utilisant display: masonry — une valeur CSS standard
  • En utilisant CSS columns (multi-column layout) — méthode disponible aujourd'hui, avec quelques limitations (bonne réponse)
  • En utilisant Flexbox avec flex-direction: column et flex-wrap: wrap — parfaitement identique au masonry
  • Il est impossible de faire du masonry en CSS pur — JavaScript est obligatoire
Explication : La méthode actuelle : columns: 3; column-gap: 20px (CSS Multi-column). Les éléments s'empilent en colonnes verticales. Limitation : l'ordre de lecture est de haut en bas, pas de gauche à droite. La spec CSS Grid "masonry" (grid-template-rows: masonry) est en discussion mais pas encore standard. Pour un vrai masonry horizontal, JavaScript reste souvent nécessaire.
Mentionne le support expérimental de grid-template-rows: masonry dans Firefox (flag). C'est une feature très attendue et un excellent sujet de conversation sur les CSS features modernes.

  • Isole les styles d'un élément pour éviter tout héritage
  • Force la création d'un nouveau stacking context sans changer d'autres propriétés (bonne réponse)
  • Isole l'élément dans un Shadow DOM léger
  • Empêche les media queries de s'appliquer à l'élément
Explication : isolation: isolate crée un nouveau stacking context SANS modifier d'autres propriétés visuelles (contrairement à opacity < 1, transform, etc.). Utile pour contrôler les z-index : un enfant avec mix-blend-mode ne blende qu'avec les éléments dans son stacking context. Aussi utile pour encapsuler les z-index d'un composant.

  • Les conflits de spécificité entre les styles inline et les stylesheets, résolus uniquement par !important
  • L'escalade progressive de la spécificité des sélecteurs pour surcharger les styles, rendant le CSS difficile à maintenir (bonne réponse)
  • La guerre des standards entre les navigateurs concernant l'implémentation de la cascade
  • Un problème de performance causé par trop de sélecteurs complexes dans un fichier CSS
Explication : La "Specificity Wars" : pour surcharger un style, on écrit un sélecteur encore plus spécifique, qui requiert encore plus de spécificité pour être surchargé, créant une escalade. Solutions : 1) BEM (sélecteurs plats, spécificité faible), 2) @layer (cascade layers contrôlée), 3) Utilitaires à haute spécificité via @layer utilities, 4) Éviter les IDs comme sélecteurs CSS.
La règle d'or : maintenir la spécificité aussi basse que possible. Classes uniquement (0,0,1,0), pas d'IDs (0,1,0,0) dans les feuilles de style. !important est le symptôme, pas la solution.

  • Multiplie l'opacité de l'élément par celle de son parent
  • Combine les couleurs de l'élément avec celles en dessous en les multipliant (les couleurs claires deviennent transparentes, les sombres s'intensifient) (bonne réponse)
  • Crée un effet de doublement visuel de l'élément
  • Applique un filtre de multiplication CSS sur les dimensions de l'élément
Explication : mix-blend-mode contrôle comment les couleurs d'un élément se fondent avec ceux en dessous. multiply multiplie les valeurs RGB (0=noir, 1=transparent) — similaire à la transparence en impression. Autres valeurs utiles : screen (inverse de multiply), overlay, darken, lighten. Créer des effets de double exposition ou de texte découpé.

  • Le Shadow DOM hérite tous les styles du document parent — aucune gestion spéciale nécessaire
  • Utiliser ::part() et ::slotted() pour styliser depuis l'extérieur, et des custom properties CSS qui "percent" à travers le Shadow DOM (bonne réponse)
  • Injecter les styles avec JavaScript dans le shadowRoot.innerHTML
  • Le Shadow DOM ne supporte pas CSS — il faut utiliser uniquement du style inline
Explication : Le Shadow DOM isole les styles. Pour styler depuis l'extérieur : 1) ::part(nom) cible des parties exposées explicitement (via l'attribut part="nom"). 2) ::slotted() cible les éléments projetés dans les slots. 3) Les CSS custom properties traversent le Shadow DOM — excellent pour le theming. 4) Adoptable Stylesheets (API moderne).
Les custom properties CSS sont le mécanisme de theming recommandé pour les Web Components. Elles traversent la frontière Shadow DOM, permettant un theming externe contrôlé.

  • La colonne prend exactement la largeur restante après les autres colonnes
  • La colonne s'ajuste à la taille de son contenu (ni plus, ni moins) (bonne réponse)
  • La colonne est créée automatiquement par l'algorithme de placement
  • La colonne hérite de la largeur du parent divisée par 3
Explication : La valeur auto dans une grille signifie que la colonne prend la taille de son contenu (similaire à min-content ou max-content selon le contexte). Contrairement à 1fr qui prend une fraction de l'espace disponible, auto est contraint par son contenu. C'est utile pour les colonnes d'icônes ou de labels courts.

  • Inverted Triangle CSS — organise le CSS du plus général au plus spécifique pour gérer la spécificité et la cascade (bonne réponse)
  • Integrated TypeScript CSS — une architecture combinant TypeScript et CSS Modules
  • Iterative CSS — une méthode pour construire des styles incrémentalement couche par couche
  • Internal Component CSS — une architecture pour les design systems modulaires
Explication : ITCSS (Harry Roberts) organise les fichiers CSS en couches de la spécificité la plus faible à la plus haute : Settings (variables) → Tools (mixins) → Generic (resets) → Elements (HTML tags) → Objects (patterns layout, OOCSS) → Components (UI spécifiques) → Utilities (overrides). Chaque couche ne surcharge que les couches précédentes. Idéal pour les grandes bases de code.
ITCSS se marie bien avec BEM pour les Components et des classes utilitaires pour les Utilities. C'est l'architecture derrière CSS Inuit (framework de Harry Roberts). Très pertinent pour les projets d'équipe de plus de 5 développeurs.

  • Retourne la valeur minimale parmi les arguments (bonne réponse)
  • Définit la taille minimale de l'élément
  • Calcule la valeur minimale d'une propriété sur la base d'une condition
  • Arrête la croissance d'un élément en définissant min-width et min-height
Explication : min(a, b) retourne la valeur la plus petite parmi ses arguments. Ex : width: min(500px, 100%) — sur desktop (>500px), la largeur sera 500px ; sur mobile (

  • En définissant des variables globales sur :root et en les appliquant sur tous les éléments directement
  • En définissant des "API CSS" via custom properties avec des valeurs par défaut, que les consommateurs peuvent surcharger localement (bonne réponse)
  • En utilisant uniquement des classes CSS pour les thèmes et des variables JavaScript pour les valeurs dynamiques
  • En créant un fichier CSS par thème et en les chargeant alternativement
Explication : Le pattern "CSS Custom Properties as API" : un composant définit ses propres variables avec des valeurs par défaut : .btn { --btn-bg: blue; --btn-color: white; background: var(--btn-bg); color: var(--btn-color); }. Pour thématiser : .btn-red { --btn-bg: red; } ou depuis le parent : .card .btn { --btn-bg: var(--card-accent); }.
C'est la technique utilisée par des design systems comme Material Design Web Components. Les variables CSS peuvent aussi être modifiées via JavaScript : element.style.setProperty('--btn-bg', '#f00').

  • Fixe le scroll à des positions précises lors du défilement dans un conteneur (bonne réponse)
  • Empêche le défilement par étapes (snapping) dans les conteneurs overflow
  • Définit la vitesse du scroll dans un conteneur
  • Synchronise le scroll entre plusieurs conteneurs
Explication : scroll-snap-type sur le conteneur et scroll-snap-align sur les enfants créent un comportement de "snap" au défilement — l'utilisateur scrolle et le viewport s'arrête sur des positions définies. Idéal pour les carousels et sliders en CSS pur, sans JavaScript. Valeur exemple : scroll-snap-type: x mandatory.

  • Un équivalent CSS des modules JavaScript pour importer des fichiers CSS
  • Une règle pour définir un scope CSS limité à un sous-arbre DOM, sans avoir besoin de classes parent dans chaque sélecteur (bonne réponse)
  • Un moyen de scope les variables CSS custom à un seul composant
  • Un remplaçant de Shadow DOM pour encapsuler les styles
Explication : @scope (.card) to (.card__footer) { .title { ... } } limite l'application des styles à un sous-arbre DOM précis (de .card jusqu'à .card__footer). Évite d'avoir à préfixer chaque sélecteur avec le nom du composant. Résout le problème des styles qui "fuient" entre composants imbriqués — plus besoin de BEM ou de nommage explicite dans certains cas.
C'est une feature CSS récente (2024). @scope avec une limite (to) permet le "donut scoping" — styliser les éléments dans le scope sauf ceux dans la limite définie.

  • Empêche le contenu de dépasser les limites du conteneur lors du scroll
  • Empêche le scroll du parent de se déclencher quand on atteint les limites du conteneur enfant (scroll chaining) (bonne réponse)
  • Contient le comportement de rebond (bounce) du scroll sur iOS
  • Limite la vitesse de défilement à l'intérieur du conteneur
Explication : overscroll-behavior: contain empêche le "scroll chaining" — quand on atteint la fin d'un conteneur scrollable enfant, le scroll ne se propage pas au parent. Très utile pour les modales, dropdowns, et sidebars avec scroll indépendant. none empêche aussi les effets de rebond (pull-to-refresh) sur mobile.

  • Un seul fichier CSS global partagé entre toutes les applications
  • Adopter des CSS Modules ou une convention BEM stricte avec des préfixes de namespace, combiner avec des tokens de design partagés via npm package (bonne réponse)
  • Dupliquer les styles dans chaque application pour éviter les dépendances croisées
  • Utiliser exclusivement des styles inline pour garantir l'isolation
Explication : Pour un monorepo : 1) Design tokens partagés comme package npm (variables CSS ou JSON). 2) CSS Modules avec namespace automatique (évite collisions). 3) Tailwind config partagée via preset. 4) Composants UI partagés (Storybook). La règle clé : les tokens sont partagés, l'implémentation peut diverger selon les besoins de chaque app.
Mentionne les build tools : Turborepo ou Nx pour le cache et l'orchestration. Les design tokens en TypeScript (Object as const) permettent l'autocomplétion et la vérification de types.

  • counter-increment ajoute des chiffres à content, counter() les affiche automatiquement
  • Ils créent et affichent des compteurs CSS, permettant de numéroter automatiquement des éléments via ::before/::after (bonne réponse)
  • counter() est un alias de nth-child() pour les compteurs de listes
  • counter-increment compte le nombre d'éléments CSS sur la page
Explication : Les compteurs CSS permettent une numérotation automatique. counter-reset: section initialise le compteur. counter-increment: section l'incrémente. content: counter(section) l'affiche. Exemple : numérotation automatique des sections d'article ou des items de liste personnalisés sans modifier le HTML.

  • L'étape du Critical Rendering Path où le navigateur dessine les pixels — optimisée en réduisant les propriétés déclenchant un repaint (couleurs, ombres, border-radius sur de grandes surfaces) (bonne réponse)
  • L'API Canvas CSS pour dessiner des formes directement dans les feuilles de style
  • Le processus de compilation Sass en CSS standard
  • L'application des gradients et effets visuels CSS3
Explication : Le paint convertit le render tree en pixels. Les propriétés déclenchant un repaint coûteux : color, background, box-shadow, border-radius, outline, border-color. Pour optimiser : promouvoir les éléments animés sur des layers GPU (transform/opacity uniquement), utiliser contain: paint, éviter les shadows complexes sur de grandes zones.
Le panel Rendering dans Chrome DevTools (Paint flashing) visualise les zones repeintes. Si toute la page se colore en vert à chaque scroll, il y a un problème de repaint.

  • Cible l'élément focus du formulaire dans lequel il se trouve
  • Cible un élément quand lui-même OU l'un de ses descendants a le focus clavier (bonne réponse)
  • Identique à :focus mais pour les éléments de formulaire uniquement
  • Cible le premier élément focusable dans un conteneur
Explication : :focus-within s'applique à un élément si lui-même OU n'importe lequel de ses descendants a le focus. Utile pour : surligner un formulaire entier quand un champ est actif, afficher un label flottant, mettre en valeur un groupe de contrôles. Exemple : .form-group:focus-within label { color: blue; }.

  • Écrire le moins de CSS possible et utiliser des frameworks CSS pour tout
  • Adopter une architecture cohérente (ITCSS/BEM), des design tokens, un linter CSS, supprimer le CSS mort régulièrement, documenter les décisions non-évidentes (bonne réponse)
  • Utiliser uniquement des sélecteurs d'éléments HTML pour maximiser la réutilisabilité
  • Mettre tout le CSS dans des fichiers inline style pour co-localiser avec le HTML
Explication : Un CSS maintenable repose sur : 1) Architecture cohérente (ITCSS, BEM, Atomic). 2) Design tokens (single source of truth pour les valeurs). 3) CSS Linter (stylelint) pour forcer les conventions. 4) Suppression du CSS mort (PurgeCSS, Coverage DevTools). 5) Documentation des décisions (pourquoi ce hack, cette spécificité). 6) Refactoring régulier.
La dette CSS est insidieuse car CSS ne "casse" pas — les styles obsolètes continuent de fonctionner. Instaure une revue de code CSS et des critères d'acceptation clairs (pas d'ID dans les sélecteurs, pas de !important sans commentaire justificatif).

  • La même chose que @media mais pour les éléments imbriqués
  • Applique des styles selon la taille du conteneur parent de l'élément, pas du viewport (bonne réponse)
  • Crée un conteneur CSS Grid pour les layouts responsives
  • Charge du CSS conditionnel selon la disponibilité d'une ressource
Explication : Les Container Queries permettent de définir des styles selon la taille du conteneur parent de l'élément (et non du viewport). Un composant peut ainsi s'adapter à sa taille disponible, peu importe où il est placé dans la page. On déclare d'abord container-type: inline-size sur le parent, puis @container (min-width: 400px) { ... }.
C'est une des features CSS les plus importantes de la décennie. Elle permet enfin de créer de vrais composants responsive — un bouton peut avoir une mise en page différente dans une sidebar étroite vs un layout large, sans JavaScript.

  • Chaque développeur définit ses propres breakpoints selon le composant qu'il développe
  • Centraliser les breakpoints en custom properties ou tokens, documenter leur sémantique, et les utiliser exclusivement dans les media queries — jamais de valeurs "magiques" (bonne réponse)
  • Utiliser uniquement les 5 breakpoints de Bootstrap sans les modifier
  • Éviter les breakpoints et utiliser uniquement des unités fluides (vw, vh, cqw)
Explication : Bonne pratique : définir les breakpoints dans un token (Sass variable, JS config, ou CSS custom property de référence), les nommer sémantiquement (sm, md, lg, xl), les documenter (640px = mobile landscape, 768px = tablet...). Outils : Sass $breakpoints map + mixin, PostCSS custom media queries, ou la config Tailwind partagée.
Les "magic numbers" de breakpoints éparpillés dans le code rendent la maintenance cauchemardesque. Centralise et nomme — une seule source de vérité pour toute l'équipe.

  • Accède aux variables d'environnement du serveur depuis le CSS
  • Accède aux variables d'environnement définies par le navigateur/OS, comme safe-area-inset pour iPhone (bonne réponse)
  • Importe des variables depuis un fichier .env externe
  • Retourne la valeur d'une propriété CSS de l'environnement parent
Explication : env() accède à des valeurs définies par le navigateur. Usage principal : padding-bottom: env(safe-area-inset-bottom) — essentiel pour les iPhones avec encoche/Dynamic Island (évite que le contenu soit coupé). Les safe-area-insets représentent les zones où l'interface iOS empiète sur le contenu.
Indispensable pour les PWA et les applications mobiles web. Ajoute viewport-fit=cover dans le meta viewport pour activer le mode plein écran sur iOS, puis utilise env(safe-area-inset-*) pour les marges.

  • Le CSS optimisé pour l'impression — défini dans @media print avec page-break-*, orphans, widows et @page pour contrôler la mise en page papier (bonne réponse)
  • Un sous-ensemble de CSS qui ne supporte pas les animations et les effets visuels complexes
  • Le CSS appliqué lors de la génération de PDF côté serveur
  • Le mode d'affichage activé par display: print pour les composants imprimables
Explication : Le print CSS dans @media print contrôle l'apparence à l'impression. Propriétés clés : page-break-before/after/inside (ou break-before/after/inside), orphans/widows (min lignes seules en bas/haut de page), @page (marges, format, orientation). Masquer les navbars, footers, publicités. Utiliser des URLs de liens en contenu (a::after { content: " (" attr(href) ")"; }).

  • Crée un pseudo-élément derrière tous les éléments en position absolute
  • Cible le fond de teinte semi-transparent affiché derrière un élément dialog, fullscreen ou popover (bonne réponse)
  • Définit le fond d'un élément avec backdrop-filter appliqué
  • Cible l'arrière-plan de la fenêtre du navigateur derrière la page
Explication : ::backdrop cible l'overlay créé derrière un élément en mode plein écran (:fullscreen), derrière un <dialog> ouvert, ou derrière un Popover API. Par défaut, c'est un fond noir semi-transparent. On peut le personnaliser : dialog::backdrop { background: rgba(0,0,0,0.5); backdrop-filter: blur(4px); }.

  • Utiliser grid-template-areas pour nommer les zones et placer les enfants par nom, avec les bons breakpoints pour passer en single column sur mobile (bonne réponse)
  • Imbriquer plusieurs grilles, une par section de la page
  • Utiliser grid uniquement pour le main content et position: fixed pour header et sidebar
  • Combiner grid-column et grid-row avec des nombres sur chaque élément enfant
Explication : grid-template-areas est idéal pour les layouts de page : grid-template-areas: "header header" "sidebar main" "footer footer". Chaque enfant est assigné via grid-area: header. C'est lisible, maintenable, et simple à responsive-ifier — sur mobile, on redéfinit les areas en colonnes simples.
C'est la façon la plus lisible de coder un layout de page complexe. La représentation ASCII des zones dans le CSS rend le layout auto-documenté. Montre que tu maîtrises l'outil principal de Grid.

  • Équilibre le poids de la police entre regular et bold
  • Distribue le texte de manière équilibrée sur plusieurs lignes pour éviter les lignes orphelines et améliorer la typographie (bonne réponse)
  • Aligne le texte sur les deux côtés comme justify mais de façon équilibrée
  • Balance la charge de rendu du texte entre le CPU et le GPU
Explication : text-wrap: balance demande au navigateur de répartir équitablement le texte sur les lignes, évitant une dernière ligne avec un seul mot. Parfait pour les titres et sous-titres. text-wrap: pretty est similaire mais optimisé pour les paragraphes (évite les orphelins). Encore en déploiement (support partiel en 2024).

  • Les micro-interactions nécessitent toujours JavaScript pour être accessibles et maintenables
  • Combiner :hover, :focus, :active, :checked avec transition/animation et pseudo-éléments ::before/::after pour créer des effets interactifs complets (bonne réponse)
  • Utiliser uniquement des GIF animés pour éviter le CSS complexe
  • Les micro-interactions CSS sont limitées aux changements de couleur — pour plus, il faut JS
Explication : CSS permet des micro-interactions avancées : :hover + transition pour des effets de survol, :focus-visible pour l'accessibilité clavier, :active pour le feedback de clic, :checked + sélecteur adjacent pour des toggles sans JS, @keyframes + animation pour des effets de feedback. Le tout déclaratif et performant.
Pattern toggle pur CSS : input[type="checkbox"] caché + label stylisé + input:checked ~ .element pour modifier des éléments frères. Accessible (keyboard, screen readers) sans une ligne de JS.

  • Nomme une transition pour la réutiliser avec animation-name
  • Identifie un élément pour participer aux View Transitions API et créer des animations de navigation fluides (bonne réponse)
  • Définit le nom de la vue courante pour le routeur CSS
  • Associe une transition CSS à une vue spécifique du framework
Explication : view-transition-name identifie un élément pour les View Transitions API. Quand la page change (navigation SPA ou MPA), les éléments avec le même nom dans les deux vues sont animés via un morphing automatique. Ex : une carte produit qui "vole" vers la page détail. S'associe avec document.startViewTransition() en JS ou les navigations Chrome modernes.
Feature 2024 très impressionnante pour les SPA. Démo : dans Chrome, une même image sur deux routes différentes fait un morphing fluide sans une ligne d'animation CSS custom.

  • Uniquement en mesurant la taille du fichier CSS minifié
  • En analysant : CSS inutilisé (Coverage), !important count, sélecteurs d'ID, nesting depth, cohérence de nommage, valeurs magiques, et en testant la maintenabilité par un changement de feature simple (bonne réponse)
  • En vérifiant si le CSS passe la validation W3C sans erreurs
  • En comptant le nombre de fichiers CSS — moins il y en a, meilleure est la qualité
Explication : Audit d'une base CSS héritée : 1) Coverage → % inutilisé. 2) Grep !important → dette technique. 3) Grep #id dans CSS → risques de spécificité. 4) Profondeur de nesting → maintenabilité. 5) Valeurs répétées sans variable → opportunités de tokens. 6) Test pratique : ajouter une feature simple → combien d'endroits modifier ?
Le test "modifier la couleur primaire" est révélateur. Si tu dois toucher 50 fichiers → pas de tokens. Si tout change en modifiant une variable → bonne architecture. C'est le test le plus pratique en entretien pour montrer ta vision d'un CSS maintenable.

  • Active le dark mode et le light mode en alternance selon l'heure
  • Indique au navigateur les schémas de couleur supportés, permettant l'adaptation des éléments natifs (scrollbars, inputs) au thème (bonne réponse)
  • Définit une liste de palettes de couleurs à utiliser par les composants
  • Importe les couleurs système de l'OS dans les variables CSS
Explication : color-scheme déclare quels schémas de couleur supporte l'élément (ou la page). Quand défini sur :root, il permet au navigateur d'adapter les éléments natifs (scrollbars, checkboxes, inputs, select) au thème clair/sombre de l'OS. Sans cette propriété, même avec un dark mode complet, les scrollbars restent blancs.

  • Les frameworks CSS utilisant @layer permettent aux utilisateurs de surcharger facilement les styles sans !important car les styles hors layer ont toujours la priorité (bonne réponse)
  • @layer garantit que les styles framework ne peuvent jamais être surchargés par erreur
  • @layer remplace complètement la spécificité dans les frameworks modernes
  • Les cascade layers permettent aux frameworks de charger leur CSS de façon asynchrone
Explication : Sans @layer, surcharger un framework CSS nécessitait souvent une spécificité plus élevée ou !important. Avec @layer, le framework déclare ses styles dans une couche (@layer framework). Les styles utilisateur hors couche ont automatiquement la priorité — quelle que soit leur spécificité. Tailwind v4 adopte cette approche.

  • Ils sont identiques — backdrop-filter est l'alias vendor-prefixé de filter
  • filter blur s'applique à l'élément et son contenu ; backdrop-filter blur s'applique au contenu visible DERRIÈRE l'élément (effet "frosted glass") (bonne réponse)
  • filter blur est plus précis ; backdrop-filter est plus performant
  • backdrop-filter s'applique uniquement aux images PNG avec transparence
Explication : filter: blur(4px) floute l'élément lui-même et son contenu. backdrop-filter: blur(4px) floute ce qui est visible derrière l'élément (effet "verre dépoli" / frosted glass). Pour que backdrop-filter soit visible, l'élément doit avoir une transparence (background: rgba(255,255,255,0.2)). backdrop-filter est plus coûteux en GPU.

  • Atomic CSS génère plus de CSS — BEM est toujours plus optimisé en taille
  • Atomic CSS : de nombreuses classes utilitaires single-purpose dans le HTML (composition) ; BEM : classes sémantiques par composant dans le CSS (abstraction). Le choix dépend du contexte et des préférences d'équipe (bonne réponse)
  • Atomic CSS est uniquement pour les prototypes ; BEM est obligatoire en production
  • BEM et Atomic CSS sont incompatibles et ne peuvent pas coexister dans un même projet
Explication : Atomic CSS (Tailwind, UnoCSS) : chaque classe fait une seule chose (text-blue-500, p-4). Le style est dans le HTML. CSS final très petit (purge). BEM/composants : le HTML est sémantique, le style est dans le CSS. Plus verbeux côté CSS. En production aujourd'hui, Tailwind domine pour sa vitesse de développement, mais BEM reste pertinent pour les design systems complexes.
Ne prends pas position tranchée — dis que tu utilises les deux selon le contexte. Tailwind pour les apps, BEM pour les librairies de composants distribuées (où le consommateur doit pouvoir surcharger facilement).

  • Crée des colonnes qui ont exactement 200px ou 1fr, jamais entre les deux
  • Crée des colonnes d'au moins 200px et d'au plus 1fr de l'espace disponible (bonne réponse)
  • Limit chaque colonne à une largeur maximale d'1fr et minimale de 200px
  • Toutes les options sont équivalentes — minmax est redondant avec 1fr
Explication : minmax(200px, 1fr) définit une colonne dont la largeur est entre 200px minimum et 1fr maximum. La colonne ne sera jamais plus petite que 200px mais peut grandir pour occuper l'espace disponible proportionnellement. Pattern classique avec repeat(auto-fill, minmax(200px, 1fr)) pour une grille responsive sans media queries.