Native HTML5-Video-Steuerelemente im Vollbildmodus ausblenden

Avatar of Sara Soueidan
Sara Soueidan am

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

Der folgende Text ist ein Gastbeitrag von Sara Soueidan. Ich kenne Sara durch ihre ausgezeichnete Arbeit auf CodePen. Sie arbeitete an benutzerdefinierten HTML5-Video-Steuerelementen und stellte fest, dass die Anpassungen verloren gingen, als das Video in den Vollbildmodus wechselte (Beispiel, wie das passiert). Sara taucht in den Shadow DOM ein und findet eine Lösung...

Wenn Sie jemals mit HTML5-Videos gearbeitet haben, haben Sie sich wahrscheinlich gefragt, wie Sie eine Reihe von Steuerelementen, Schiebereglern und Griffen auf Ihrer Seite erhalten, obwohl Sie nur ein einziges <video>-Tag zum DOM hinzugefügt haben.

Woher kamen all diese Steuerelemente?

Browser fügen diese Steuerelemente als „Unterbaum“ des Video-Tags in die Darstellung des Dokuments ein. Diese Elemente (Schaltflächen, Schieberegler usw.) *sind* Teil des DOM, aber Sie können sie im Haupt-DOM-Baum nicht wirklich sehen, Sie sehen sie nur auf der Seite gerendert. Mehr dazu in Kürze.

Das Problem der HTML5-Video-Steuerelemente im Vollbildmodus

Bei der Arbeit an einem benutzerdefinierten HTML5-Video-Framework stieß ich kürzlich auf ein Problem, auf das viele Designer und Entwickler in diesem Bereich stoßen. Anstatt die benutzerdefinierten Steuerelemente anzuzeigen, die ich entwickelt hatte, erschienen beim Wechsel in den Vollbildmodus die nativen Browser-Steuerelemente. Wie so viele andere suchte ich nach Antworten auf dieses Problem, fand aber keine. (Update: Dieser Bug ist im Chrome-Bugtracker eingereicht).

Nach einiger Inspektion in den Entwicklertools stellte ich fest,

  1. dass die nativen Steuerelemente immer noch da waren. Indem wir das Attribut controls des Video-Elements auf false setzen, können wir die Steuerelemente *ausblenden*, aber aus irgendeinem Grund erscheinen sie beim Eintritt in den Vollbildmodus wieder, obwohl sie im normalen Bildschirmmodus ausgeblendet sind. (Warum?)
  2. Die benutzerdefinierten Steuerelemente waren im Vollbildmodus *unter* dem Video verborgen. Die Inspektion der Steuerelemente mit den Entwicklertools zeigte, dass der Grund, warum die Steuerelemente darunter verborgen waren, darin bestand, dass die Stylesheet des User-Agents (in diesem Fall die Stylesheet von Chrome) die auf die Steuerelemente angewendeten Stile überschrieb, mit einem sehr seltsamen z-index-Wert, muss ich sagen!
Der hohe z-index, der von der User-Agent-Stylesheet von Chrome angewendet wird

Wie machen wir das? Wie verhindern wir, dass die nativen Steuerelemente im Vollbildmodus erscheinen und stattdessen unsere eigenen benutzerdefinierten Steuerelemente anzeigen?

Der zweite Punkt ist einfach: Überschreiben Sie einfach die User-Agent-Stylesheet. Das machen wir ständig in unseren Stylesheets. Dazu kommen wir gleich. Aber was ist mit dem ersten Punkt? Wie können wir Elemente ausblenden, die der Browser hinzufügt, die wir aber nicht im DOM-Baum sehen, mit dem wir arbeiten?

Beachten Sie, dass die in diesem Artikel beschriebene Technik zum Ausblenden der nativen Steuerelemente nur in Browsern funktioniert, die den Shadow DOM unterstützen.

Kurze Einführung in den Shadow DOM

