Komponente „Einstellungen“ erstellen

Eine grundlegende Übersicht darüber, wie Sie eine Einstellungskomponente mit Schiebereglern und Kästchen erstellen

In diesem Beitrag möchte ich darüber sprechen, wie man eine Einstellungskomponente für das Web erstellt, die responsiv ist, die Eingabe mehrerer Geräte unterstützt und browserübergreifend funktioniert. Demo ansehen

Demo

Wenn Sie ein Video bevorzugen oder eine UI/UX-Vorschau von unserem Projekt erhalten möchten, finden Sie hier eine kürzere Schritt-für-Schritt-Anleitung auf YouTube:

Überblick

Ich habe die Aspekte dieser Komponente in folgende Abschnitte unterteilt:

  1. Layouts
  2. Farbe
  3. Benutzerdefinierter Bereich
  4. Benutzerdefinierte Kästcheneingabe
  5. Überlegungen zur Barrierefreiheit
  6. JavaScript

Layouts

Dies ist die erste GUI-Challenge-Demo, die ein komplett CSS-Raster ist. Hier sind die einzelnen Raster, die mit den Chrome-Entwicklertools für das Raster hervorgehoben wurden:

Bunte Umrisse und Overlays mit Abstandsabstand, um alle Felder anzuzeigen, aus denen das Einstellungslayout besteht

Nur für eine Pause

Das gängigste Layout:

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

Ich bezeichne dieses Layout als „nur für Lücken“, weil es nur ein Raster verwendet, um Lücken zwischen Blöcken hinzuzufügen.

Diese Strategie wird in fünf Layouts verwendet:

Vertikale Rasterlayouts, die durch Konturen hervorgehoben und Lücken ausgefüllt werden

Das fieldset-Element, das die einzelnen Eingabegruppen (.fieldset-item) enthält, verwendet gap: 1px, um die Haarlinien zwischen den Elementen zu erstellen. Keine schwierige Rahmenlösung!

Ausgefüllte Lücke
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

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

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

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

Natürlicher Rasterumbruch

Das komplexeste Layout war schließlich das Makrolayout, das logische Layoutsystem zwischen <main> und <form>.

Inhaltsumbruch zentrieren

Sowohl die Flexbox als auch das Raster bieten Funktionen für align-items oder align-content. Wenn Elemente zusammengefasst werden, verteilen content-Layoutausrichtungen den Raum unter den untergeordneten Elementen als Gruppe.

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

Das Hauptelement verwendet die Abkürzung „Alignment“ (place-content: center), damit die untergeordneten Elemente in ein- und zweispaltigen Layouts vertikal und horizontal zentriert werden.

Im obigen Video sehen Sie, wie der „Inhalt“ zentriert bleibt, obwohl ein Zeilenumbruch erfolgt ist.

Automatische Mindestanpassung wiederholen

Das <form> verwendet für jeden Abschnitt ein adaptives Rasterlayout. Dieses Layout wechselt je nach verfügbarem Platz von ein in zwei Spalten.

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;
}

Dieses Raster hat einen anderen Wert für row-gap (--space-xl) als column-gap (--space-xxl), um dem responsiven Layout diesen benutzerdefinierten Touch zu verleihen. Wenn die Spalten gestapelt sind, möchten wir eine große Lücke, aber nicht so groß wie auf einem Breitbildbildschirm.

Für die Eigenschaft grid-template-columns werden drei CSS-Funktionen verwendet: repeat(), minmax() und min(). Una Kravets hat dazu einen tollen Blogpost zum Layout, der RAM genannt wird.

Es gibt drei besondere Ergänzungen in unserem Layout, wenn Sie es mit dem von Una vergleichen:

  • Wir übergeben eine zusätzliche min()-Funktion.
  • Wir geben align-items: flex-start an.
  • Es gibt einen max-width: 89vw-Stil.

Die zusätzliche min()-Funktion wird von Evan Minto in seinem Blog im Beitrag Intrinsically Responsive CSS Grid with minmax() and min() beschrieben. Ich empfehle Ihnen, das zu lesen. Durch die Korrektur der flex-start-Ausrichtung wird der standardmäßige Dehnungseffekt entfernt, sodass die untergeordneten Elemente dieses Layouts nicht dieselbe Höhe haben müssen, sondern eine natürliche, unveränderliche Höhe haben können. Im YouTube-Video wird diese Ergänzung kurz beschrieben.

