Créer un composant Settings

Présentation de base sur la création d'un composant de paramètres composé de curseurs et de cases à cocher.

Dans cet article, je souhaite partager mes réflexions sur la création d'un composant de paramètres pour le Web qui est responsif, compatible avec plusieurs entrées d'appareils et compatible avec tous les navigateurs. Essayez la démo.

Démo

Si vous préférez une vidéo ou un aperçu de l'UI/UX de ce que nous créons, voici une visite guidée plus courte sur YouTube:

Présentation

J'ai divisé les aspects de ce composant en sections:

  1. Mises en page
  2. Couleur
  3. Saisie de plage personnalisée
  4. Saisie de case à cocher personnalisée
  5. Considérations sur l'accessibilité
  6. JavaScript

Mises en page

Il s'agit de la première démonstration de défi d'interface utilisateur entièrement basée sur la grille CSS. Voici chaque grille mise en évidence à l'aide des Outils pour les développeurs Chrome:

Des contours colorés et des superpositions d'espacement qui permettent de voir toutes les cases qui composent la mise en page des paramètres

Juste pour la coupure

Disposition la plus courante :

foo {
  display: grid;
  gap: var(--something);
}

J'appelle cette mise en page "juste pour l'espace", car elle n'utilise que la grille pour ajouter des espaces entre les blocs.

Cinq mises en page utilisent cette stratégie. Voici toutes les mises en page :

Mises en page de grilles verticales mises en évidence par des contours et des espaces remplis

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

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

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
Traversée de la bordure
.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>.

Centrer le contenu encapsulant

Flexbox et la grille offrent toutes deux des capacités à align-items ou align-content. En cas d'encapsulation d'éléments, les alignements de mise en page content répartissent l'espace entre les enfants en tant que groupe.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
}

L'élément principal utilise le saisies d'alignement place-content: center afin que les enfants soient centrés verticalement et horizontalement dans les mises en page à une et deux colonnes.

Dans la vidéo ci-dessus, vous pouvez voir que le "contenu" reste centré, même si le retour à la ligne a eu lieu.

Répéter l'ajustement automatique minimal

<form> utilise une mise en page en grille adaptative pour chaque section. Cette mise en page passe d'une à deux colonnes en fonction de l'espace disponible.

form {
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
  align-items: flex-start;
  max-width: 89vw;
}

Cette grille a une valeur différente pour row-gap (--space-xl) que pour column-gap (--space-xxl) pour apporter une touche personnalisée à la mise en page responsive. Lorsque les colonnes s'empilent, nous voulons un écart important, mais pas aussi grand que sur un grand écran.

La propriété grid-template-columns utilise trois fonctions CSS : repeat(), minmax() et min(). Una Kravets a écrit un excellent article de blog sur la mise en page à ce sujet, qu'elle appelle RAM.

Notre mise en page comporte trois ajouts particuliers par rapport à celle d'Una :

  • Nous transmettons une fonction min() supplémentaire.
  • Nous spécifions align-items: flex-start.
  • Il existe un style max-width: 89vw.

La fonction min() supplémentaire est bien décrite par Evan Minto sur son blog dans l'article Intrinsically Responsive CSS Grid with minmax() and min(). Je vous recommande de le lire. La correction d'alignement flex-start permet de supprimer l'effet d'étirement par défaut, de sorte que les enfants de cette mise en page n'aient pas besoin d'avoir des hauteurs égales, mais des hauteurs naturelles et intrinsèques. La vidéo YouTube présente brièvement cette fonctionnalité.

max-width: 89vw mérite une petite analyse dans cet article. Je vais vous montrer la mise en page avec et sans le style appliqué :

Que se passe-t-il ? Lorsque max-width est spécifié, il fournit un contexte, un dimensionnement explicite ou un dimensionnement défini à l'algorithme de mise en page auto-fit afin de savoir combien de répétitions il peut tenir dans l'espace. Bien qu'il semble évident que l'espace soit en "pleine largeur", conformément à la spécification de la grille CSS, une taille ou une taille maximale définie doit être indiquée. J'ai fourni une valeur max-size.

