Comparer & CompareCaption

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 la page en contient plusieurs. Définissez lang sur la langue principale de la page.

À éviter
<html lang="ar,en,fr,pt">...</html>
Vous ne pouvez pas utiliser plusieurs langues.
À faire
<html lang="ar">...</html>
Définissez uniquement la langue principale de la page. Ici, la langue est l'arabe.

Comme les boutons, les liens obtiennent principalement leur nom accessible à partir de leur contenu textuel. Une bonne astuce lors de la création d'un lien consiste à insérer le texte le plus significatif dans le lien lui-même, plutôt que des mots de remplissage tels que "ici" ou "En savoir plus".

Pas assez descriptive
Check out our guide to web performance <a href="/guide">here</a>.
Contenus utiles !
Check out <a href="/guide">our guide to web performance</a>.

Vérifier si une animation déclenche la mise en page

Une animation qui déplace un élément avec autre chose que transform peut être lente. Dans l'exemple suivant, j'ai obtenu le même résultat visuel en animant top et left, et en utilisant transform.

À éviter
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     top: calc(90vh - 160px);
     left: calc(90vw - 200px);
  }
}
À faire
.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 tester cela dans les deux exemples de Glitch suivants et explorer les performances à l'aide des outils de développement.

Avec le même balisage, nous pouvons remplacer padding-top: 56.25% par aspect-ratio: 16 / 9, et définir aspect-ratio sur un ratio spécifié de width / height.

Utiliser padding-top
.container {
  width: 100%;
  padding-top: 56.25%;
}
Utiliser les proportions
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

L'utilisation de aspect-ratio au lieu de padding-top est beaucoup plus claire et ne remanie pas la propriété de marge intérieure pour effectuer une action en dehors de son champ d'application habituel.

Oui, c'est exact, j'utilise reduce pour enchaîner une séquence de promesses. Je suis tellement intelligente. Mais ce codage est un peu très intelligent qu'il vaut mieux ne pas le faire.

Toutefois, lors de la conversion de la fonction ci-dessus en fonction asynchrone, il est tentant de passer trop séquentiel:

Déconseillé (trop séquentiel)
async function logInOrder(urls) {
  for (const url of urls) {
    const response = await fetch(url);
    console.log(await response.text());
  }
}
Cela semble beaucoup plus propre, mais ma deuxième extraction ne commence pas tant que ma première exploration n'a pas été entièrement lue, et ainsi de suite. C'est beaucoup plus lent que dans l'exemple des promesses qui effectue les extractions en parallèle. Heureusement, il existe un milieu idéal.
Recommandée : sympa et parallèle
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);
  }
}
Dans cet exemple, les URL sont récupérées et lues en parallèle, mais le bit reduce "intelligent" est remplacé par un for-loop standard, ennuyeux et lisible.

Écrire des propriétés personnalisées Houdini

Voici un exemple de définition d'une propriété personnalisée (variable CSS, par exemple), mais avec une syntaxe (type), une valeur initiale (remplacement) et une valeur booléenne d'héritage (la valeur de son parent est-elle héritée ou non ?). La méthode actuelle consiste à utiliser CSS.registerProperty() en JavaScript. Toutefois, dans Chromium 85 et versions ultérieures, la syntaxe @property sera compatible avec vos fichiers CSS:

Fichier JavaScript distinct (Chromium 78)
CSS.registerProperty({
  name: '--colorPrimary',
  syntax: '',
  initialValue: 'magenta',
  inherits: false
});
Incluse dans le fichier CSS (Chromium 85)
@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 seulement lu sous forme de chaîne. Il a des données !

Le CSS backdrop-filter applique un ou plusieurs effets à un élément translucide ou transparent. Pour le comprendre, tenez compte des images ci-dessous.

Pas de transparence au premier plan
Triangle superposé sur un cercle. Le cercle ne peut pas être vu à travers le triangle.
.frosty-glass-pane {
  backdrop-filter: blur(2px);
}
Transparence du premier plan
Triangle superposé sur un cercle. Le triangle est translucide, ce qui permet de voir le cercle à travers.
.frosty-glass-pane {
  opacity: .9;
  backdrop-filter: blur(2px);
}

