Komponente mit Mehrfachauswahl erstellen

Ein grundlegender Überblick darüber, wie Sie eine responsive, adaptive und barrierefreie Komponente mit Mehrfachauswahl erstellen können, um Nutzerfreundlichkeit zu sortieren und zu filtern.

In diesem Beitrag möchte ich Ihnen zeigen, wie Sie eine Komponente mit Mehrfachauswahl erstellen können. Testen Sie die Demo ansehen.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> Demo

Falls Sie Videos bevorzugen, finden Sie hier eine YouTube-Version dieses Beitrags:

Übersicht

Nutzern werden oft Artikel, manchmal viele Artikel, präsentiert, und in diesen kann es eine gute Idee sein, die Liste zu reduzieren, Auswahlüberlastung. Dieses In diesem Blogpost wird die Benutzeroberfläche zum Filtern von Auswahlmöglichkeiten erläutert. Dies geschieht durch Darstellung von Artikelattributen, die von Nutzenden ausgewählt oder deaktiviert werden können, wodurch die Ergebnisse reduziert werden. und reduziert die Auswahlmöglichkeiten.

Interaktionen

Ziel ist es, einen schnellen Durchlauf der Filteroptionen für alle Nutzer und ihre mit unterschiedlichen Eingabetypen. Dies wird mit einer anpassungsfähigen und responsiven aus zwei Komponenten. Traditionelle Seitenleiste mit Kästchen für Desktop, Tastatur und Screenreadern sowie ein <select multiple> für Touch-Nutzer*innen.

Screenshot des Vergleichs mit hell und dunkel auf Desktops und einer Seitenleiste mit
im Vergleich zu iOS- und Android-Mobilgeräten mit Mehrfachauswahl.

Diese Entscheidung, die integrierte Mehrfachauswahl für Touch-Gesten und nicht für Desktop-Computer zu verwenden, spart Arbeit und schafft Arbeit, aber ich denke, dass wir eine angemessene Nutzererfahrung mit weniger Codeaufwand bieten, als das gesamte responsive Webdesign in einer Komponente zu entwickeln.

Berührung

Die Touch-Komponente spart Platz und verbessert die Nutzerinteraktion auf mobil. Sie spart Platz, indem eine ganze Seitenleiste mit Kästchen zu einem Touchbedienung mit <select>-Overlay. Es hilft bei der Eingabegenauigkeit, ein großes Touch-Overlay, das vom System zur Verfügung gestellt wird.

A
Screenshot-Vorschau der Mehrfachauswahl-Funktion in Chrome auf Android- und iPhone-Geräten
iPad. Auf dem iPad und iPhone ist die Mehrfachauswahl geöffnet und es wird jeweils eine
eine einzigartige Nutzererfahrung,
die für die Bildschirmgröße optimiert ist.

Tastatur und Gamepad

Unten siehst du, wie ein <select multiple> über die Tastatur verwendet wird.

Diese integrierte Mehrfachauswahl kann nicht gestaltet werden und ist nur in einem kompakten Format Layout, das für die Darstellung vieler Optionen nicht geeignet ist. Sie sehen, dass Sie die Vielfalt der Möglichkeiten in diesem winzigen Feld sieht? Die Größe lässt sich zwar ändern, immer noch nicht so nützlich wie eine Seitenleiste mit Kästchen.

Markup

Beide Komponenten sind im selben <form>-Element enthalten. Die Ergebnisse der unabhängig davon, ob es sich dabei um Kästchen oder Mehrfachauswahl handelt, Raster filtern, könnte aber auch an einen Server gesendet werden.

<form>

</form>

Komponente „Kästchen“

Gruppen von Kästchen sollten in einem <fieldset> -Element und mit einem <legend> Wenn HTML so strukturiert ist, können Screenreader und FormData wird automatisch verstehen, in welcher Beziehung die Elemente stehen.

<form>
  <fieldset>
    <legend>New</legend>
    … checkboxes …
  </fieldset>
</form>

Fügen Sie nach der Gruppierung <label> und <input type="checkbox"> für für jeden der Filter. Ich habe mich für einen <div> entschieden, damit die CSS-Eigenschaft gap können Sie gleichmäßige Abstände zwischen ihnen festlegen und die Ausrichtung beibehalten, wenn Beschriftungen mehrere Linien haben.

<form>
  <fieldset>
    <legend>New</legend>
    <div>
      <input type="checkbox" id="last 30 days" name="new" value="last 30 days">
      <label for="last 30 days">Last 30 Days</label>
    </div>
    <div>
      <input type="checkbox" id="last 6 months" name="new" value="last 6 months">
      <label for="last 6 months">Last 6 Months</label>
    </div>
   </fieldset>
</form>

Screenshot mit einem informativen Overlay für die Legende und
  Feldset-Elemente, zeigt die Farbe und den Elementnamen an.

<select multiple>-Komponente