Der vom Browser generierte Unterbaum von DOM-Elementen wird als „Shadow DOM“ bezeichnet. Einfach ausgedrückt handelt es sich um eine Reihe von DOM-Elementen, ähnlich den Ihnen bereits bekannten, wie z. B. <div>s und <span>s, die vom Browser als *Dokumentfragment* hinzugefügt werden und wie der Haupt-DOM-Baum auf der Seite gerendert werden.

James Edwards fasst die Funktion des Shadow DOM perfekt in seinem Artikel für SitePoint zusammen:

Der Shadow DOM kapselt Inhalte, indem er Dokumentfragmente erstellt. Effektiv ist der Inhalt eines Shadow DOM ein *anderes Dokument*, das mit dem Hauptdokument zusammengeführt wird, um die gesamte gerenderte Ausgabe zu erzeugen.

Tatsächlich nutzen einige Browser dies bereits zur Darstellung einiger ihrer nativen Widgets.

Der Grund, warum Browser dies tun, ist, dass Browserentwickler beschlossen haben, einige DOM-Elemente zu kapseln, um sie vor uns Entwicklern zu verbergen, damit wir uns nicht mit den Implementierungsdetails dieser Elemente befassen müssen, um uns die Arbeit zu erleichtern. Wie James Edwards auch in seinem Artikel sagte:

Da er isoliert ist, können Benutzer ihn nicht versehentlich kaputt machen, es gibt keine Möglichkeit für Namenskonflikte mit von Ihnen verwendeten Klassen oder IDs, und das CSS der Hauptseite wirkt sich überhaupt nicht darauf aus.

Wir wissen also jetzt, dass die dem Video-Tag hinzugefügten Steuerelemente nur Teil des vom Browser für dieses Tag generierten Shadow-DOM-Unterbaums sind.

Natives Video-Steuerelemente ausblenden

Wir müssen die Steuerelemente, die Teil des Shadow DOM sind, gestalten können, aber wie machen wir das, wenn die regulären CSS-Selektoren, die wir kennen, nicht auf Shadow DOM-Elemente zugreifen können?

Nachdem ich diesen hervorragenden Einführungsartikel von Dimitri Glazkov gelesen hatte, erfuhr ich, dass es „eine praktische Pseudo-Attribut-Funktionalität gibt, die es Shadow-DOM-Unterbäumen ermöglicht, eine beliebige Pseudo-Element-Kennung mit einem Element im Unterbaum zu verknüpfen.“

Das bedeutet, dass einige Elemente innerhalb des Shadow-DOM-Unterbaums über ihr zugeordnetes Pseudo-Element gestaltet werden können. Das klingt großartig!

Aber wie bestimmen wir, welches Pseudo-Element dem Shadow-DOM-Element zugeordnet ist, das wir gestalten müssen? Einige Elemente sind mehr oder weniger bekannt, wie z. B. das Range-Input-Element, für das in Webkit-Browsern ein Pseudo-Element zur Gestaltung seines Griffs verfügbar ist.

::-webkit-slider-thumb

Firefox bietet ebenfalls zwei Pseudo-Elemente zur Gestaltung von Range-Inputs, seit es diese ab Version 23.0 unterstützt.

::-moz-range-track

und

::-moz-range-thumb

Aber was ist mit anderen weniger bekannten Pseudo-Elementen, die anderen Shadow-DOM-Elementen zugeordnet sind? Welche Pseudo-Elemente sind ihnen zugeordnet? Um das herauszufinden, kommen die Chrome-Entwicklertools zu Hilfe!

Pseudo-Elemente, die Shadow DOM-Elementen zugeordnet sind, ermitteln

Eine der großartigen Funktionen der Chrome-Entwicklertools ist, dass Sie die Shadow-DOM-Unterbäume im Elemente-Panel genauso inspizieren können, wie Sie einen „regulären“ DOM-Baum inspizieren würden. Alles, was Sie tun müssen, ist diese Funktion zu aktivieren:

  1. Gehen Sie zu den Einstellungen der Entwicklertools (indem Sie auf das kleine Zahnrad-Symbol unten rechts in den Entwicklertools klicken)
  2. Aktivieren Sie im Reiter „Allgemein“ die Option „Shadow DOM anzeigen“
  3. Starten Sie die Entwicklertools neu (schließen und wieder öffnen)

