Zwei Probleme bei der Gestaltung des Details-Elements und wie man sie löst

Avatar of Greg Gibson
Greg Gibson am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

In der nicht allzu fernen Vergangenheit erforderten selbst einfache, Akkordeon-ähnliche Interaktionen JavaScript-Event-Listener oder einige CSS-Tricks. Und je nach verwendeter Lösung konnte die Bearbeitung des zugrunde liegenden HTML kompliziert werden.

Nun, die Elemente <details> und <summary> (die zusammen als ein „Disclosure Widget“ bezeichnet werden) haben die Erstellung und Wartung dieser Komponenten relativ trivial gemacht.

Bei meiner Arbeit verwenden wir sie für Dinge wie häufig gestellte Fragen.

Ziemlich standardmäßiges Frage/Antwort-Format

Es gibt ein paar zu berücksichtigende Probleme

Da die Ein- und Ausklapp-Interaktivität bereits in den HTML-Tags <details> und <summary> integriert ist, können Sie jetzt Disclosure Widgets ohne *jegliches* JavaScript oder CSS erstellen. Aber Sie möchten vielleicht trotzdem etwas. Ungestaltet lassen <details> Disclosure Widgets uns mit zwei Problemen zurück.

Problem 1: Der <summary>-Cursor

Obwohl der Abschnitt <summary> zur Interaktion einlädt, ist der Standardcursor des Elements ein Textauswahl-Icon und nicht der Zeigefinger, den man vielleicht erwartet

Wir erhalten den Textcursor, bevorzugen aber vielleicht den Zeiger, um stattdessen Interaktion anzuzeigen.

Problem 2: Verschachtelte Blockelemente in <summary>

Das Verschachteln eines Block-Level-Elements (z. B. einer Überschrift) innerhalb eines <summary>-Elements verschiebt diesen Inhalt unterhalb des Pfeilmarkers, anstatt ihn inline zu halten

Block-Level-Elemente teilen sich keinen Platz mit dem Summary-Marker.

Die CSS-Reset-Korrektur

Um diese Probleme zu beheben, können wir die folgenden beiden Stile zum Reset-Abschnitt unserer Stylesheets hinzufügen

details summary { 
  cursor: pointer;
}

details summary > * {
  display: inline;
}

Lesen Sie weiter für mehr über jedes Problem und seine jeweilige Lösung.

Ändern des <summary>-Cursorwerts

Wenn Benutzer mit der Maus über ein Element auf einer Seite fahren, möchten wir, dass sie immer einen Cursor sehen, „der die erwartete Benutzerinteraktion mit diesem Element widerspiegelt.“

Wir haben kurz darauf hingewiesen, dass, obwohl <summary>-Elemente interaktiv sind (wie ein Link oder ein Formular-Button), ihr Standard-Cursor nicht der Zeigefinger ist, den wir normalerweise für solche Elemente sehen. Stattdessen erhalten wir den text-Cursor, den wir normalerweise erwarten, wenn wir Text auf einer Seite eingeben oder auswählen.

Um dies zu beheben, ändern Sie den Cursorwert auf pointer

details summary { 
  cursor: pointer;
}

Einige bemerkenswerte Websites beinhalten diese Eigenschaft bereits, wenn sie <details>-Elemente gestalten. Die MDN Web Docs-Seite über das Element selbst tut genau das. GitHub verwendet ebenfalls Disclosure Widgets für bestimmte Elemente, wie z. B. die Aktionen zum Beobachten, Sternen und Forken eines Repos.

GitHub verwendet cursor: pointer für das <summary>-Element seiner Disclosure-Widget-Menüs.

Ich vermute, der Standardwert cursor: text wurde gewählt, um anzuzeigen, dass der Summary-Text (zusammen mit dem Rest des Inhalts eines Disclosure Widgets) vom Benutzer ausgewählt werden kann. Aber in den meisten Fällen halte ich es für wichtiger anzuzeigen, dass das <summary>-Element interaktiv ist.

Summary-Text *ist* weiterhin auswählbar, auch nachdem wir den Cursorwert von text auf pointer geändert haben. Beachten Sie, dass die Änderung des Cursors nur das Erscheinungsbild und nicht die Funktionalität beeinflusst.

Verschachtelte <summary>-Inhalte inline anzeigen

Innerhalb jedes <summary>-Abschnitts der zuvor gezeigten FAQ-Einträge umschließe ich die Frage normalerweise in einem geeigneten Überschriften-Tag (abhängig von der Seitenstruktur)

<details>
  <summary>
    <h3>Will my child's 504 Plan be implemented?</h3>
  </summary>
  <p>Yes. Similar to the Spring, case managers will reach out to students.</p>
</details>

Das Verschachteln einer Überschrift in <summary> kann aus mehreren Gründen hilfreich sein

  • Konsistente visuelle Gestaltung. Ich mag es, wenn meine FAQ-Fragen wie andere Überschriften auf meinen Seiten aussehen.
  • Die Verwendung von Überschriften hält die Seitenstruktur für Benutzer von Internet Explorer und älteren Chromium-Versionen von Edge gültig, die <details>-Elemente nicht unterstützen. (In diesen Browsern ist ein solcher Inhalt immer sichtbar und nicht interaktiv.)
  • Korrekte Überschriften können Benutzern von assistiven Technologien helfen, sich innerhalb von Seiten zu navigieren. (Das gesagt, Überschriften innerhalb von <summary>-Elementen stellen einen besonderen Fall dar, wie unten detailliert erklärt wird. Einige Screenreader interpretieren diese Überschriften als das, was sie sind, andere nicht.)

Überschriften vs. Buttons

