L'attribut lang ne peut être associé qu'à une seule langue. Cela signifie que l'attribut <html>
ne peut avoir qu'une seule langue, même si plusieurs langues sont utilisées sur la page. Définissez lang
sur la langue principale de la page.
<html lang="ar,en,fr,pt">...</html>
<html lang="ar">...</html>
Liens
Comme pour les boutons, le nom accessible des liens provient principalement de leur contenu textuel. Lorsque vous créez un lien, il est judicieux de placer le texte le plus pertinent dans le lien lui-même, plutôt que d'utiliser des mots de remplissage comme "Ici" ou "En savoir plus".
Check out our guide to web performance <a href="/guide">here</a>.
Check out <a href="/guide">our guide to web performance</a>.
Vérifier si une animation déclenche une mise en page
Une animation qui déplace un élément à l'aide d'un autre élément que transform
est susceptible d'être lente.
Dans l'exemple suivant, j'ai obtenu le même résultat visuel en animant top
et left
, et en utilisant transform
.
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { top: calc(90vh - 160px); left: calc(90vw - 200px); } }
.box { position: absolute; top: 10px; left: 10px; animation: move 3s ease infinite; } @keyframes move { 50% { transform: translate(calc(90vw - 200px), calc(90vh - 160px)); } }
Vous pouvez le tester dans les deux exemples Glitch suivants et explorer les performances à l'aide de DevTools.
Avec le même balisage, nous pouvons remplacer padding-top: 56.25%
par aspect-ratio: 16 / 9
, en définissant aspect-ratio
sur un ratio spécifié de width
/ height
.
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
L'utilisation de aspect-ratio
au lieu de padding-top
est beaucoup plus claire et ne révise pas la propriété de marge intérieure pour effectuer une action en dehors de son champ d'application habituel.
Oui, c'est bien cela. J'utilise reduce
pour enchaîner une séquence de promesses. Je suis tellement intelligent. Mais il s'agit d'un code trop intelligent dont vous pouvez vous passer.
Toutefois, lorsque vous convertissez ce code en fonction asynchrone, il est tentant d'être trop séquentiel:
async function logInOrder(urls) { for (const url of urls) { const response = await fetch(url); console.log(await response.text()); } }
function markHandled(...promises) { Promise.allSettled(promises); } async function logInOrder(urls) { // fetch all the URLs in parallel const textPromises = urls.map(async (url) => { const response = await fetch(url); return response.text(); }); markHandled(...textPromises); // log them in sequence for (const textPromise of textPromises) { console.log(await textPromise); } }
reduce
"intelligent" est remplacé par une boucle for standard, ennuyeuse et lisible.
Écrire des propriétés personnalisées Houdini
Voici un exemple de définition d'une propriété personnalisée (pensez à une variable CSS), mais avec une syntaxe (type), une valeur initiale (valeur de remplacement) et une valeur booléenne d'héritage (hérite-t-elle de la valeur de son parent ou non ?). La méthode actuelle consiste à utiliser CSS.registerProperty()
en JavaScript, mais à partir de Chromium 85, la syntaxe @property
sera prise en charge dans vos fichiers CSS:
CSS.registerProperty({ name: '--colorPrimary', syntax: '' , initialValue: 'magenta', inherits: false });
@property --colorPrimary { syntax: '' ; initial-value: magenta; inherits: false; }
Vous pouvez désormais accéder à --colorPrimary
comme à n'importe quelle autre propriété CSS personnalisée, via var(--colorPrimary)
. Cependant, la différence ici est que --colorPrimary
n'est pas simplement lu comme une chaîne. Il contient des données !
CSS backdrop-filter
applique un ou plusieurs effets à un élément translucide ou transparent. Pour comprendre cela, regardez les images ci-dessous.

.frosty-glass-pane { backdrop-filter: blur(2px); }

.frosty-glass-pane { opacity: .9; backdrop-filter: blur(2px); }
L'image de gauche montre comment les éléments se chevauchant seraient affichés si backdrop-filter
n'était pas utilisé ou n'était pas compatible. L'image de droite applique un effet de floutage à l'aide de backdrop-filter
. Notez qu'il utilise opacity
en plus de backdrop-filter
. Sans opacity
, il n'y aurait rien à flouter. Il va presque de soi que si opacity
est défini sur 1
(entièrement opaque), l'arrière-plan n'est pas affecté.
Cependant, contrairement à l'événement unload
, beforeunload
peut être utilisé de manière légitime. Par exemple, lorsque vous souhaitez avertir l'utilisateur qu'il a des modifications non enregistrées qu'il perdra s'il quitte la page. Dans ce cas, nous vous recommandons de n'ajouter des écouteurs beforeunload
que lorsqu'un utilisateur a des modifications non enregistrées, puis de les supprimer immédiatement après l'enregistrement des modifications non enregistrées.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });
beforeunload
sans condition.
function beforeUnloadListener(event) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; }; // A function that invokes a callback when the page has unsaved changes. onPageHasUnsavedChanges(() => { window.addEventListener('beforeunload', beforeUnloadListener); }); // A function that invokes a callback when the page's unsaved changes are resolved. onAllChangesSaved(() => { window.removeEventListener('beforeunload', beforeUnloadListener); });
beforeunload
que lorsqu'il est nécessaire (et le supprime lorsqu'il ne l'est pas).
Minimiser l'utilisation de Cache-Control: no-store
Cache-Control: no-store
est un en-tête HTTP que les serveurs Web peuvent définir sur les réponses pour indiquer au navigateur de ne pas stocker la réponse dans un cache HTTP. Cette valeur doit être utilisée pour les ressources contenant des informations utilisateur sensibles, par exemple les pages derrière une connexion.
L'élément fieldset
, qui contient chaque groupe d'entrée (.fieldset-item
), utilise gap: 1px
pour créer les bordures fines entre les éléments. Aucune solution de bordure délicate !
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
Retour à la ligne naturel dans la grille
La mise en page la plus complexe s'est avérée être la mise en page macro, le système de mise en page logique entre <main>
et <form>
.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
L'élément fieldset
, qui contient chaque groupe d'entrée (.fieldset-item
), utilise gap: 1px
pour créer les bordures fines entre les éléments. Aucune solution de bordure délicate !
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
Mise en page <header>
des onglets
La mise en page suivante est presque identique: j'utilise flex pour créer un ordre vertical.
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
.snap-indicator
doit se déplacer horizontalement avec le groupe de liens, et cette mise en page d'en-tête permet de le faire. Aucun élément positionné de manière absolue ici !
Gentle Flex est une stratégie de centrage uniquement plus fidèle. Il est doux et délicat, car contrairement à place-content: center
, aucune taille de boîte enfant n'est modifiée lors du centrage. Tous les éléments sont empilés, centrés et espacés aussi délicatement que possible.
.gentle-flex {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1ch;
}
- Ne gère que l'alignement, l'orientation et la distribution
- Les modifications et la maintenance sont toutes au même endroit
- L'espacement garantit un espacement égal entre les n enfants.
- Nombre le plus élevé de lignes de code
Idéal pour les mises en page macro et micro.
Utilisation
gap
accepte n'importe quelle longueur ou pourcentage CSS comme valeur.
.gap-example {
display: grid;
gap: 10px;
gap: 2ch;
gap: 5%;
gap: 1em;
gap: 3vmax;
}
Vous pouvez transmettre une longueur de 1 pour l'espace, qui sera utilisée à la fois pour la ligne et la colonne.
.grid { display: grid; gap: 10px; }
.grid { display: grid; row-gap: 10px; column-gap: 10px; }
Gap peut transmettre deux longueurs, qui seront utilisées pour les lignes et les colonnes.
.grid { display: grid; gap: 10px 5%; }
.grid { display: grid; row-gap: 10px; column-gap: 5%; }