L'image de gauche montre comment les éléments qui se chevauchent seraient affichés si backdrop-filter n'était pas utilisé ou accepté. 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 aucun élément à flouter. Il va sans dire que si opacity est défini sur 1 (entièrement opaque), cela n'aura aucun effet sur l'arrière-plan.

Cependant, contrairement à l'événement unload, il existe des utilisations légitimes de beforeunload. Par exemple, lorsque vous souhaitez avertir l'utilisateur qu'il a des modifications non enregistrées, il sera perdu s'il quitte la page. Dans ce cas, nous vous recommandons d'ajouter des écouteurs beforeunload uniquement lorsqu'un utilisateur a non enregistré des modifications, puis de les supprimer immédiatement après leur enregistrement.

À éviter
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
Le code ci-dessus ajoute un écouteur beforeunload sans condition.
À faire
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);
});
Le code ci-dessus n'ajoute l'écouteur beforeunload que lorsque cela est nécessaire (et le supprime dans le cas contraire).

Réduire 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 qui indiquent au navigateur de ne pas stocker la réponse dans un cache HTTP. Il doit être utilisé pour les ressources contenant des informations utilisateur sensibles, par exemple les pages nécessitant une connexion.

L'élément fieldset, qui contient chaque groupe d'entrée (.fieldset-item), utilise gap: 1px pour créer les bordures de contour entre les éléments. Pas de solution de bordure compliquée !

Intervalle comblé
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
Astuce de bordure
.grid {
  display: grid;

  & > .fieldset-item {
    background: var(--bg-surface-2);

    &:not(:last-child) {
      border-bottom: 1px solid var(--bg-surface-1);
    }
  }
}

Enveloppement naturel de la grille

La mise en page la plus complexe a fini par être la mise en page macro, le système de mise en page logique entre <main> et <form>.

entrée
<input
  type="checkbox"
  id="text-notifications"
  name="text-notifications"
>
étiquette
<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 de contour entre les éléments. Pas de solution de bordure compliquée !

Intervalle comblé
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
Astuce de bordure
.grid {
  display: grid;

  & > .fieldset-item {
    background: var(--bg-surface-2);

    &:not(:last-child) {
      border-bottom: 1px solid var(--bg-surface-1);
    }
  }
}

Mise en page des onglets <header>

La mise en page suivante est presque la même: j'utilise l'flex pour créer un ordre vertical.

HTML
<snap-tabs>
  <header>
    <nav></nav>
    <span class="snap-indicator"></span>
  </header>
  <section></section>
</snap-tabs>
CSS
header {
  display: flex;
  flex-direction: column;
}

Le .snap-indicator doit se déplacer horizontalement avec le groupe de liens, et cette mise en page d'en-tête permet de définir cette étape. Il n'y a pas d'éléments positionnés de façon absolue ici.

Gentle Flex est une stratégie de centrage uniquement plus efficace. Il est doux et doux, car contrairement à place-content: center, la taille de la boîte pour les enfants n'est pas modifiée pendant le centrage. Aussi délicatement que possible, tous les éléments sont empilés, centrés et espacés.

.gentle-flex {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1ch;
}
Avantages
  • Gère uniquement l'alignement, la direction et la distribution
  • Modifications et maintenance au même endroit
  • L'écart garantit un espacement égal entre n enfants
Inconvénients
  • La plupart des 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;
}


L'écart peut être transmis d'une longueur, qui sera utilisée à la fois pour la ligne et la colonne.

Raccourci
.grid {
  display: grid;
  gap: 10px;
}
Définir des lignes et des colonnes ensemble à la fois
Développé
.grid {
  display: grid;
  row-gap: 10px;
  column-gap: 10px;
}


L'écart peut être transmis de deux longueurs, qui seront utilisées pour les lignes et les colonnes.

Raccourci
.grid {
  display: grid;
  gap: 10px 5%;
}
Définir les lignes et les colonnes séparément en même temps
Développé
.grid {
  display: grid;
  row-gap: 10px;
  column-gap: 5%;
}