Wenn Sie nun das <video>-Element inspizieren, erhalten Sie etwas Ähnliches wie auf dem folgenden Screenshot.

Der dem <video>-Element hinzugefügte Shadow-DOM-Unterbaum, inspiziert mit den Chrome-Entwicklertools, zeigt ein neues #document-fragment

Dann, genauso wie Sie die Stilregeln für jedes HTML-Element erhalten können, wenn Sie es im Elemente-Panel anklicken, können Sie auch die Pseudo-Elemente sehen, die dem Unterbaum des Shadow DOM zugeordnet sind. Ziemlich raffiniert, oder? :)

Das CSS-Panel in den Chrome-Entwicklertools zeigt den Namen des Pseudo-Elements, das dem <div> innerhalb des Shadow-DOM-Unterbaums zugeordnet ist.

Für die Video-Steuerelemente können wir dem Screenshot entnehmen, dass es ein Pseudo-Element namens ::-webkit-media-controls gibt, das, wie der Name schon sagt, Elementen zugeordnet ist, die Medien-Steuerelemente enthalten.

Wenn Sie auf dieses Pseudo-Element display:none !important; setzen, wird das Element im normalen und im Vollbildmodus vollständig ausgeblendet.

::-webkit-media-controls {
  display:none !important;
}

Aber bedenken Sie, dass dieses Pseudo-Element dem äußersten <div> im Unterbaum zugeordnet ist, das Medien-Steuerelemente enthalten wird, *allerlei* Medien-Steuerelemente. Das bedeutet, dass Sie auch die Steuerelemente für dieses Medienelement ausblenden, wenn Sie irgendwo auf der Seite ein <audio>-Element haben.

Wenn Sie also nicht *alle* nativen Medien-Steuerelemente des Browsers ausblenden möchten, müssen Sie angeben, welche Art von Medien-Steuerelementen ausgeblendet werden sollen, nämlich diejenigen, die dem Video-Element zugeordnet sind, und Sie würden sie durch Angabe des „Geltungsbereichs“ für dieses Pseudo-Element ansprechen.

video::-webkit-media-controls {
  display:none !important;
}

Dies blendet die nativen Steuerelemente vollständig aus.

Eine weitere Option ist, dass Sie tiefer in den Unterbaum gehen können, um das Pseudo-Element zu finden, das dem inneren und spezifischeren div zugeordnet ist, das die eigentlichen Steuerelemente enthält: Schaltflächen, Schieberegler usw. und dieses ausblenden.

Wenn wir also eine Ebene tiefer gehen, erhalten wir das Pseudo-Element, das dem inneren div zugeordnet ist.

video::-webkit-media-controls-enclosure {
  display:none !important;
}

Wenn Sie die Eigenschaft display dieses Pseudo-Elements auf none setzen, werden die nativen Steuerelemente im normalen und im Vollbildmodus vollständig ausgeblendet. Sie können auch sehen, dass dieses Pseudo-Element in Bezug auf den Geltungsbereich (das Video-Element) und das ihm zugeordnete div spezifischer ist: das div, das die eigentlichen Steuerelemente „umgibt“.

Und das ist im Grunde alles, was Sie tun müssen, um die nativen Steuerelemente im Vollbildmodus auszublenden. Einfach, oder?

Benutzerdefinierte Video-Steuerelemente anzeigen

Was die benutzerdefinierten Steuerelemente betrifft, so erschienen sie in meiner Demo immer noch nicht, nachdem ich die nativen ausgeblendet hatte, weil, wie Sie im obigen Screenshot gesehen haben, die User-Agent-Stylesheet einen Wert für z-index für den Vollbildmodus hatte.

Der hohe z-index, der von der User-Agent-Stylesheet von Chrome angewendet wird