Beachten Sie, dass das <summary>-Element ein wenig ungewöhnlich ist. Es verhält sich in vielerlei Hinsicht wie ein Button. Tatsächlich hat es sogar eine implizite ARIA-Zuordnung von role=button. Aber ganz anders als bei Buttons dürfen Überschriften direkt in <summary>-Elemente verschachtelt werden.

Das stellt uns – und Browser- und Assistive-Technology-Entwicklern – vor einen Widerspruch

  • Überschriften sind in <summary>-Elementen erlaubt, um Navigationshilfen auf der Seite bereitzustellen.
  • Buttons entfernen die Semantik aus allem (wie Überschriften), was in ihnen verschachtelt ist.

Leider sind assistive Technologien inkonsistent darin, wie sie diese Situation gehandhabt haben. Einige Screenreader-Technologien, wie NVDA und Apples VoiceOver, erkennen Überschriften in <summary>-Elementen an. JAWS hingegen nicht.

Das bedeutet für uns, dass wir beim Platzieren einer Überschrift in <summary> das Aussehen der Überschrift gestalten *können*. **Aber wir können nicht garantieren, dass unsere Überschrift tatsächlich als Überschrift interpretiert wird!**

Mit anderen Worten, es schadet wahrscheinlich nicht, dort eine Überschrift zu platzieren. Sie mag nur nicht immer helfen.

Alles inline machen

Wenn wir einen Überschriften-Tag (oder ein anderes Block-Element) direkt in unser <summary> einfügen, wollen wir wahrscheinlich dessen display-Stil auf inline ändern. Andernfalls erhalten wir unerwünschte Umbrüche, wie z. B. das Ein-/Ausklapp-Pfeilsymbol, das über der Überschrift anstatt daneben angezeigt wird.

Wir können die folgende CSS verwenden, um einen display-Wert von inline auf jede Überschrift und jedes andere Element anzuwenden, das direkt in <summary> verschachtelt ist.

details summary > * { 
  display: inline;
}

Ein paar Hinweise zu dieser Technik. Erstens empfehle ich die Verwendung von inline und nicht inline-block, da das Problem mit dem Zeilenumbruch auch bei inline-block auftritt, wenn der Überschriftentext über eine Zeile hinausgeht.

Zweitens, anstatt den display-Wert der verschachtelten Elemente zu ändern, sind Sie vielleicht versucht, den Standardwert display: list-item des <summary>-Elements durch display: flex zu ersetzen. Zumindest ich war es! Wenn wir dies jedoch tun, verschwindet der Pfeilmarker. Hoppla!

Bonus-Tipp: Internet Explorer von Ihren Stilen ausschließen

Ich habe bereits erwähnt, dass Internet Explorer und ältere Chromium-Versionen (auch EdgeHTML genannt) von Edge <details>-Elemente nicht unterstützen. Wenn wir also keine Polyfills für diese Browser verwenden, möchten wir vielleicht sicherstellen, dass unsere benutzerdefinierten Disclosure-Widget-Stile für sie nicht angewendet werden. Andernfalls landen wir in einer Situation, in der unser gesamtes Inline-Styling das Element durcheinanderbringt.

Inline <summary>-Überschriften könnten in Internet Explorer und EdgeHTML ungewöhnliche oder unerwünschte Effekte haben.

Außerdem ist das <summary>-Element in diesem Fall nicht mehr interaktiv, was bedeutet, dass der Standardstil text des Cursors besser geeignet ist als pointer.

Wenn wir entscheiden, dass unsere Reset-Stile nur für die entsprechenden Browser gelten sollen, können wir eine Feature-Abfrage hinzufügen, die verhindert, dass IE und EdgeHTML jemals unsere Stile angewendet bekommen. Hier ist, wie wir das mit @supports machen, um eine Funktion zu erkennen, die nur diese Browser unterstützen.

@supports not (-ms-ime-align: auto) {

  details summary { 
    cursor: pointer;
  }

  details summary > * { 
    display: inline;
  }

  /* Plus any other <details>/<summary> styles you want IE to ignore.
}

IE unterstützt Feature-Abfragen tatsächlich überhaupt nicht, daher wird alles im obigen Block ignoriert, was in Ordnung ist! EdgeHTML unterstützt Feature-Abfragen, aber es wird auch nichts innerhalb des Blocks angewendet, da es die einzige Browser-Engine ist, die -ms-ime-align unterstützt.

Die Hauptnebenwirkung hier ist, dass es auch einige ältere Versionen von Chrome (nämlich 12-27) und Safari (macOS- und iOS-Versionen 6-8) gibt, die <details> unterstützen, aber keine Feature-Abfragen unterstützen. Die Verwendung einer Feature-Abfrage bedeutet, dass diese Browser, die etwa 0,06 % der weltweiten Nutzung (Stand Januar 2021) ausmachen, unsere benutzerdefinierten Disclosure-Widget-Stile ebenfalls nicht anwenden.

Die Verwendung eines @supports selector(details)-Blocks anstelle von @supports not (-ms-ime-align: auto) wäre eine ideale Lösung. Aber Selector-Abfragen haben sogar noch weniger Browser-Unterstützung als Property-basierte Feature-Abfragen.

Abschließende Gedanken

Sobald wir unsere HTML-Struktur eingerichtet und unsere beiden CSS-Reset-Stile hinzugefügt haben, können wir all unsere Disclosure Widgets beliebig verschönern. Schon einfache Rand- und Hintergrundfarbstile können für Ästhetik und Benutzerfreundlichkeit viel bewirken. Wissen Sie nur, dass die Anpassung der <summary>-Marker ein wenig kompliziert werden kann!