max-width: 89vw möchte ich dir in diesem Beitrag noch einmal genauer ansehen. Hier sehen Sie das Layout mit und ohne angewendeten Stil:

Was ist passiert? Wenn max-width angegeben ist, wird Kontext, explizite Größenangaben oder festgelegte Größenangaben für den auto-fit-Layoutalgorithmus bereitgestellt. So weiß er, wie viele Wiederholungen er in den Bereich passen kann. Auch wenn es offensichtlich erscheint, dass der Bereich "volle Breite" hat, muss gemäß der CSS-Rasterspezifikation eine bestimmte Größe oder maximale Größe angegeben werden. habe ich eine maximale Größe angegeben.

Warum 89vw? Weil „es hat funktioniert“ für mein Layout. Andere Chrome-Nutzer untersuchen, warum ein sinnvollerer Wert wie 100vw nicht ausreicht und ob es sich tatsächlich um einen Fehler handelt.

Abstand

Ein Großteil der Harmonie dieses Layouts geht auf eine begrenzte Palette der Abstände zurück. 7, um genau zu sein.

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

Die Verwendung dieser Abläufe ist sehr gut mit Grid, CSS @nest und Level 5-Syntax von @media. Hier ein Beispiel mit dem vollständigen <main>-Layoutsatz an Stilen.

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);
    }
  }
}

Ein Raster mit zentrierten Inhalten, die standardmäßig mäßige Abstände haben (wie auf Mobilgeräten). Wenn jedoch mehr Platz für den Darstellungsbereich zur Verfügung steht, wird er durch einen höheren Abstand verteilt. Preisvergleichsportal 2021 sieht ziemlich gut aus!

Erinnern Sie sich an das frühere Layout, „nur für Lücken“? Hier ist eine vollständigere Version davon, wie sie in dieser Komponente aussehen:

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

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

Farbe

Durch den kontrollierten Einsatz von Farben stach dieses Design als ausdrucksstark und dennoch minimalistisch heraus. Ich mache das so:

: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);
}

Ich nenne meine Oberflächen- und Textfarben mit Zahlen und nicht mit Namen wie surface-dark und surface-darker, da ich sie in einer Medienabfrage drehe und hell und dunkel keine Bedeutung hat.

Ich drehe sie in einer Bevorzugten Medienabfrage wie dieser:

: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);
    }
  }
}

Bevor wir uns mit den Details zur Farbsyntax befassen, ist es wichtig, einen kurzen Überblick über das Gesamtbild und die Strategie zu erhalten. Aber da ich etwas übertroffen bin, möchte ich ein bisschen weitermachen.

LCH?

LCH ist eine menschenorientierte Syntax, die sich darauf konzentriert, wie wir Farbe wahrnehmen, und nicht, wie wir Farbe mithilfe von Mathematik messen (z. B. 255). Dies hat einen klaren Vorteil, da Menschen sie einfacher schreiben können und andere Menschen auf diese Anpassungen abgestimmt sein können.

Screenshot der Webseite pod.link/csspodcast mit der angezeigten Folge „Farbe 2: Perception“
Weitere Informationen über wahrnehmbare Farbe (und mehr) finden Sie im CSS-Podcast.

In dieser Demo konzentrieren wir uns heute auf die Syntax und die Werte, die ich umdrehe, um hell und dunkel zu machen. Sehen wir uns eine Oberfläche und eine Textfarbe an:

: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) übersetzt die Helligkeit 10%, 0 Chroma und den Farbton 0 – ein sehr dunkles, farbloses Grau. Dann wird in der Medienabfrage für den hellen Modus die Helligkeit mit --surface1: lch(90 0 0); in 90% gestellt. Und das ist der Kern der Strategie. Ändern Sie zuerst die Helligkeit zwischen den beiden Themen und halten Sie die Kontrastverhältnisse bei, die das Design erfordert oder was die Barrierefreiheit aufrechterhalten kann.

Der Vorteil von lch() ist, dass Helligkeit auf Menschen ausgerichtet ist und wir eine gute %-Änderung daran haben können, dass % sich wahrnehmbar und konsistent unterscheidet. hsl() ist beispielsweise nicht so zuverlässig.

Weitere Informationen zu Farbräumen und lch() finden Sie hier. Bald!