Eine selten verwendete Funktion des <select>-Elements ist multiple Wenn das Attribut mit einem <select>-Element verwendet wird, darf der Nutzer wählen Sie viele aus der Liste aus. Es ist, als würde man die Interaktion aus einer Radioliste ändern, zu einer Kontrollkästchen-Liste hinzufügen.

<form>
  <select multiple="true" title="Filter results by category">
    …
  </select>
</form>

Um Gruppen innerhalb von <select> mit Labels zu versehen und zu erstellen, verwenden Sie die <optgroup> -Element und weisen Sie ihm ein label-Attribut und einen Wert zu. Dieses Element und Attribut entsprechen den Elementen <fieldset> und <legend>.

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      …
    </optgroup>
  </select>
</form>

Fügen Sie jetzt den Parameter <option> Elemente für den Filter.

<form>
  <select multiple="true" title="Filter results by category">
    <optgroup label="New">
      <option value="last 30 days">Last 30 Days</option>
      <option value="last 6 months">Last 6 Months</option>
    </optgroup>
  </select>
</form>

Screenshot des Desktop-Renderings eines Elements mit Mehrfachauswahl.

Eingaben mit Zählern erfassen, um assistive Technologien zu informieren

Der Status Rolle die bei dieser User Experience eingesetzt wird, um die Filter für Screenreader und andere assistive Technologien. Das YouTube-Video die Funktion demonstriert. Die Integration beginnt mit HTML und dem Attribut role="status"

<div role="status" class="sr-only" id="applied-filters"></div>

Dieses Element liest Änderungen am Inhalt vor. Wir können die mit CSS Zähler wenn Nutzende mit den Kästchen interagieren. Dazu müssen wir zunächst eine Zähler mit einem Namen für ein übergeordnetes Element der Eingaben und Zustandselemente.

aside {
  counter-reset: filters;
}

Standardmäßig beträgt die Anzahl 0, was sehr gut ist. Nichts ist :checked in diesem Design als Standard.

Um den neu erstellten Zähler zu erhöhen, zielen wir als Nächstes auf die untergeordneten Elemente <aside>-Element, das :checked ist. Wenn Nutzende den Status der Eingaben ändern, Der filters-Zähler zählt.

aside :checked {
  counter-increment: filters;
}

Das CSS-Team kennt jetzt das allgemeine Ergebnis der Kästchen-UI und die Statusrolle -Element ist leer und wartet auf Werte. Da das Preisvergleichsportal die Anzahl des Gedächtnisses, counter() -Funktion ermöglicht den Zugriff auf den Wert über Pseudo Inhalt des Elements:

aside #applied-filters::before {
  content: counter(filters) " filters ";
}

Im HTML-Code für das Statusrollenelement werden jetzt "2 Filter " angezeigt. zu einem Bildschirm Leser. Das ist ein guter Anfang, aber wir können es besser machen. Ergebnisse, die durch die Filter aktualisiert wurden. Wir erledigen das über JavaScript, was Zähler leisten können.

Screenshot des MacOS-Screenreaders mit der Anzahl der aktiven Filter

Die Begeisterung für das Nest-Team

Der Zähleralgorithmus funktionierte mit CSS nesting-1, da ich alle Logik in einem Block zusammenzufassen. Fühlt sich handlich und zentral zum Lesen und Aktualisieren an

aside {
  counter-reset: filters;

  & :checked {
    counter-increment: filters;
  }

  & #applied-filters::before {
    content: counter(filters) " filters ";
  }
}

Layouts

In diesem Abschnitt werden die Layouts zwischen den beiden Komponenten beschrieben. Die meisten Layout-Stile gelten für die Desktop-Kontrollkästchenkomponente.

Das Formular

Um die Lesbarkeit und Lesbarkeit für Nutzer zu optimieren, wird für das Formular eine maximale mit einer Breite von 30 Zeichen, sodass für jedes Zeichen eine optische Linienbreite festgelegt wird, Filterlabel. Im Formular werden ein Rasterlayout und die Eigenschaft gap verwendet, um Fieldsets zu erstellen.

form {
  display: grid;
  gap: 2ch;
  max-inline-size: 30ch;
}

Das <select>-Element

Die Liste der Labels und Kästchen belegen auf Mobilgeräten zu viel Platz. Daher prüft das Layout, ob das primäre Zeigegerät des Nutzers zu sehen ist, um es zu ändern. die Touchbedienung zu verbessern.

@media (pointer: coarse) {
  select[multiple] {
    display: block;
  }
}

Der Wert coarse gibt an, dass der Nutzer nicht mit mit hoher Präzision über ihr primäres Eingabegerät. Auf einer Mobilgerät befindet, ist der Zeigerwert oft coarse, da die primäre Interaktion ist Touch. Auf einem Desktop-Gerät lautet der Zeigerwert häufig fine. um eine Maus oder ein anderes hochpräzises Eingabegerät anzuschließen.

Feldsätze

Der Standardstil und das Standardlayout einer <fieldset> mit einem <legend> sind eindeutig:

Screenshot der Standardstile für einen Feldsatz und eine Legende.