Pourquoi 89vw ? Parce que "ça a fonctionné" pour ma mise en page. Avec quelques autres membres de l'équipe Chrome, nous essayons de comprendre pourquoi une valeur plus raisonnable, comme 100vw, n'est pas suffisante et si cela s'agit en fait d'un bug.

Espacement

Une grande partie de l'harmonie de cette mise en page provient d'une palette d'espacement limitée (7 pour être exact).

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

L'utilisation de ces flux est très pratique avec la grille, CSS @nest et la syntaxe de niveau 5 d'@media. Voici un exemple, l'ensemble de styles de mise en page <main> complet.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);

  @media (width >= 540px) {
    & {
      padding: var(--space-lg);
    }
  }

  @media (width >= 800px) {
    & {
      padding: var(--space-xl);
    }
  }
}

Grille avec contenu centré, avec une marge modérée par défaut (comme sur mobile). Toutefois, à mesure que l'espace de la fenêtre d'affichage devient disponible, il se répartit en augmentant la marge intérieure. Le CSS de 2021 est plutôt prometteur !

Vous vous souvenez de la mise en page précédente, « juste pour l'écart » ? Voici une version plus complète de leur apparence dans ce composant :

header {
  display: grid;
  gap: var(--space-xxs);
}

section {
  display: grid;
  gap: var(--space-md);
}

Couleur

L'utilisation contrôlée de la couleur a permis à cette conception de se démarquer comme étant expressive, mais minimaliste. Je procède comme suit :

:root {
  --surface1: lch(10 0 0);
  --surface2: lch(15 0 0);
  --surface3: lch(20 0 0);
  --surface4: lch(25 0 0);

  --text1: lch(95 0 0);
  --text2: lch(75 0 0);
}

Je nomme mes couleurs de surface et de texte avec des nombres plutôt que des noms comme surface-dark et surface-darker, car dans une requête multimédia, je les inverserai, et les couleurs claires et sombres n'auront pas de sens.

Je les inverse dans une requête de médias de préférence comme suit :

:root {
  ...

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --surface2: lch(100 0 0);
      --surface3: lch(98 0 0);
      --surface4: lch(85 0 0);

      --text1: lch(20 0 0);
      --text2: lch(40 0 0);
    }
  }
}

Il est important d'avoir un aperçu rapide de la stratégie et de l'image globale avant de nous plonger dans les détails de la syntaxe des couleurs. Mais comme je suis un peu en avance, laissez-moi revenir en arrière.

LCH?

Sans entrer trop en profondeur dans la théorie des couleurs, la syntaxe LCH est une syntaxe orientée humaine, qui s'adapte à la façon dont nous percevons la couleur, et non à la façon dont nous la mesurons avec les mathématiques (comme 255). Cela présente un avantage distinctif, car les humains peuvent l'écrire plus facilement et les autres humains seront en phase avec ces ajustements.

Capture d&#39;écran de la page Web pod.link/csspodcast, avec l&#39;épisode Color 2: Perception affiché
Découvrez la couleur perceptive (et plus encore) dans le podcast CSS.

Aujourd'hui, dans cette démonstration, concentrons-nous sur la syntaxe et les valeurs que je change pour rendre clair et sombre. Examinons une surface et une couleur de texte:

:root {
  --surface1: lch(10 0 0);
  --text1:    lch(95 0 0);

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --text1:    lch(40 0 0);
    }
  }
}

--surface1: lch(10 0 0) correspond à une luminosité 10%, un chroma de 0 et une teinte de 0: un gris incolore très sombre. Ensuite, dans la requête multimédia pour le mode clair, la luminosité est définie sur 90% avec --surface1: lch(90 0 0);. Et c'est l'essentiel de la stratégie. Commencez par modifier la luminosité entre les deux thèmes, en conservant les rapports de contraste requis par la conception ou ce qui maintient l'accessibilité.