CSS kann derzeit überhaupt nicht auf diese Farben zugreifen. Noch einmal: Auf ein Drittel der Farben in den meisten modernen Monitoren haben wir keinen Zugriff. Dies sind nicht einfach beliebige Farben, sondern die leuchtendsten Farben, die auf dem Display angezeigt werden können. Unsere Websites sind blass, da die Monitorhardware schneller entwickelt wurde als CSS-Spezifikationen und Browserimplementierungen.

Lea Verou

Adaptive Formularsteuerelemente mit Farbschema

Viele Browser liefern Steuerelemente für das dunkle Design, derzeit Safari und Chromium. Sie müssen jedoch in CSS oder HTML angeben, dass sie in Ihrem Design verwendet werden.

Im Beispiel oben wird die Wirkung der Eigenschaft aus dem Bereich „Stile“ der Entwicklertools veranschaulicht. In der Demo wird das HTML-Tag verwendet, das meiner Meinung nach im Allgemeinen besser geeignet ist:

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

Weitere Informationen dazu findest du in diesem color-scheme-Artikel von Thomas Steiner. Sie können noch viel mehr nutzen als das dunkle Kästchen eingeben.

Preisvergleichsportal accent-color

Kürzlich gab es in Zusammenhang mit accent-color für Formularelemente eine Aktivität. Das ist ein einzelner CSS-Stil, der die im Eingabeelement des Browsers verwendete Färbung ändern kann. Weitere Informationen dazu finden Sie hier auf GitHub. Ich habe es in meine Stile für diese Komponente aufgenommen. Mit Unterstützung des Browsers werden die Kästchen stärker vom Design gestaltet.

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

Screenshot von Chromium unter Linux mit pinken Kästchen

Farbakzente mit festen Farbverläufen und Fokus im Fokus

Farben kommen am meisten hervor, wenn sie sparsam eingesetzt werden. Eine der Möglichkeiten, die ich gerne erreiche, sind farbenfrohe Interaktionen mit der Benutzeroberfläche.

Im obigen Video gibt es viele Ebenen für Feedback und Interaktionen auf der Benutzeroberfläche, die der Interaktion eine persönliche Note verleihen, indem sie:

  • Kontext hervorheben
  • Es gibt UI-Feedback dazu, wie voll der Wert im Bereich ist.
  • UI-Feedback geben, dass ein Feld Eingaben annimmt.

Um Feedback zu geben, wenn mit einem Element interagiert wird, verwendet CSS die Pseudoklasse :focus-within, um die Darstellung verschiedener Elemente zu ändern. Sehen wir uns .fieldset-item an, das sehr interessant ist:

.fieldset-item {
  ...

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

    & svg {
      fill: white;
    }

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

Wenn eines der untergeordneten Elemente dieses Elements den Fokus innerhalb des folgenden Bereichs hat:

  1. Dem Hintergrund .fieldset-item wird eine Oberflächenfarbe mit höherem Kontrast zugewiesen.
  2. Das verschachtelte svg ist für einen höheren Kontrast weiß gefüllt.
  3. Das verschachtelte <picture>-clip-path wird zu einem vollständigen Kreis erweitert und der Hintergrund wird mit dem hellen festen Farbverlauf gefüllt.

Benutzerdefinierter Zeitraum

Anhand des folgenden HTML-Eingabeelements zeige ich Ihnen, wie ich seine Darstellung angepasst habe:

<input type="range">

Es gibt 3 Teile dieses Elements, die angepasst werden müssen:

  1. Bereichselement / Container
  2. Track
  3. Mag ich

Bereichselementstile

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 */
}

Die ersten CSS-Zeilen sind die benutzerdefinierten Teile der Stile. Ich hoffe, dass die eindeutige Beschriftung bei den Stilen hilfreich ist. Bei den übrigen Stilen handelt es sich hauptsächlich um zurückgesetzte Stile, um eine einheitliche Grundlage für die Erstellung der kniffligen Teile der Komponente zu schaffen.

Track-Stile

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;
}

Der Trick dabei ist, die leuchtende Füllfarbe zu „enthüllen“. Dazu wird der Farbverlauf für den Hardstopp oben verwendet. Der Farbverlauf ist bis zum Füllprozentsatz transparent. Danach wird die Farbe der nicht gefüllten Fahrbahnoberfläche verwendet. Hinter dieser nicht gefüllten Fläche befindet sich eine ganze Breite, die darauf wartet, dass die Transparenz zu sehen ist.

