CSS
2022-08
smooth.css /* Applying it to the html element will provide smooth scrolling to anchors
https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior */
html {
scroll-behavior : smooth ;
}
Prendre en compte les préférences utilisateur·ice pour lancer une animation
2022-08
motion.css /* Remove animations for folks who set their OS to reduce motion.
1. Immediately jump any animation to the end point
2. Remove transitions & fixed background attachment
See: https://github.com/mozdevs/cssremedy/issues/11
*/
@ media ( prefers-reduced-motion : reduce ) {
*,
:: before ,
:: after {
animation-delay : -1 ms !important ;
animation-duration : 1 ms !important ;
animation-iteration-count : 1 !important ;
background-attachment : initial !important ;
scroll-behavior : auto !important ;
transition-delay : 0 s !important ;
transition-duration : 0 s !important ;
}
}
Une autre option est de le faire directement en ne chargeant la CSS
dédiée aux animations que si la préférence utilisateur·ice
la rend acceptable :
motion-link.html /* Another approach (no-motion-first approach)
See: https://tatianamac.com/posts/prefers-reduced-motion/ */
< link
rel = "stylesheet"
href = "animations.css"
media = "(prefers-reduced-motion: no-preference)"
/>
Voir aussi ce qu’il est possible de faire en HTML et en JS .
Avoir un bon ratio pour les vidéos
2022-08
Une façon documentée par ici pour afficher des incrustations
vidéos dans un format convenable :
video-ratio.css . video {
aspect-ratio : 16 / 9 ;
width : 100 % ;
}
Un reset minimaliste
2022-08
Un reset très bien documentée par ici qui est relativement
court :
reset.css *, * :: before , * :: after {
box-sizing : border-box ;
}
* {
margin : 0 ;
}
html , body {
height : 100 % ;
}
body {
line-height : 1.5 ;
-webkit- font-smoothing : antialiased ;
}
img , picture , video , canvas , svg {
display : block ;
max-width : 100 % ;
}
input , button , textarea , select {
font : inherit ;
}
p , h1 , h2 , h3 , h4 , h5 , h6 {
overflow-wrap : break-word ;
}
J’ajoute souvent aussi ces quelques règles que j’estime être importantes
pour avoir des styles par défaut cohérents :
reset-extras.css summary {
cursor : pointer ;
}
[ hidden ] {
display : none !important ;
}
[ disabled ] {
pointer-events : none ;
opacity : 0.3 ;
}
Il y a d’autres projets comme minireset.css qui existent.
Masquer du contenu
2022-08
Il y a plusieurs façons de le faire mais je trouve que la meilleure
explication vient de Kitty Giraudel à travers deux articles
de 2020.
screen-readers-only.css . sr-only {
border : 0 !important ;
clip : rect ( 1 px , 1 px , 1 px , 1 px ) !important ;
-webkit- clip-path : inset ( 50 % ) !important ;
clip-path : inset ( 50 % ) !important ;
height : 1 px !important ;
overflow : hidden !important ;
margin : -1 px !important ;
padding : 0 !important ;
position : absolute !important ;
width : 1 px !important ;
white-space : nowrap !important ;
}
. sr-only . sr-only--focusable : focus ,
. sr-only . sr-only--focusable : active {
clip : auto !important ;
-webkit- clip-path : auto !important ;
clip-path : auto !important ;
height : auto !important ;
overflow : visible !important ;
width : auto !important ;
white-space : normal !important ;
}
C’est ensuite utilisable ainsi, par exemple pour un lien d’accès direct
au contenu où l’on a besoin de conserver le focus :
< a href = "#main" class = "sr-only sr-only--focusable" > Skip to content</ a >
Changement de graisse
2022-08
Lorsqu’on clic sur un élément pour le rendre gras (ou l’inverse),
ça modifie l’espace réservé par le navigateur pour ce(s) terme(s).
Parfois, cela peut engendrer des effets disgracieux (hover sur un lien,
item actif d’un onglet, etc).
Une solution trouvée par ici est de charger le contenu en gras
dans un :: before
reserve-bold-space.css . reserve-bold-space :: before {
content : attr ( data -text );
font-weight : bold ;
display : block ;
block-size : 0 ;
visibility : hidden ;
}
On peut ensuite l’appeler ainsi dans le HTML :
< div class = "reserve-bold-space" data-text = "The tab label" >
The tab label
</ div >
Notez bien qu’il faut que le contenu du data-text
soit le même que
le contenu affiché !
Augmenter la spécificité d’une classe
2022-08
Si vous n’avez accès qu’à une classe et qu’il vous faut la spécificité
d’un id par exemple, il est possible d’utiliser : not ()
avec un
id ce qui va artificiellement passer ce sélecteur à une spécificité d’id
même si celui-ci n’existe pas ! Merci Robert Koritnik .
bump-specificity.css . app : not ( # nonexisting ) {
/* whatever. */
}
Pour tester les spécificités en CSS : Specificity Calculator
Cas d’usages de is ()
et has ()
2022-08
Support navigateur
Attention, si is ()
n’est pas trop mal supporté ,
has ()
n’est pas implémenté par de nombreux navigateurs
à ce jour (22 août 2022). Je consigne les cas d’usage ici pour
l’avenir mais ça n’est pas envisageable en production pour l’instant.
Il est possible de tester son existence avec @ supports
+ selector ()
:
@ supports ( selector ( : has ( works ))) {
/* safe to use :has() */
}
Plein d’exemples qui viennent du blog de webkit .
Lorsque tu veux que les éléments qui suivent un titre soient proches
de ce titre :
has-titles.css : is ( h1 , h2 , h3 , h4 , h5 , h6 ) : has (+ : is ( p , figcaption , pre , dl , ul , ol )) {
margin-bottom : 0 ;
}
Lorsque tu veux que ton formulaire t’indique un peu mieux où est
l’erreur :
has-errors.css fieldset : has ( input : invalid ) label {
color : red ;
}
Ici, j’applique un style au label
mais ça pourrait être
plus large bien entendu, ça ouvre de très nombreuses possibilités !
Lorsque tu veux changer des variables CSS en fonction d’un
choix utilisateur·ice (par exemple un sélecteur de thème) :
has-choice.css body : has ( option [ value = 'pony' ] : checked ) {
--font-family : cursive ;
--text-color : #b10267 ;
--body-background : #ee458e ;
--main-background : #f4b6d2 ;
}
Ça ne fait qu’effleurer les possibilités mais ça promet .
Un article par Bramus Van Damme à ce sujet ainsi qu’un
article sur le blog de Chrome qui donnent d’autres exemples.
Trouver les déclarations CSS non utilisées
2022-10
Un petit script à copier-coller dans sa console pour afficher toutes les déclarations CSS qui ne sont pas utilisées dans la page en cours (inspiré de cet article , ce site est une mine).
unused-css.js ;( function () {
let rulesCounter = 0
Array . from ( document . styleSheets ). forEach (( stylesheet ) => {
const rules = Array . from ( stylesheet . cssRules || [])
const sheethref = stylesheet . href || 'inline'
rules . forEach (( rule ) => {
if (
! document . querySelectorAll ( rule . selectorText ). length &&
rule . selectorText !== undefined
) {
console . log ( ` ${ sheethref } : " ${ rule . selectorText } " not found.` )
rulesCounter += 1
}
})
})
console . log ( ` ${ rulesCounter } CSS rules unused on that page.` )
})()
Info
Les CSS sont généralement utilisées pour plusieurs pages à la fois donc ça peut ne pas être très pertinent mais ça donne quand même une aperçu de ce qui pourrait être optimisé pour l’affichage de cette seule page !
2022-11
La propriété scroll-margin-top
permet de gérer la distance depuis le haut de la page et l’endroit jusqu’où scrolle la page lorsqu’il y a une ancre ciblée.
C’est particulièrement intéressant dans un contexte de header sticky
:
scroll-sticky-header.css . topnav {
top : 0 ;
position : sticky ;
padding-top : 1 rem ;
padding-bottom : 1 rem ;
}
. topnav div {
font-size : 1.2 rem ;
}
[ id ] {
scroll-margin-top : calc ( 1.2 rem + 2 rem ); /* (1)! */
}
La taille du texte plus les deux paddings .
Une arborescence à base de ul
et de details
2022-11
Un article détaillé de Kate Rose Morley pour recréer une arborescence en CSS en combinant des ul
/li
et des details
/summary
, particulièrement malin !
tree-ul-details.css . tree {
--spacing : 1.5 rem ;
--radius : 10 px ;
}
. tree li {
display : block ;
position : relative ;
padding-left : calc ( 2 * var ( --spacing ) - var ( --radius ) - 2 px );
}
. tree ul {
margin-left : calc ( var ( --radius ) - var ( --spacing ));
padding-left : 0 ;
}
. tree ul li {
border-left : 2 px solid #ddd ;
}
. tree ul li : last-child {
border-color : transparent ;
}
. tree ul li :: before {
content : '' ;
display : block ;
position : absolute ;
top : calc ( var ( --spacing ) / -2 );
left : -2 px ;
width : calc ( var ( --spacing ) + 2 px );
height : calc ( var ( --spacing ) + 1 px );
border : solid #ddd ;
border-width : 0 0 2 px 2 px ;
}
. tree summary {
display : block ;
cursor : pointer ;
}
. tree summary :: marker ,
. tree summary :: -webkit-details-marker {
display : none ;
}
. tree summary : focus {
outline : none ;
}
. tree summary : focus-visible {
outline : 1 px dotted #000 ;
}
. tree li :: after ,
. tree summary :: before {
content : '' ;
display : block ;
position : absolute ;
top : calc ( var ( --spacing ) / 2 - var ( --radius ));
left : calc ( var ( --spacing ) - var ( --radius ) - 1 px );
width : calc ( 2 * var ( --radius ));
height : calc ( 2 * var ( --radius ));
border-radius : 50 % ;
background : #ddd ;
}
. tree summary :: before {
content : '+' ;
z-index : 1 ;
background : #696 ;
color : #fff ;
line-height : calc ( 2 * var ( --radius ) - 2 px );
text-align : center ;
}
. tree details [ open ] > summary :: before {
content : '−' ;
}
Par ici un exemple complet assez brut car c’est toujours chouette de jouer avec en direct :
Ouvrir dans un nouvel onglet
Utiliser hsl()
et des variables CSS pour décliner des styles
2023-01
Manuel Matuzović montre comment utiliser des variables CSS et la fonction hsl ()
pour adapter un design en ne changeant qu’une seule variable de teinte (hue ) de couleur :
hsl-css-variables.css [ role = 'status' ] {
--h : 206 deg ;
--s : 74 % ;
--background-color : hsl ( var ( --h ) var ( --s ) 90 % );
--border-color : hsl ( var ( --h ) var ( --s ) 70 % );
background-color : var ( --background-color );
border : 2 px solid var ( --border-color );
padding : 1 rem ;
margin-block-end : 1 em ;
}
. warning {
--h : 40 deg ;
}
. error {
--h : 0 deg ;
}
C’est fascinant car cela permet de jouer avec la variable dans l’inspecteur de styles, par exemple en modifiant le curseur j’arrive rapidement à :
Mettre en surbrillance la destination d’une ancre
2023-11
Vient de là et peut être appliqué à une nouvelle entrée sur la page aussi par exemple :
highlight.css : target /* (1)! */ {
animation : highlight 3 s ease-in-out ;
}
@ keyframes highlight {
from {
background-color : palegoldenrod ;
}
to {
background-color : white ;
}
}
Pour que ça s’applique à une ancre, à adapter.
Une grille avec éléments à fond perdu
2023-12
Info
Le « fond perdu » (ou « débord » ou « bord perdu ») est une expression consacrée pour une impression sans marges. Vous aussi vous venez de l’apprendre ?
Merci à Josh W. Comeau pour cette astuce :
grid-full-bleed.css . wrapper {
display : grid ;
grid-template-columns :
1 fr
min ( 60 ch , calc ( 100 % - 64 px )) /* (1)! */
1 fr ;
grid-column-gap : 32 px ;
}
. wrapper > * {
grid-column : 2 ; /* (2)! */
}
. full-bleed {
width : 100 % ;
grid-column : 1 / -1 ; /* (3)! */
}
On définit une colonne centrale de 60ch
pour la visibilité et on prend en compte le gap * 2
pour la version petits écrans.
On met tout le contenu dans la colonne du milieu (seconde ici).
On se donne la possibilité avec une classe de pouvoir étendre un élément à la largeur totale de la fenêtre.
2024-06
Andrew Walpole a créé un outil permettant de définir plusieurs niveaux, Layout Breakouts Builder , dont l’exemple par défaut (4 niveaux) est :
layout-breakouts-builder.css . page-layout > *, . full-width > * {
grid-column : content ;
}
. page-layout , . full-width {
--minimum-content-padding : 2 rem ;
/** TRACK WIDTHS **/
--full-max-width : 1 fr ;
--popout-max-width : 1400 px ;
--content-max-width : 1060 px ;
--inset-content-max-width : 840 px ;
/** TRACK SIZES **/
--full : minmax ( var ( --minimum-content-padding ), 1 fr );
--popout : minmax ( 0 , calc ( ( var ( --popout-max-width ) - var ( --content-max-width )) * 0.5 ) );
--content : minmax ( 0 , calc ( ( var ( --content-max-width ) - var ( --inset-content-max-width )) * 0.5 ) );
--inset-content : min ( var ( --inset-content-max-width ), 100 % - var ( --minimum-content-padding ) * 2 );
display : grid ;
grid-template-columns :
[ full-start ]
var ( --full )
[ popout-start ]
var ( --popout )
[ content - start ]
var ( --content )
[ inset - content - start ]
var ( --inset-content )
[ inset - content - end ]
var ( --content )
[ content - end ]
var ( --popout )
[ popout-end ]
var ( --full )
[ full-end ];
}
/** CLASSES **/
. full { grid-column : full ; }
. full-start { grid-column-start : full-start ; }
. full-end { grid-column-end : full-end ; }
. popout { grid-column : popout ; }
. popout-start { grid-column-start : popout-start ; }
. popout-end { grid-column-end : popout-end ; }
. content { grid-column : content ; }
. content-start { grid-column-start : content - start ; }
. content-end { grid-column-end : content - end ; }
. inset-content { grid-column : inset - content ; }
. inset-content-start { grid-column-start : inset - content - start ; }
. inset-content-end { grid-column-end : inset - content - end ; }
. full-width { grid-column : full ; }
. full-content , . full-content-nopad { grid-column : full ; }
. full-content { padding-inline : var ( --minimum-content-padding ); }
Des éléments arrondis imbriqués et homogènes
2024-06
Un article de Andy Bell, Relative rounded corners , qui explique comment faire en sorte que des bords arrondis imbriqués conservent un radius homogène plus plaisant à l’œil :
matched-radius.css . matched-radius {
--matched-radius-padding : 8 px ;
--matched-radius-inner-size : 12 px ;
padding : var ( --matched-radius-padding );
border-radius : calc (
var ( --matched-radius-inner-size ) + var ( --matched-radius-padding )
);
}
. matched-radius__inner {
border-radius : var ( --matched-radius-inner-size );
}
La beauté des variables CSS , c’est qu’il est possible de les écraser directement depuis le HTML au besoin. Par exemple :
< div class = "matched-radius"
style = "--matched-radius-inner-size: 15px;--matched-radius-padding: 4px;" >
< div class = "matched-radius__inner" >
</ div >
</ div >
2024-06
Un article de Andrew Walpole, The Showy / Hidey Navigation Bar qui documente un pattern qui je n’affectionne pas vraiment mais ça peut être utile dans certaines circonstances :
showy-hidey-header.css header {
--nav-height : 100 px ;
min-height : var ( --nav-height );
.navbar {
--top-position : 0 px ;
position : fixed ;
width : 100 % ;
top : var ( --top-position );
transition : top 0.6 s ; /* (1)! */
&. hide : not ( : focus -within ) {
-- top - position : -100 % ;
}
}
}
« animer/transitionner top
, c’est mal ! » dit Rik .
Il est à noter que cela nécessite d’avoir également un bout de JS pour gérer le calcul du masquage (scroll down) / réaffichage (scroll up) :
showy-hidey-header.js const useShowyHidey = () => {
let lastScrollTop = 0
const navbar = document . querySelector ( '.navbar' )
const navHeight = getComputedStyle ( navbar ). getPropertyValue ( '--nav-height' )
const toggleNavOnScroll = () => {
const currentScrollTop = document . documentElement . scrollTop
if (
currentScrollTop > lastScrollTop &&
currentScrollTop > Number . parseInt ( navHeight )
) {
navbar . classList . add ( 'hide' )
} else if ( currentScrollTop < lastScrollTop ) {
navbar . classList . remove ( 'hide' )
}
lastScrollTop = Math . max ( 0 , currentScrollTop )
}
if ( navbar ) {
window . removeEventListener ( 'scroll' , toggleNavOnScroll )
window . addEventListener ( 'scroll' , toggleNavOnScroll )
}
}
useShowyHidey ()
Pour des boutons plus résilients
2024-10
Un article de David Bushell sur des propriétés CSS moins connues relatives aux boutons :
button-styling.css . button ,
:: file-selector-button {
inline-size : fit-content ;
touch-action : manipulation ;
user-select : none ;
}
* {
&:focus-visible {
outline : 2 px solid magenta ;
outline-offset : 2 px ;
}
}
Un curseur dédié pour pointer des éléments
2024-10
Je suis pas mal de l’avis de Chris Ferdinandi concernant l’importance de changer le type de curseur au survol d’éléments comme < summary >
:
cursor-pointer.css button ,
[ type = "button" ],
[ type = "reset" ],
[ type = "submit" ],
[ type = "image" ],
[ type = "checkbox" ],
[ type = "radio" ],
summary {
cursor : pointer ;
}
Note
Si vous avez une référence solide qui vient expliquer pourquoi cela n’est pas une bonne idéé, notamment en matière d’accessibilité, n’hésitez pas à me contacter !
Exemples de CSS minimalistes / sans classe
2022-10
Pour progresser
2024-10
Pour jouer
2022-10