L'avantage de lch() ici est que la légèreté est axée sur l'humain. Nous pouvons donc être satisfaits d'un changement de %, car il sera perçu et cohérent. hsl(), par exemple, n'est pas aussi fiable.

Pour en savoir plus sur les espaces de couleurs et lch(), consultez les ressources supplémentaires. Ça arrive !

Pour le moment, le CSS ne peut pas du tout accéder à ces couleurs. Je répète : Nous n'avons pas accès à un tiers des couleurs de la plupart des écrans modernes. Et ce ne sont pas n'importe quelles couleurs, mais les couleurs les plus vives que l'écran peut afficher. Nos sites Web sont délavés, car le matériel des écrans a évolué plus rapidement que les spécifications CSS et les implémentations de navigateurs.

Lea Verou

Commandes de formulaire adaptatives avec jeu de couleurs

De nombreux navigateurs proposent des commandes de thème sombre, actuellement Safari et Chromium, mais vous devez spécifier dans CSS ou HTML que votre conception les utilise.

L'exemple ci-dessus montre l'effet de la propriété dans le panneau "Styles" de DevTools. La démonstration utilise la balise HTML, qui est généralement un meilleur emplacement, à mon avis :

<meta name="color-scheme" content="dark light">

Pour en savoir plus, consultez cet articlecolor-scheme de Thomas Steiner. Vous pouvez tirer bien plus parti des cases à cocher sombres !

CSS accent-color

Une activité récente a été détectée autour de accent-color sur les éléments du formulaire. Il s'agit d'un style CSS unique capable de modifier la couleur de teinte utilisée dans l'élément de saisie du navigateur. Pour en savoir plus, consultez cette page GitHub. Je l'ai inclus dans mes styles pour ce composant. Comme les navigateurs le prennent en charge, mes cases à cocher seront plus adaptées au thème avec des touches de couleur rose et violet.

input[type="checkbox"] {
  accent-color: var(--brand);
}

Capture d&#39;écran de Chromium sur Linux avec des cases à cocher roses

Créations color pop avec des dégradés fixes et un focus intérieur

Les couleurs ressortent le plus lorsqu'elles sont utilisées avec parcimonie, et j'aime y parvenir grâce à des interactions colorées dans l'interface utilisateur.

La vidéo ci-dessus comporte de nombreuses couches de commentaires et d'interaction de l'interface utilisateur, qui permettent de personnaliser l'interaction en:

  • Mettre en avant le contexte
  • Fournir des commentaires sur l'UI sur le niveau de remplissage de la valeur dans la plage
  • Fournir des commentaires à l'UI indiquant qu'un champ accepte la saisie

Pour fournir des commentaires lorsqu'un élément est utilisé, le CSS utilise la pseudo-classe :focus-within pour modifier l'apparence de divers éléments. Décomposons .fieldset-item, c'est très intéressant :

.fieldset-item {
  ...

  &:focus-within {
    background: var(--surface2);

    & svg {
      fill: white;
    }

    & picture {
      clip-path: circle(50%);
      background: var(--brand-bg-gradient) fixed;
    }
  }
}

Lorsqu'un des enfants de cet élément a le focus :

  1. Une couleur de surface plus contrastée est attribuée à l'arrière-plan .fieldset-item.
  2. Le svg imbriqué est rempli en blanc pour un contraste plus élevé.
  3. Le clip-path <picture> imbriqué se développe en cercle complet et l'arrière-plan est rempli du dégradé fixe lumineux.

Période personnalisée

Étant donné l'élément d'entrée HTML suivant, je vais vous montrer comment j'ai personnalisé son apparence :

<input type="range">

Cet élément se compose de trois parties que nous devons personnaliser :

  1. Élément de plage / conteneur
  2. Track
  3. Pouce

Styles d'élément de plage

input[type="range"] {
  /* style setting variables */
  --track-height: .5ex;
  --track-fill: 0%;
  --thumb-size: 3ex;
  --thumb-offset: -1.25ex;
  --thumb-highlight-size: 0px;

  appearance: none;         /* clear styles, make way for mine */
  display: block;
  inline-size: 100%;        /* fill container */
  margin: 1ex 0;            /* ensure thumb isn't colliding with sibling content */
  background: transparent;  /* bg is in the track */
  outline-offset: 5px;      /* focus styles have space */
}