Track-Füllung

Für mein Design ist JavaScript erforderlich, um den Füllstil beizubehalten. Es gibt nur CSS-Strategien, aber das Daumenelement muss dieselbe Höhe wie der Track haben, und ich konnte innerhalb dieser Grenzen keine Harmonie finden.

/* 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));
  })
})

Ich denke, das ist ein tolles visuelles Upgrade. Der Schieberegler funktioniert problemlos auch ohne JavaScript. Das --track-fill-Attribut ist nicht erforderlich. Es hat lediglich keine Füllung, wenn kein Füllstil vorhanden ist. Wenn JavaScript verfügbar ist, füllen Sie die benutzerdefinierte Eigenschaft aus und beobachten Sie gleichzeitig Nutzeränderungen. Synchronisieren Sie dann die benutzerdefinierte Eigenschaft mit dem Wert.

Hier ist ein großartiger Beitrag zu CSS-Tricks von AnaTudor, in dem eine reine CSS-Lösung für die Track-Füllung demonstriert wird. Auch ich fand dieses range-Element sehr inspirierend.

Thumbnail-Stile

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;
}

Die meisten dieser Stile sind das Erstellen eines schönen Kreises. Auch hier sehen Sie wieder den festen Hintergrundverlauf, der die dynamischen Farben der Daumen, Tracks und zugehörigen SVG-Elemente vereinheitlicht. Ich habe die Stile für die Interaktion getrennt, um die box-shadow-Technik zu isolieren, die für die Hervorhebung durch Bewegen des Mauszeigers verwendet wird:

@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;
  }
}

Das Ziel war ein einfach zu verwaltendes und animiertes visuelles Highlight für das Feedback der Nutzenden. Durch die Verwendung eines Boxschattens kann ich verhindern, dass durch diesen Effekt das Layout ausgelöst wird. Dazu erstelle ich einen Schatten, der nicht verschwommen ist und der kreisförmigen Form des Daumenelements entspricht. Dann ändere ich die Streuungsgröße und passe sie an, wenn der Mauszeiger darauf bewegt wird.

Wenn nur der Hervorhebungseffekt so einfach wäre...

Browserübergreifende Auswahl

Ich habe festgestellt, dass ich diese -webkit-- und -moz--Selektoren benötige, um eine browserübergreifende Konsistenz zu erreichen:

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

Benutzerdefiniertes Kästchen

Anhand des folgenden HTML-Eingabeelements zeige ich Ihnen, wie ich seine Darstellung angepasst habe:

<input type="checkbox">

Es gibt 3 Teile dieses Elements, die angepasst werden müssen:

  1. Checkbox-Element
  2. Verknüpfte Labels
  3. Hervorhebungseffekt

Kästchenelement

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;
}

Die Stile transform-style und position bereiten sich auf das Pseudoelement vor, das wir später vorstellen werden, um die Hervorhebung zu gestalten. Ansonsten sind es meine Meinungen eher unwichtig. Ich mag den Cursor als Zeiger, einen Umrissversatz und die Standardkästchen sind zu klein. Wenn accent-color unterstützt wird, fügen Sie diese Kästchen in das Farbschema der Marke ein.

Kästchenlabels

Es ist aus zwei Gründen wichtig, Labels für Kästchen anzugeben. Die erste gibt an, wofür der Kästchenwert verwendet wird, um mit „Für was ein oder aus“ zu antworten. Im Hinblick auf die UX haben sich Webnutzer an die Interaktion mit Kästchen über ihre zugehörigen Labels gewöhnt.

Eingabe
<input
  type="checkbox"
  id="text-notifications"
  name="text-notifications"
>
Label
<label for="text-notifications">
  <h3>Text Messages</h3>
  <small>Get notified about all text messages sent to your device</small>
</label>

Fügen Sie auf Ihrem Label ein for-Attribut hinzu, das nach der ID <label for="text-notifications"> auf ein Kästchen verweist. Doppelte im Kästchen den Namen und die ID an, damit sie mit verschiedenen Tools und Technologien wie einer Maus oder einem Screenreader gefunden werden kann: <input type="checkbox" id="text-notifications" name="text-notifications">. :hover, :active und weitere sind kostenlos in Verbindung mit der Verbindung, sodass Sie mit Ihrem Formular mehr Interaktionsmöglichkeiten haben.

Kästchen hervorheben

Ich möchte meine Oberflächen einheitlich halten. Das Schiebereglerelement hat eine schöne Miniaturansicht, die ich mit dem Kästchen verwenden möchte. Für die Miniaturansicht konnte box-shadow und die Eigenschaft spread verwendet werden, um einen Schatten nach oben und unten zu skalieren. Dieser Effekt funktioniert hier jedoch nicht, da die Kästchen quadratisch sind und sein sollten.

Der gleiche visuelle Effekt konnte ich mit einem Pseudoelement und einer Menge komplizierter CSS erzielen:

@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;
}

Ein kreisförmiges Pseudoelement zu erstellen ist unkompliziert. Es war jedoch schwieriger, es hinter dem Element zu platzieren, mit dem es verbunden ist. Hier ist ein Beispiel, bevor und nachdem ich das Problem behoben habe:

Das ist definitiv eine Mikrointeraktion, aber wichtig für mich, die visuelle Einheitlichkeit zu wahren. Das Verfahren zur Skalierung der Animation ist das gleiche, das wir bereits an anderer Stelle verwendet haben. Wir setzen eine benutzerdefinierte Eigenschaft auf einen neuen Wert und lassen CSS den Übergang basierend auf den Bewegungseinstellungen übernehmen. Das wichtigste Merkmal hier ist translateZ(-1px). Das übergeordnete Element erstellte einen 3D-Raum und das untergeordnete Pseudoelement tippte darauf, indem es sich etwas zurück in den Z-Raum setzte.

Barrierefreiheit

Im YouTube-Video werden die Interaktionen von Maus, Tastatur und Screenreader für diese Einstellungskomponente gut demonstriert. Ich werde hier auf einige der Details eingehen.

HTML-Elementoptionen

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

Dort findest du Hinweise und Tipps für das Browser-Tool des Nutzers. Einige Elemente enthalten Hinweise zur Interaktion, andere verbinden die Interaktivität und beeinflussen den Baum für Barrierefreiheit, den ein Screenreader verwendet.

HTML-Attribute

Elemente, die von Screenreadern nicht benötigt werden, lassen sich ausblenden. Hier ist das Symbol neben dem Schieberegler:

<picture aria-hidden="true">

Das obige Video zeigt den Screenreader-Arbeitsablauf unter Mac OS. Der Eingabefokus bewegt sich direkt von einem Schieberegler zum nächsten. Das liegt daran, dass wir das Symbol auf dem Weg zum nächsten Schieberegler ausgeblendet haben. Ohne dieses Attribut müsste der Nutzer anhalten, zuhören und über das Bild hinausgehen, das er möglicherweise nicht sehen kann.

Die SVG-Datei ist eine Menge mathematischer Elemente. Wir fügen ein <title>-Element hinzu, mit dem ein Titel, der kostenlos über den Mauszeiger bewegt wird, und einen menschenlesbaren Kommentar zur Mathematik hinzugefügt werden können:

<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>

Darüber hinaus haben wir ausreichend deutlich gekennzeichneten HTML-Code verwendet, sodass das Formular sehr gut mit Maus, Tastatur, Controllern von Videospielen und Screenreadern getestet werden kann.

JavaScript

Wie die Track-Füllfarbe über JavaScript verwaltet wird, habe ich bereits besprochen. Sehen wir uns also den JavaScript-Code für <form> an:

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

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

Jedes Mal, wenn mit dem Formular interagiert oder es geändert wird, protokolliert die Konsole das Formular als Objekt in einer Tabelle zur einfachen Überprüfung, bevor es an einen Server gesendet wird.

Screenshot der Ergebnisse von „console.table()“, wobei die Formulardaten in einer Tabelle angezeigt werden

Fazit

Jetzt, wo du weißt, wie ich es gemacht habe, wie würdest du es tun?! So entsteht eine unterhaltsame Component-Architektur! Wer erstellt die erste Version mit Slots in seinem Lieblings-Framework? 🙂

Diversifizieren wir unsere Ansätze und lernen Sie alle Möglichkeiten kennen, wie wir das Web nutzen können. Erstelle eine Demo und twittere mich-Links. Ich füge sie dann unten zum Abschnitt Community-Remixe hinzu.

Community-Remixe

  • @tomayac durch den Stil in Bezug auf den Mauszeigerbereich für die Kästchenlabels. Diese Version hat keine Hover-Lücke zwischen den Elementen: Demo und Quelle.