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">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.
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.
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>
<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>
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.
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:
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.
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;
}
![Screenshot, der zeigt, wie das Häkchen
in der ersten Textzeile
in einem mehrzeiligen Zeilenumbruch-Szenario.](https://web.dev/static/articles/building/a-multi-select-component/image/screenshot-showing-the-c-b135285ef7d8a.png?authuser=2&hl=de)
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.
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.
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.