Les premières lignes de CSS sont les parties personnalisées des styles. J'espère que le libellé clair de ces lignes vous sera utile. Le reste des styles est principalement constitué de styles de réinitialisation, afin de fournir une base cohérente pour créer les parties délicates du composant.

Styles de suivi

input[type="range"]::-webkit-slider-runnable-track {
  appearance: none; /* clear styles, make way for mine */
  block-size: var(--track-height);
  border-radius: 5ex;
  background:
    /* hard stop gradient:
        - half transparent (where colorful fill we be)
        - half dark track fill
        - 1st background image is on top
    */
    linear-gradient(
      to right,
      transparent var(--track-fill),
      var(--surface1) 0%
    ),
    /* colorful fill effect, behind track surface fill */
    var(--brand-bg-gradient) fixed;
}

L&#39;astuce consiste à &quot;révéler&quot; la couleur de remplissage vive. Pour ce faire, utilisez le dégradé d'arrêt dur en haut. Le dégradé est transparent jusqu'au pourcentage de remplissage, puis utilise la couleur de la surface de la piste non remplie. Derrière cette surface non remplie se trouve une couleur pleine largeur, qui attend que la transparence la révèle.

Style de remplissage du tracé

Ma conception nécessite JavaScript pour conserver le style de remplissage. Il n'existe que des stratégies CSS, mais l'élément "Thumb" doit avoir la même hauteur que le titre, et je n'ai pas réussi à trouver une harmonie dans ces limites.

/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')

/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
  const max = slider.getAttribute('max') || 10;
  const percent = slider.value / max * 100;

  return `${parseInt(percent)}%`;
};

/* on page load, set the fill amount */
sliders.forEach(slider => {
  slider.style.setProperty('--track-fill', rangeToPercent(slider));

  /* when a slider changes, update the fill prop */
  slider.addEventListener('input', e => {
    e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
  })
})

Je pense que cela constitue une belle amélioration visuelle. Le curseur fonctionne très bien sans JavaScript. La propriété --track-fill n'est pas nécessaire. S'il n'est pas présent, il n'aura tout simplement pas de style de remplissage. Si JavaScript est disponible, renseignez la propriété personnalisée tout en observant les modifications apportées par l'utilisateur, en synchronisant la propriété personnalisée avec la valeur.

Voici un excellent article sur CSS-Tricks publié par Ana Tudor, qui présente une solution réservée aux CSS pour le remplissage des pistes. J'ai également trouvé cet élément range très inspirant.

Styles de pouce

input[type="range"]::-webkit-slider-thumb {
  appearance: none; /* clear styles, make way for mine */
  cursor: ew-resize; /* cursor style to support drag direction */
  border: 3px solid var(--surface3);
  block-size: var(--thumb-size);
  inline-size: var(--thumb-size);
  margin-top: var(--thumb-offset);
  border-radius: 50%;
  background: var(--brand-bg-gradient) fixed;
}

La plupart de ces styles permettent de créer un cercle bien défini. Vous pouvez à nouveau voir le dégradé d'arrière-plan fixe qui unifie les couleurs dynamiques des miniatures, des pistes et des éléments SVG associés. J'ai séparé les styles pour l'interaction afin d'isoler la technique box-shadow utilisée pour la surbrillance en survol :

@custom-media --motionOK (prefers-reduced-motion: no-preference);

::-webkit-slider-thumb {
  

  /* shadow spread is initally 0 */
  box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);

  /* if motion is OK, transition the box-shadow change */
  @media (--motionOK) {
    & {
      transition: box-shadow .1s ease;
    }
  }

  /* on hover/active state of parent, increase size prop */
  @nest input[type="range"]:is(:hover,:active) & {
    --thumb-highlight-size: 10px;
  }
}

