Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Les petites aventures de CSS, saison 2025

Raphael Goetter
January 24, 2025

Les petites aventures de CSS, saison 2025

CSS a bien évolué.
De simple langage de description à ses débuts, il devient un véritable outil de programmation, embarquant variables, imbrications, conditions et un peu plus chaque jour.
Les évolutions sont parfois si nombreuses qu'il est difficile de tout suivre. Ça tombe bien car c'est justement ce qu'on va faire : un rapide panorama de fonctionnalités modernes mais déjà utilisables en production (variables, sélecteurs, cascade, positionnements, etc.)

Raphael Goetter

January 24, 2025
Tweet

More Decks by Raphael Goetter

Other Decks in Design

Transcript

  1. CSS 1 finalisé (50 propriétés) 1996 1998 CSS 2 finalisé

    CSS 3 🤯 (1ère propriété) 1999 CSS "living standard" 2012 2007 CSS 2.1 finalisé 2025 ~650 propriétés en CSS Google Chrome 1 Internet Explorer 6 Microsoft Edge Mozilla Firefox 1
  2. QUE SIGNIFIE VRAIMENT "CSS" ? Cascading Style Sheets Completely Shitty

    Selectors C'est Super Simple ! Centering Stuffs Simply Choucroute et Saucisses de Strasbourg 1
  3. COMMENT RÉDIGER UN COMMENTAIRE EN CSS ? {{ ceci est

    un commentaire }} /# ceci est un commentaire #/ /* ceci est un commentaire */ <!-- ceci est un commentaire --> // ceci est un commentaire 2
  4. QUI EST TIM BERNERS-LEE ? L'inventeur des Gifs animés L'inventeur

    du Web L'inventeur de CSS L'inventeur des memes Le frère de Bruce (déso) 3
  5. QU'EST-CE DONC QUE CECI ? Un extrait de la documentation

    du framework Tailwind Une suite de caractères aléatoires Un listing en langage Basic comme au bon vieux temps Une incantation satanique ancestrale Laissez-moi partir, par pitié ! 4 <div class="relative mx-auto p-3 col-start-1 row- start-1 flex flex-col-reverse rounded-lg bg- gradient-to-t from-black/75 via-black/0 text- center md:text-left sm:bg-none sm:row-start-2 sm:mx-0 sm:p-0 lg:row-start-1"> 1
  6. COMBIEN DE LIGNES DE CSS FAUT-IL POUR CENTRER VERTICALEMENT UN

    ÉLÉMENT ? Une bonne dizaine J'ai arrêté de compter Deux ou trois maximum Toi, tu veux avoir des ennuis On ne peut pas centrer verticalement en CSS 5
  7. VARIABLES CSS Leur vrai nom : "Custom Properties" support :root

    { --color-text: hotpink; --spacing-md: 12px; } /* Button component */ .button { color: var(--color-text); padding: var(--spacing-md); } Ici nous déclarons les variables dans :root (= tout le document) et les associons à une valeur. Ces variables sont appliquées sur ce bouton à l'aide de var(). Les "variables" CSS (custom properties) sont des propriétés personnalisables, manipulables et réutilisables.
  8. VARIABLES CSS Leur vrai nom : "Custom Properties" support CAS

    D'USAGES CLASSIQUES ? .card { --gap: 16px; display: grid; gap: var(--gap); } @media (min-width: 576px) { .card { --gap: 32px; } } modifier des gouttières selon la place dispo :root { --color-text: black; } @media (prefers-color-scheme: dark) { :root { --color-text: white; } } .component { color: var(--color-text); } modifier des couleurs selon les prefs utilisateur
  9. .link { display: flex; flex-wrap: wrap; } .link:hover, .link:focus {

    color: hotpink; } @media (min-width: 576px) { .link { flex-direction: column; } } .link > * { margin-left: 1rem; } sans nesting La syntaxe "classique" de CSS engendre fréquemment des répétitions de sélecteurs qui compliquent la maintenabilité du projet dans la durée. NESTING Imbrication de sélecteurs CSS support La syntaxe imbriquée (nesting) rassemble les règles CSS dans un seul sélecteur et évite un grand nombre de répétitions inutiles.
  10. .link { display: flex; flex-wrap: wrap; } .link:hover, .link:focus {

    color: hotpink; } @media (min-width: 576px) { .link { flex-direction: column; } } .link > * { margin-left: 1rem; } sans nesting NESTING Imbrication de sélecteurs CSS support .link { display: flex; flex-wrap: wrap; &:hover, &:focus { color: hotpink; } @media (min-width: 576px) { flex-direction: column; } & > * { margin-left: 1rem; } } avec nesting
  11. La règle @supports() s'assure du support navigateur pour une propriété

    donnée et n'applique les styles que si la condition est respectée. @SUPPORTS Détection du support navigateur support .title { color: #000; /* je suis noir par défaut */ } @supports (backdrop-filter: initial) { .title { backdrop-filter: blur(10px) brightness(60%); color: #fff; } } Si backdrop-filter n'est pas reconnu par le navigateur, la couleur de texte reste noire.
  12. DISPLAY: CONTENTS Effacement d'une boîte en CSS support Un élément

    en display: contents n'est plus généré. Ses enfants héritent directement des propriétés de son parent, un peu comme si on faisait "sauter un étage" en CSS. .row { display: flex; } /* ou bien */ .row { display: grid; } .col-6 { display: contents; } hop, je ne suis plus là ! (uniquement en CSS) .row { display: flex; } /* ou bien */ .row { display: grid; } marche pô <div class="row"> <div class="col-6"> <div>1</div> <div>2</div> <div>3</div> </div> </div> Je veux appliquer Flexbox ou Grid sur "row" et avoir une action sur les div 1, 2 et 3... (toute ressemblance avec Bootstrap n'est pas fortuite)
  13. :HAS() Sélecteur de parent (et plus encore) support /* si

    le lien contient une image, j'applique ces styles sur le lien */ a:has(img) { color: hotpink; } <a href=""> <img src="" alt=""> </a> La pseudo-classe :has() permet de cibler l'ancêtre d'un élément… mais pas que. selecteur:has(liste-de-selecteurs) {}
  14. :HAS() Sélecteur de parent (et plus encore) support .product:has(.discount) {

    order: -1; } Je mets en avant les produits soldés -50% -30%
  15. :HAS() Sélecteur de parent (et plus encore) support .card {

    display: grid; grid-template-columns: auto 1fr; } .card:has(>img) { gap: 20px; } source : Codepen Je veux une gouttière ici, mais uniquement s'il y a une image enfant direct dans la card .card-group:has(> :nth-child(2):last-child) { gap: 20px; } Et je veux une gouttière ici, uniquement si ce conteneur a exactement deux enfants 🤯
  16. :HAS() Sélecteur de parent (et plus encore) support .form-group:has(input:checked) {

    background: #ddd; } source : Codepen Je veux une couleur de fond sur le parent du label et de la checkbox quand celle-ci est cochée
  17. :HAS() Sélecteur de parent (et plus encore) support .subMenu {

    display: grid; &:has(> :nth-child(6)) { grid-template-columns: 1fr 1fr; width: 250px; } &:has(> :nth-child(8)) { grid-template-columns: 1fr 1fr 1fr; width: 350px; } } source : Ahmad Shadeed Les styles s'adaptent au nombre d'enfants !
  18. :HAS() Sélecteur de parent (et plus encore) support <body> ...

    n'importe où dans le DOM ... <div> <input type="checkbox" id="check" class="toggle"> <label for="check">toggle light/dark</label> </div> </body> source : Codepen body { background-color: white; color: black; } body:has(#check:checked) { background-color: black; color: white; } J'inverse les couleurs de la page quand la checkbox est cochée
  19. “ Grâce à :has() il est possible de cibler n'importe

    quel élément du DOM à partir de n'importe quel autre élément du DOM.
  20. GRID LAYOUT Le positionnement moderne en CSS support <div class="container">

    <header>header</header> <nav>nav</nav> <article>article</article> <footer>footer</footer> </div> .container { display: grid; gap: 10px; @media (width > 576px) { grid-template-columns: 200px 1fr; & header, & footer { grid-column: span 2; } } } affichage sur écran réduit : une seule colonne affichage sur écran plus large : deux colonnes Grid Layout est le modèle de positionnement responsive en CSS par excellence. Tout est y réalisable : placement, fluidité, alignements, etc.
  21. ALIGNEMENTS PARTOUT align et justify sur des display block support

    Les propriétés align / justify sont désormais applicables en dehors des spécifications Grid et Flexbox .container { display: ce-que-tu-veux; align-content: center; } align-content justify-content align-self justify-self
  22. SCROLL-SNAP Technique de scroll avec des points d'accroche support Scroll-snap

    crée des points d'accroche lors du défilement, permettant de garantir la position sur laquelle on arrive après avoir fait défiler du contenu. .card-group { overflow-x: auto; scroll-snap-type: x mandatory; } .card { scroll-snap-align: center; } adhérence des enfants sur l'axe x alignement de chaque card sur la "grille" (ici, elle sera centrée)
  23. Permet d'ancrer n'importe quel élément par rapport à n'importe quel

    autre élément dans le DOM .anchor { anchor-name: --anchor; } .target { position: absolute; position-anchor: --anchor; position-area: right; } je sers de référence je me positionne par rapport à l'ancre de référence ANCHOR POSITIONING Positionner un élément par rapport à n'importe quel autre support Source : Codepen
  24. ANCHOR POSITIONING Positionner un élément par rapport à n'importe quel

    autre support Valeur ancrée au slider. Source : Codepen Source : Codepen Source : Codepen
  25. QUELLE COULEUR CSS EST LA PLUS SOMBRE ? grey darkgrey

    lightgrey white grey's anatomy fifty shades of grey 1
  26. !IMPORTANT SIGNIFIE-T-IL "IMPORTANT" OU "PAS IMPORTANT" ? Oui c'est important

    Non on s'en fiche un peu Ça dépend ? Moi j'en mets partout, au cas où C'est un piège ! 3
  27. QUELLE EST LA VALEUR MAXIMALE THÉORIQUE DE LA PROPRIÉTÉ Z-INDEX

    ? 0 1023 16383 65535 plus de 2 milliards 4
  28. UNITÉS DE VIEWPORT vw, vh, vmin, vmax support 100vw .element

    { width: 100vw; /* 100% viewport width */ } .element { min-height: 100vh; /* 100% viewport height */ } 100vh Les unités de viewport se réfèrent à l'ensemble de la fenêtre et non au parent de l'élément.
  29. UNITÉS DE VIEWPORT DYNAMIQUES dvw, dvh, ... support .element {

    min-height: 100vh; /* 100% viewport height */ } 100dvh .element { min-height: 100dvh; /* 100% dynamic viewport height */ } 100dvh bug connu sur iOS
  30. MEDIA QUERIES RANGE La nouvelle syntaxe intuitive support La syntaxe

    moderne (range) des Media Queries est bien plus intuitive que la syntaxe historique @media (min-width: 576px) { ... } @media (max-width: 768px) { ... } @media (min-width: 320px) and (max-width: 768px) { ... } #old (mais toujours OK) @media (width >= 576px) { ... } @media (width <= 768px) { ... } @media (320px <= width <= 768px) { ... } #new .card { display: flex; flex-direction: column; @media (width > 576px) { flex-direction: row; } } et en plus on peut l'imbriquer (nesting) !
  31. CONTAINER QUERIES Styles conditionnés par la taille d'un conteneur support

    Les Container Queries permettent d'interroger la taille d'un conteneur ancêtre et d'adapter des styles CSS sur un élement descendant. <div class="card-container"> <article class="card"> <img> <h2></h2> <p></p> <button></button> </article> </div> .card-container { container-type: inline-size; } @container (width >= 400px) { .card { /* styles à appliquer */ } } Je fais une requête sur la largeur (inline-size) de .card-container Si la condition de largeur est remplie, alors j'applique plein de jolis styles CSS
  32. Les Style Queries permettent d'interroger les styles d'un conteneur ancêtre

    et d'adapter des styles CSS sur un élement descendant. .card-container { --discount: 50; } @container style(--discount: 50) { .card { /* styles à appliquer */ } } Je fais une requête sur la valeur de --discount du container STYLE QUERIES Styles conditionnés par les styles d'un conteneur support
  33. /* Custom Media Queries */ :root { --viewport: mobile; @media

    (width >= 768px) { --viewport: tablet; } @media (width >= 1280px) { --viewport: desktop; } } La variable --viewport s'adapte à la taille de la fenêtre STYLE QUERIES Styles conditionnés par les styles d'un conteneur support Source : Codepen Le nombre de colonnes s'adapte à --viewport .card { display: grid; @container style(--viewport: tablet) { grid-template-columns: 200px 1fr; } }
  34. Animations déclenchées au scroll dans la page ou à la

    visibilité d'un élément dans la page source : Codepen ANIMATION-TIMELINE support Animations liées au scroll ou à la vue
  35. @supports (animation-timeline: scroll()) { .to-top { opacity: 0; animation: linear

    auto both; animation-name: reveal; animation-timeline: scroll(y); animation-range: 300px 300px; } } @keyframes reveal { 100% { opacity: 1; } } Bouton scroll-to-top. Source : Codepen ANIMATION-TIMELINE: SCROLL() support Animations liées au scroll
  36. Liens masqués au scroll. Source : Codepen Indicateur de scroll

    vertical. Source : Codepen Auto-hide sticky header. Source : Codepen ANIMATION-TIMELINE: SCROLL() support Animations liées au scroll
  37. Animation des "toppings" SVG en arrivant dans le viewport. Source

    : Codepen Animations déclenchées selon la visibilité d'un élément dans la fenêtre ou son parent ANIMATION-TIMELINE: VIEW() support Animations liées à la visibilité dans le viewport
  38. Rangées de logos défilants horizontalement lorsque la section traverse le

    viewport (animation "view") ANIMATION-TIMELINE: VIEW() support Animations liées à la visibilité dans le viewport
  39. Navigation du site lorsque chaque section entre dans le viewport

    (animation de type "view") goetter.fr ANIMATION-TIMELINE: VIEW() support Animations liées à la visibilité dans le viewport
  40. QUELLE RÈGLE L'EMPORTE ? .kiwi { color: hotpink; } .kiwi

    { color: hotpink !important; } .kiwi { color: hotpink !veryimportant; } #kiwi { color: hotpink; } <div style="color: hotpink"> 1
  41. OÙ DONC EST NÉ LE WEB ? En Alsace En

    France Aux États-Unis En Suisse En Grande Bretagne 2
  42. 2

  43. QUE RETROUVE-T-ON SUR LA PAGE D’ACCUEIL DU TOUT PREMIER SITE

    WEB ? Une photo de chat Des gifs animés Une animation Flash Une publicité Une liste de liens 3
  44. QUELLE EST LA PARTICULARITÉ DE LA COULEUR "REBECCAPURPLE" ? C'est

    un palindrome Elle n'est pas du tout violette Elle n'existe pas Il s'agit d'un hommage à une personne réelle C'est la couleur de fond du logo officiel de CSS 4
  45. MERCI ! raphaël goetter slides sur : https://speakerdeck.com/goetter unités de

    viewport media query range container query style query animation-timeline (scroll) animation-timeline (view) grid layout aligner partout scroll-snap anchor positioning variables nesting @supports display: contents :has