Normalerweise verwende ich zum Abstand meiner untergeordneten Elemente die Eigenschaft gap, aber die eindeutige Positionierung von <legend> erschwert die Erstellung einer gleichmäßigen Verteilung von Kindern. Anstelle von gap wird das benachbarte gleichgeordnete Element Selector und margin-block-start verwendet werden.

fieldset {
  padding: 2ch;

  & > div + div {
    margin-block-start: 2ch;
  }
}

Dadurch wird der <legend> nicht mehr über das Targeting auf <div> untergeordnete Elemente.

Screenshot mit dem Randabstand zwischen den Eingaben, aber nicht der Legende.

Filterlabel und -kästchen

Als direktes untergeordnetes Element von <fieldset> und innerhalb der maximalen Breite des 30ch, der Labeltext wird möglicherweise umgebrochen, wenn er zu lang ist. Der Zeilenumbruch ist toll, Abstimmungsprobleme zwischen Text und Kästchen nicht. Die Flexbox ist dafür ideal.

fieldset > div {
  display: flex;
  gap: 2ch;
  align-items: baseline;
}
<ph type="x-smartling-placeholder">
</ph> Screenshot, der zeigt, wie das Häkchen
    in der ersten Textzeile
in einem mehrzeiligen Zeilenumbruch-Szenario.
. Spiel mehr in diesem Codepen

Das animierte Raster

Die Layoutanimation wird von Isotope erstellt. A leistungsstarkes Plug-in zum interaktiven Sortieren und Filtern.

JavaScript

JavaScript unterstützt nicht nur die Orchestrierung eines animierten, interaktiven Rasters, wird verwendet, um einige Unschärfe zu polieren.

Nutzereingabe normalisieren

Dieses Design hat ein Formular mit zwei verschiedenen Möglichkeiten, Input zu geben, nicht serialisieren, nicht identisch sind. Mit JavaScript können wir jedoch Normalisieren der Daten.

Screenshot der JavaScript-Konsole der Entwicklertools mit
  das Ziel, normalisierte Datenergebnisse.

Ich habe die Datenstruktur des <select>-Elements an den gruppierten Kästchen ausgerichtet Struktur. Dazu muss ein input Event-Listener zum Element <select> hinzugefügt. selectedOptions zugeordnet sind.

document.querySelector('select').addEventListener('input', event => {
  // make selectedOptions iterable then reduce a new array object
  let selectData = Array.from(event.target.selectedOptions).reduce((data, opt) => {
    // parent optgroup label and option value are added to the reduce aggregator
    data.push([opt.parentElement.label.toLowerCase(), opt.value])
    return data
  }, [])
})

Jetzt können Sie das Formular bedenkenlos senden oder, im Fall dieser Demo, Isotope anweisen. worauf gefiltert werden soll.

Fertigstellen des Statusrollenelements

Das Element ermittelt und meldet die Filteranzahl nur anhand des Kästchens Interaktion, aber ich fand es eine gute Idee, auch die Anzahl der Ergebnisse und achten Sie darauf, dass die <select>-Elementauswahl ebenfalls gezählt wird.

<select> Elementauswahl wird in counter() widergespiegelt

Im Abschnitt „Datennormalisierung“ wurde bereits ein Listener für die Eingabe erstellt. Bei Am Ende dieser Funktion die Anzahl der ausgewählten Filter und die Anzahl der Ergebnisse für diese Filter bekannt. Die Werte können an das Rollenelement des Bundesstaates übergeben werden. wie hier gezeigt.

let statusRoleElement = document.querySelector('#applied-filters')
statusRoleElement.style.counterSet = selectData.length

Die Ergebnisse spiegeln sich im Element role="status" wider

:checked bietet eine integrierte Möglichkeit, die Anzahl der ausgewählten Filter an Statusrollenelement, aber die gefilterte Anzahl der Ergebnisse ist nicht sichtbar. JavaScript kann die Interaktion mit den Kontrollkästchen überwachen und nach dem Filtern der fügen Sie textContent wie das <select>-Element hinzu.

document
  .querySelector('aside form')
  .addEventListener('input', e => {
    // isotope demo code
    let filterResults = IsotopeGrid.getFilteredItemElements().length
    document.querySelector('#applied-filters').textContent = `giving ${filterResults} results`
})

Insgesamt ist mit dieser Arbeit die Bekanntmachung „2 Filter mit 25 Ergebnissen“ abgeschlossen.

Screenshot des macOS-Screenreaders, der Ergebnisse ankündigt

Unsere hervorragende Unterstützungstechnologie wird jetzt allen wie sie mit ihnen interagieren.

Fazit

Jetzt, wo du weißt, wie ich es gemacht habe, wie würdest du... ‽ 🙂

Lassen Sie uns unsere Herangehensweisen diversifizieren und alle Möglichkeiten kennenlernen, wie wir das Web entwickeln können. Erstelle eine Demo, twittere mir Links und ich füge sie hinzu im Abschnitt „Community-Remixe“ weiter unten.

Community-Remixe

Hier gibt es noch nichts zu sehen.