L'objectif était de créer une fonctionnalité visuelle animée et facile à gérer pour les commentaires des utilisateurs. En utilisant une ombre portée, je peux éviter de déclencher la mise en page avec l'effet. Pour ce faire, je crée une ombre qui n'est pas floutée et qui correspond à la forme circulaire de l'élément de curseur. Je modifie ensuite la taille de l'écartement en cas de survol.

Si seulement l'effet de surbrillance était aussi simple sur les cases à cocher…

Sélecteurs multinavigateurs

J'ai constaté que j'avais besoin de ces sélecteurs -webkit- et -moz- pour assurer la cohérence entre les navigateurs :

input[type="range"] {
  &::-webkit-slider-runnable-track {}
  &::-moz-range-track {}
  &::-webkit-slider-thumb {}
  &::-moz-range-thumb {}
}

Case à cocher personnalisée

Étant donné l'élément d'entrée HTML suivant, je vais vous montrer comment j'ai personnalisé son apparence :

<input type="checkbox">

Cet élément se compose de trois parties que nous devons personnaliser :

  1. Élément de case à cocher
  2. Libellés associés
  3. Effet de mise en surbrillance

Élément de case à cocher

input[type="checkbox"] {
  inline-size: var(--space-sm);   /* increase width */
  block-size: var(--space-sm);    /* increase height */
  outline-offset: 5px;            /* focus style enhancement */
  accent-color: var(--brand);     /* tint the input */
  position: relative;             /* prepare for an absolute pseudo element */
  transform-style: preserve-3d;   /* create a 3d z-space stacking context */
  margin: 0;
  cursor: pointer;
}

Les styles transform-style et position préparent le pseudo-élément que nous présenterons plus tard pour styliser le repère. Sinon, ce sont surtout des trucs de style peu avisés de ma part. J'aime que le curseur se transforme en pointeur, j'aime les décalages de contour, les cases à cocher par défaut sont trop petites, et si accent-color est compatible, intégrez ces cases à cocher dans le jeu de couleurs de la marque.

Libellés des cases à cocher

Il est important de fournir des libellés pour les cases à cocher pour deux raisons. La première consiste à représenter l'utilisation de la valeur de la case à cocher pour répondre à la question "Activé ou désactivé pour quoi ?". Deuxièmement, pour l'expérience utilisateur, les utilisateurs Web se sont habitués à interagir avec les cases à cocher via les libellés qui leur sont associés.

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>

Dans votre étiquette, placez un attribut for qui pointe vers une case à cocher par ID : <label for="text-notifications">. Dans votre case à cocher, doublez le nom et l'ID pour vous assurer qu'il est détecté par différents outils et technologies, comme une souris ou un lecteur d'écran : <input type="checkbox" id="text-notifications" name="text-notifications">. :hover, :active et d'autres sont disponibles sans frais avec la connexion, ce qui augmente les façons d'interagir avec votre formulaire.

Mise en surbrillance de la case à cocher

Je souhaite que mes interfaces soient cohérentes. L'élément de curseur présente un joli surlignage de vignette que je voudrais utiliser avec la case à cocher. La miniature a pu utiliser box-shadow et sa propriété spread pour mettre à l'échelle une ombre. Toutefois, cet effet ne fonctionne pas ici, car nos cases à cocher sont, et doivent l'être, carrées.

J'ai réussi à obtenir le même effet visuel avec un pseudo-élément, mais avec une certaine quantité de code CSS délicat:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

input[type="checkbox"]::before {
  --thumb-scale: .01;                        /* initial scale of highlight */
  --thumb-highlight-size: var(--space-xl);

  content: "";
  inline-size: var(--thumb-highlight-size);
  block-size: var(--thumb-highlight-size);
  clip-path: circle(50%);                     /* circle shape */
  position: absolute;                         /* this is why position relative on parent */
  top: 50%;                                   /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
  left: 50%;
  background: var(--thumb-highlight-color);
  transform-origin: center center;            /* goal is a centered scaling circle */
  transform:                                  /* order here matters!! */
    translateX(-50%)                          /* counter balances left: 50% */
    translateY(-50%)                          /* counter balances top: 50% */
    translateZ(-1px)                          /* PUTS IT BEHIND THE CHECKBOX */
    scale(var(--thumb-scale))                 /* value we toggle for animation */
  ;
  will-change: transform;

  @media (--motionOK) {                       /* transition only if motion is OK */
    & {
      transition: transform .2s ease;
    }
  }
}