Ich habe keine Ahnung, warum die Entwickler diesen Wert gewählt haben, aber es könnte daran liegen, dass dieser Wert, wie Nate Volker in seinem Kommentar unten anmerkte, der Maximalwert für eine vorzeichenbehaftete 32-Bit-Ganzzahl ist, was der Datentyp sein könnte, den die Browserentwickler zur Darstellung von Werten für z-index verwenden. Um sicherzustellen, dass die benutzerdefinierten Steuerelemente sichtbar sind, müssen Sie daher den z-index für die benutzerdefinierten Steuerelemente auf diesen Wert oder höher setzen.

Wenn Sie ihn auf 2147483646 setzen, verschwinden die Steuerelemente im Vollbildmodus unter Firefox und manchmal (ein Bug?) unter Chrome. Der z-index für den Steuerelement-Container sollte also >= 2147483647 sein.

.custom-video-controls {
  z-index: 2147483647;
}

Zusammenfassung

Um die nativen Steuerelemente im Vollbildmodus in Browsern, die den Shadow DOM unterstützen, auszublenden, müssen Sie

  1. das Pseudo-Element, das ihnen zugeordnet ist, ansprechen: video::-webkit-media-controls-enclosure, das Sie mithilfe der Chrome-Entwicklertools und der Inspektion des Shadow DOM finden können, und dessen Anzeige auf none setzen, und dann Ihre benutzerdefinierten Steuerelemente anzeigen
  2. den z-index Ihrer benutzerdefinierten Steuerelemente auf einen Wert setzen, der höher ist als der von der User-Agent-Stylesheet bereitgestellte z-index.

Und das ist im Grunde alles!

Demo

Siehe den Pen Custom HTML5 Video Controls in Full Screen von Chris Coyier (@chriscoyier) auf CodePen.

Was ist mit anderen Browsern, die den Shadow DOM nicht unterstützen?

Während der Arbeit habe ich die Ergebnisse auch in Firefox getestet. Das Setzen des z-index auf den oben genannten Wert lässt die benutzerdefinierten Steuerelemente auch im Vollbildmodus von Firefox erscheinen, so dass das Anzeigen der Steuerelemente einfach ist. Aber die Shadow-DOM-Lösung funktioniert nicht, da Firefox sie noch nicht unterstützt, sodass die nativen Steuerelemente im Vollbildmodus auch weiterhin erscheinen.

Man kann durchaus ähnliches Verhalten in anderen Browsern erwarten, die den Shadow DOM nicht unterstützen.

Der einzige Weg, den ich gefunden habe, die nativen Steuerelemente in diesen Browsern auszublenden, ist, die nativen Steuerelemente mit den benutzerdefinierten zu überdecken, indem man einfach einfache und grundlegende CSS-Stile verwendet, die auf den Vollbildmodus abzielen, um die benutzerdefinierten Steuerelemente darüber zu positionieren.
Dies blendet die nativen Steuerelemente aus, hat aber auch eine Einschränkung: Die benutzerdefinierten Steuerelemente können keinen transparenten Hintergrund haben, sonst scheinen die nativen Steuerelemente durch.

Es gibt hier noch eine weitere mögliche Lösung. Herr James Edwards bemerkte in seinem Kommentar unten, dass die nativen Steuerelemente im Vollbildmodus auch auf andere Weise ausgeblendet werden können, ohne den Shadow DOM verwenden zu müssen, indem man den Vollbildmodus auf ein Element anwendet, zum Beispiel ein

, das das Video-Element enthält. Ich habe seine Technik getestet und sie funktionierte in Chrome, und sie funktionierte auch in der neuesten Version von Firefox unter Windows 7, und laut Herrn Edwards sollte sie auch in anderen Browsern funktionieren, die den Vollbildmodus unterstützen.

Weitere Lektüre

Und wenn Sie interessiert sind, können Sie auch sehen, wie Sie die Shadow-DOM-API und HTML <template>s verwenden können, um Ihren eigenen „gekapselten“ Code und HTML-Vorlagen zu erstellen, indem Sie sich diese Präsentation von Peter Gasston über Web Components ansehen, die er auf der diesjährigen CSSConfEU hielt.