/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
  --thumb-scale: 1;
}

La création d'un pseudo-élément de cercle est une tâche simple, mais le placer derrière l'élément auquel il est associé a été plus difficile. Voici ce que cela donnait avant et après avoir corrigé le problème :

Il s'agit d'une micro-interaction, mais il est important pour moi de maintenir la cohérence visuelle. La technique de mise à l'échelle de l'animation est la même que celle que nous utilisons ailleurs. Nous définissons une propriété personnalisée sur une nouvelle valeur et laissons le CSS la transférer en fonction des préférences de mouvement. La fonctionnalité clé est translateZ(-1px). Le parent a créé un espace 3D et cet élément enfant pseudo a exploité cet espace en se plaçant légèrement en arrière dans l'espace Z.

Accessibilité

La vidéo YouTube offre une excellente démonstration des interactions de la souris, du clavier et du lecteur d'écran pour ce composant de paramètres. Je vais rappeler certains des détails ici.

Choix d'éléments HTML

<form>
<header>
<fieldset>
<picture>
<label>
<input>

Chacun d'eux contient des conseils et des astuces pour l'outil de navigation de l'utilisateur. Certains éléments fournissent des indices d'interaction, d'autres connectent l'interactivité et d'autres aident à façonner l'arborescence d'accessibilité dans laquelle un lecteur d'écran navigue.

Attributs HTML

Nous pouvons masquer les éléments qui ne sont pas nécessaires aux lecteurs d'écran, dans ce cas l'icône à côté du curseur:

<picture aria-hidden="true">

La vidéo ci-dessus montre le flux du lecteur d'écran sur Mac OS. Notez que le focus de saisie passe directement d'un curseur à l'autre. En effet, nous avons masqué l'icône qui correspondait peut-être à un arrêt avant d'arriver au curseur suivant. Sans cet attribut, l'utilisateur doit s'arrêter, écouter et passer l'image qu'il ne peut pas voir.

Le SVG est un ensemble de calculs. Ajoutons un élément <title> pour un titre libre au survol de la souris et un commentaire lisible par l'humain sur ce que les calculs créent:

<svg viewBox="0 0 24 24">
  <title>A note icon</title>
  <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>

En dehors de cela, nous avons utilisé suffisamment de code HTML clairement marqué pour que les tests du formulaire soient très bons avec la souris, le clavier, les manettes de jeu vidéo et les lecteurs d'écran.

JavaScript

J'ai déjà expliqué comment la couleur de remplissage de la piste était gérée à partir de JavaScript. Examinons maintenant le code JavaScript associé à <form>:

const form = document.querySelector('form');

form.addEventListener('input', event => {
  const formData = Object.fromEntries(new FormData(form));
  console.table(formData);
})

Chaque fois que l'utilisateur interagit avec le formulaire et le modifie, la console le consigne en tant qu'objet dans un tableau pour faciliter son examen avant de l'envoyer à un serveur.

Capture d&#39;écran des résultats de console.table(), où les données du formulaire sont affichées dans un tableau

Conclusion

Maintenant que tu sais comment j'ai fait, comment faire ?! Cela permet d'obtenir une architecture de composants amusante ! Qui va créer la première version avec des emplacements dans son framework préféré ? 🙂

Diversifions nos approches et découvrons toutes les façons de créer sur le Web. Créez une démo, tweetez-moi des liens et je les ajouterai à la section Remix de la communauté ci-dessous.

Remix de la communauté

  • @tomayac pour son style concernant la zone de survol des libellés des cases à cocher. Cette version ne comporte aucun espace de survol entre les éléments: demo et source.