Farbe-Inputs: Ein tiefer Einblick in browserübergreifende Unterschiede

Avatar of Ana Tudor
Ana Tudor am

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

In diesem Artikel werden wir uns die Struktur von <input type='color'>-Elementen, Browserinkonsistenzen, warum sie in einem bestimmten Browser so und nicht anders aussehen und wie man dem auf den Grund geht, genauer ansehen. Ein gutes Verständnis dieses Inputs ermöglicht es uns zu beurteilen, ob ein bestimmtes browserübergreifendes Aussehen erzielt werden kann und wie dies mit minimalem Aufwand und Code geschehen kann.

Hier ist genau das, worüber wir sprechen

Aber bevor wir uns damit beschäftigen, müssen wir uns erst mit...

Barrierefreiheitsprobleme!

Wir haben hier ein riesiges Problem: Für diejenigen, die vollständig auf eine Tastatur angewiesen sind, funktioniert dieser Input in Safari und in Firefox unter Windows nicht wie erwartet, aber er funktioniert in Firefox auf Mac und Linux (was ich nur unter Fedora getestet habe, also schreien Sie mich gerne in den Kommentaren an, wenn es bei Ihnen auf einer anderen Distribution nicht funktioniert).

In Firefox unter Windows können wir mit Tab zum Input navigieren, um ihn zu fokussieren, und mit Enter einen Dialog aufrufen… den wir dann nicht mit der Tastatur navigieren können!

Ich habe versucht, mit Tab, Pfeiltasten und jeder anderen verfügbaren Taste auf der Tastatur zu navigieren… nichts! Ich konnte den Dialog zumindest mit dem guten alten Alt + F4 schließen. Später habe ich im Bug-Ticket auf Bugzilla, das ich dafür gefunden habe, auch einen Workaround entdeckt: Alt + Tab zu einem anderen Fenster, dann Alt + Tab zurück und der Picker-Dialog kann mit der Tastatur navigiert werden.

In Safari ist es noch schlimmer. Der Input ist nicht einmal fokussierbar (Bug-Ticket), wenn VoiceOver nicht eingeschaltet ist. Und selbst mit VoiceOver ist das Durchtabben des Dialogs, den die Inputs öffnen, unmöglich.

Wenn Sie <input type='color'> auf einer echten Website verwenden möchten, lassen Sie die Browser bitte wissen, dass dies etwas ist, das gelöst werden muss!

Wie man hineinschaut

In Chrome müssen wir die Entwicklertools aufrufen, zu Einstellungen gehen und im Abschnitt Präferenzen unter Elemente die Option Benutzeragenten-Shadow-DOM anzeigen aktivieren.

So betrachten Sie die Struktur in einem Input in Chrome.

Wenn wir dann zurückkehren, um unser Element zu inspizieren, können wir in seinen Shadow-DOM hineinsehen.

In Firefox müssen wir about:config aufrufen und sicherstellen, dass das Flag devtools.inspector.showAllAnonymousContent auf true gesetzt ist.

So betrachten Sie die Struktur in einem Input in Firefox.

Dann schließen wir die Entwicklertools, und wenn wir unseren Input erneut inspizieren, können wir hineinsehen.

Leider scheinen wir für das vor-Chromium-Edge keine Option dafür zu haben.

Die Struktur im Inneren

Die in den Entwicklertools aufgedeckte Struktur unterscheidet sich von Browser zu Browser, genau wie bei Range-Inputs.

In Chrome haben wir am oberen Rand des Shadow-DOM ein <div>-Wrapper, auf den wir mit ::-webkit-color-swatch-wrapper zugreifen können.

Im Inneren befindet sich ein weiteres <div>, auf das wir mit ::-webkit-color-swatch zugreifen können.

Screenshot der Chrome DevTools, der das Shadow-DOM des <input type='color' data-recalc-dims= zeigt. Ganz oben haben wir ein Div, das der Swatch-Wrapper ist und über ::-webkit-color-swatch-wrapper angesprochen werden kann. Darin befindet sich ein weiteres Div, das der Swatch ist und über ::-webkit-color-swatch angesprochen werden kann. Dieses Div hat die background-color auf den Wert des übergeordneten Farbeingangs gesetzt.
Innere Struktur in Chrome.

In Firefox sehen wir nur ein <div>, aber es ist nicht beschriftet, also wie greifen wir darauf zu?

Aus einer Vermutung heraus, da dieses <div> die background-color auf das value-Attribut des Inputs gesetzt hat, genau wie die ::-webkit-color-swatch-Komponente, habe ich ::-moz-color-swatch ausprobiert. Und es stellt sich heraus, dass es funktioniert!

Screenshot der Firefox DevTools, der zeigt, was sich in einem <input type='color' data-recalc-dims= befindet. Im Gegensatz zu Chrome haben wir hier nur ein Div, das der Swatch ist und über ::-moz-color-swatch angesprochen werden kann. Dieses Div hat die background-color auf den Wert des übergeordneten Farbeingangs gesetzt.
Innere Struktur in Firefox.

Später erfuhr ich jedoch, dass es eine bessere Möglichkeit gibt, dies für Firefox herauszufinden!

Wir können in die Firefox DevTools-Einstellungen gehen und im Abschnitt Inspector sicherstellen, dass die Option "Browserstile anzeigen" aktiviert ist. Dann gehen wir zurück zum Inspector und wählen dieses <div> in unserem <input type='color'> aus. Unter den Benutzeragenten-Stilen sehen wir eine Regel für input[type='color']::-moz-color-swatch!

Animiertes GIF. Zeigt, wie man die angewendeten Benutzeragenten-Stile in Firefox DevTools aktiviert: Einstellungen data-recalc-dims= Inspector > aktivieren Sie das Kontrollkästchen Browserstile anzeigen.
Browserstile in Firefox DevTools aktivieren.

Im vor-Chromium-Edge können wir nicht einmal sehen, welche Art von Struktur wir im Inneren haben. Ich habe ::-ms-color-swatch ausprobiert, aber es hat nicht funktioniert, und ::-ms-swatch auch nicht (was ich in Betracht gezogen habe, denn für ein input type='range' haben wir ::-webkit-slider-thumb und ::-moz-range-thumb, aber nur ::-ms-thumb).

Nach langem Suchen fand ich nur dieses Problem von 2016. Der vor-Chromium-Edge erlaubt es uns offenbar nicht, das Innere dieses Inputs zu stylen. Nun, das ist ein Dämpfer.

Wie man sich die Browserstile ansieht

In allen Browsern haben wir die Möglichkeit, keine eigenen Stile anzuwenden und uns dann die berechneten Stile anzusehen.

In Chrome und Firefox können wir auch die Benutzeragenten-Stylesheet-Regelsätze sehen, die das aktuell ausgewählte Element beeinflussen (obwohl wir dies in Firefox explizit aktivieren müssen, wie im vorherigen Abschnitt gezeigt).

Screenshot-Collage der Chrome DevTools und Firefox DevTools, die zeigen, wo man nach Benutzeragenten-Stilen sucht: Elemente data-recalc-dims= Stile in Chrome und Inspector > Stile in Firefox.
Browserstile in Chrome und Firefox überprüfen.

Dies ist oft hilfreicher als die berechneten Stile, aber es gibt Ausnahmen und wir sollten die berechneten Werte immer noch überprüfen.

In Firefox können wir auch die CSS-Datei für die form-Elemente unter view-source:resource://gre-resources/forms.css sehen.

Screenshot showing view-source:resource://gre-resources/forms.css open in Firefox to allow us seeing user agent styles for form elements.
Browserstile in Firefox überprüfen.

Das Input-Element selbst

Wir werden uns nun die Standardwerte einiger Eigenschaften in verschiedenen Browsern ansehen, um ein klares Bild davon zu bekommen, was wir tatsächlich explizit setzen müssten, um ein benutzerdefiniertes browserübergreifendes Ergebnis zu erzielen.

Die erste Eigenschaft, die ich bei <input>-Elementen immer zu überprüfen denke, ist box-sizing. Der Anfangswert dieser Eigenschaft ist border-box in Firefox, aber content-box in Chrome und Edge.

Comparative screenshots of DevTools in the three browsers showing the computed values of box-sizing for the actual input.
Die box-sizing-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Wir sehen, dass Firefox es auf border-box für <input type='color'> setzt, aber es sieht so aus, als ob Chrome es gar nicht setzt, so dass es beim Anfangswert von content-box bleibt (und ich vermute, dass dasselbe für Edge gilt).

Auf jeden Fall bedeutet das alles, dass wir, wenn wir einen border oder padding auf diesem Element haben wollen, auch box-sizing explizit setzen müssen, damit wir ein konsistentes Ergebnis über alle diese Browser hinweg erzielen.

Der Wert der font-Eigenschaft ist in jedem Browser anders, aber da wir keinen Text in diesem Input haben, ist alles, was uns wirklich interessiert, die font-size, die über alle von mir geprüften Browser hinweg konsistent ist: 13.33(33)px. Dies ist ein Wert, der wirklich so aussieht, als käme er von der Division von 40px durch 3, zumindest in Chrome.

Comparative screenshots of DevTools in the three browsers showing the font values for the actual input.
Die font-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Dies ist eine Situation, in der die berechneten Stile für Firefox nützlicher sind, denn wenn wir uns die Browserstile ansehen, erhalten wir nicht viele nützliche Informationen.

Screenshot of what we get if we look at the browser styles where the font was set for Firefox. The value for the font is -moz-field, which is an alias for the look of a native text field. Expanding this to check the longhands shows us empty instead of actual values.
Manchmal sind die Browserstile ziemlich nutzlos (Firefox-Screenshot).

Der margin ist ebenfalls über alle diese Browser hinweg konsistent und berechnet sich zu 0.

Comparative screenshots of DevTools in the three browsers showing the margin values for the actual input.
Die margin-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Der border ist für jeden einzelnen Browser anders. Sowohl in Chrome als auch in Edge haben wir einen solid 1px-Rahmen, aber die border-color ist anders (rgb(169, 169, 169) für Chrome und rgb(112, 112, 112) für Edge). In Firefox ist der border ein outset 2px, mit einer border-color von… ThreeDLightShadow?!

Comparative screenshots of DevTools in the three browsers showing the border values for the actual input.
Die border-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Was hat es mit ThreeDLightShadow auf sich? Wenn es Ihnen nicht vertraut vorkommt, keine Sorge! Es ist ein (jetzt veralteter) CSS2-Systemwert, der mir in Firefox unter Windows im Tab Computed Stile als rgb(227, 227, 227) angezeigt wird.

Screenshot of Computed panel search in Firefox on Windows, showing that the ThreeDLightShadow keyword computes to rgb(227, 227, 227).
Berechnete border-color für <input type='color'> in Firefox unter Windows.

Beachten Sie, dass unter Windows in Firefox (zumindest unter Windows) die Zoomstufe des Betriebssystems (EinstellungenSystemAnzeigeGröße von Text, Apps und anderen Elementen ändern) den berechneten Wert von border-width beeinflusst, auch wenn dies bei keiner anderen Eigenschaft, die ich geprüft habe, der Fall zu sein scheint und teilweise mit dem border-style zusammenhängt.

Screenshot showing the Windows display settings window with the zoom level options dropdown opened.
Zoomstufenoptionen unter Windows.

Das Seltsamste sind die berechneten border-width-Werte für verschiedene Zoomstufen, die keinen Sinn zu ergeben scheinen. Wenn wir den ursprünglichen border-style: outset beibehalten, haben wir

  • 1,6px für 125 %
  • 2px für 150 %
  • 1,7px für 175 %
  • 1,5px für 200 %
  • 1,8px für 225 %
  • 1,6px für 250 %
  • 1,66667px für 300 %

Wenn wir border-style: solid setzen, erhalten wir eine berechnete border-width von 2px, genau wie sie gesetzt wurde, für Zoomwerte, die ein Vielfaches von 50 % sind, und die gleichen berechneten Werte wie für border-style: outset für alle anderen Zoomstufen.

Das padding ist bei Chrome und Edge gleich (1px 2px), während Firefox wieder die Ausnahme ist.

Comparative screenshots of DevTools in the three browsers showing the padding values for the actual input.
Die padding-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Es mag so aussehen, als sei der Firefox padding 1px. Das ist so eingestellt und es gibt keinen Hinweis darauf, dass etwas überschrieben wird – wenn eine Eigenschaft überschrieben wird, wird sie grau und durchgestrichen angezeigt.

Screenshot of Firefox DevTools highlighting how the border set on input[type='color'] overrides the one set on input and the look (grey + strike-through) of overridden properties.
Überschreibungen in Firefox erkennen.

Aber der berechnete Wert ist tatsächlich 0 8px! Außerdem ist dies ein Wert, der nicht von der Zoomstufe des Betriebssystems abhängt. Was zum Teufel ist hier los?!

Screenshot der Firefox DevTools, der zeigt, wie der berechnete Padding-Wert bei <input type='color' data-recalc-dims= nicht der ist, der für das Input gesetzt wurde, obwohl keine Überschreibung zu erfolgen scheint.
Berechneter Wert für padding in Firefox entspricht nicht dem Wert, der für das Input gesetzt wurde.

Wenn Sie tatsächlich versucht haben, ein Farbfeld zu inspizieren, sich die Stile genau angesehen haben und Ihr Gehirn anders funktioniert als meines (d.h. Sie lesen, was vor Ihnen liegt, und scannen nicht nur nach dem einen Ding, das Sie interessiert, und ignorieren alles andere …), dann haben Sie wahrscheinlich bemerkt, dass es etwas gibt, das das 1px-Padding überschreibt (und markiert sein sollte) — das flussrelative Padding!

Screenshot of Firefox DevTools showing the flow-relative padding overriding the old padding due to higher specificity of selector (input[type='color'] vs. input).
Flussrelative padding-Überschreibungen in Firefox.

Verdammt, wer hätte gedacht, dass diese Eigenschaften mit vielen Buchstaben tatsächlich relevant sind? Danke an Zoltan, dass er es bemerkt und mir Bescheid gegeben hat. Sonst hätte es mich wahrscheinlich noch zwei Tage gekostet, das herauszufinden.

Das wirft die Frage auf, ob die gleiche Art von Überschreibung nicht auch in anderen Browsern und/oder für andere Eigenschaften auftreten könnte.

Edge unterstützt keine CSS Logical Properties, also lautet die Antwort in dieser Ecke "Nein".

In Chrome werden keine der logischen Eigenschaften für margin, border oder padding explizit für <input type='color'> gesetzt, daher gibt es keine Überschreibung.

In Bezug auf andere Eigenschaften in Firefox hätten wir uns in der gleichen Situation für margin oder border befinden können, aber bei diesen beiden ist es nur so, dass die flussrelativen Eigenschaften für unser Input nicht explizit gesetzt wurden, so dass es wieder keine Überschreibung gibt.

Dennoch ist das definitiv etwas, auf das man in Zukunft achten sollte!

Wenn wir zu den Abmessungen übergehen, ist die width unseres Inputs in Chrome und Edge 44px und in Firefox 64px.

Comparative screenshots of DevTools in the three browsers showing the width values for the actual input.
Die width-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Seine height ist in allen drei Browsern 23px.

Comparative screenshots of DevTools in the three browsers showing the height values for the actual input.
Die height-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Beachten Sie, dass bei Chrome und Edge mit box-sizing von content-box ihre width- und height-Werte padding oder border nicht enthalten. Da Firefox jedoch box-sizing auf border-box gesetzt hat, enthalten seine Abmessungen padding und border.

Comparative screenshots of DevTools in the three browsers showing the layout boxes.
Die Layout-Boxen für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Das bedeutet, dass die content-box in Chrome und Edge 44pxx23px und in Firefox 44pxx19px beträgt, die padding-box in Chrome und Edge 48pxx25px und in Firefox 60pxx19px und die border-box in Chrome und Edge 50pxx27px und in Firefox 64pxx23px beträgt.

Wir können deutlich sehen, wie die Abmessungen in Chrome festgelegt wurden, und ich würde vermuten, dass sie in Edge auf die gleiche direkte Weise festgelegt wurden, auch wenn Edge es uns nicht erlaubt, diese Dinge zu verfolgen. Firefox zeigt diese Abmessungen nicht als explizit festgelegt an und erlaubt uns nicht einmal, zu verfolgen, woher sie stammen (wie es beispielsweise bei anderen Eigenschaften wie border der Fall ist). Aber wenn wir uns alle Stile ansehen, die auf input[type='color'] angewendet wurden, stellen wir fest, dass die Abmessungen als flussrelative Stile festgelegt wurden (inline-size und block-size).

Screenshot of the Firefox user agent styles showing flow relative dimensions being set on input[type='color'].
Wie die Abmessungen von <input type='color'> in Firefox festgelegt wurden.

Die letzte Eigenschaft, die wir für den normalen Zustand des eigentlichen Inputs prüfen, ist background. Hier hat Edge als einziger Browser eine background-image (gesetzt auf einen Gradienten von oben nach unten), während Chrome und Firefox beide eine background-color haben, die auf ButtonFace (ein weiterer veralteter CSS2-Systemwert) gesetzt ist. Das Seltsame ist, dass dies rgb(240, 240, 240) sein sollte (gemäß dieser Ressource), aber sein berechneter Wert in Chrome ist rgb(221, 221, 221).

Comparative screenshots of DevTools in the three browsers showing the background values for the actual input.
Die background-Werte für <input type='color'> im Vergleich in Chrome, Firefox und Edge (von oben nach unten).

Was noch seltsamer ist, ist, dass, wenn wir uns unseren Input in Chrome tatsächlich ansehen, er tatsächlich einen Gradienten-background zu haben scheint! Wenn wir ihn screenshoten und dann einen Picker verwenden, erhalten wir, dass er einen von oben nach unten gerichteten Gradienten von #f8f8f8 bis #ddd hat.

Screenshot of the input in Chrome. A very light, almost white, grey to another light, but still darker grey gradient from top to bottom can be seen as the background, not the solid background-color indicated by DevTools.
Wie der eigentliche Input in Chrome aussieht. Er scheint einen Gradienten zu haben, obwohl die Informationen in den DevTools uns sagen, dass dies nicht der Fall ist.

Beachten Sie auch, dass das Ändern von nur der background-color (oder einer anderen Eigenschaft, die nichts mit den Abmessungen zu tun hat, wie border-radius) in Edge auch die background-image, background-origin, border-color oder border-style ändert.

Animated gif. Shows the background-image, background-origin, border-color, border-style before and after changing the seemingly unrelated background-color - their values don't get preserved following this change.
Edge: Nebenwirkungen der Änderung von background-color.

Andere Zustände

Wir können uns die Stile ansehen, die für eine Reihe von anderen Zuständen eines Elements gelten, indem wir auf die Schaltfläche :hov im Bedienfeld Styles für Chrome und Firefox und auf die Schaltfläche a: im gleichen Styles-Bedienfeld für Edge klicken. Dies öffnet einen Abschnitt, in dem wir die gewünschten Zustände auswählen können.

Screenshot collage highlighting the buttons that bring up the states panel in Chrome, Firefox and Edge.
So sehen Sie sich andere Zustände in Chrome, Firefox, Edge an (von oben nach unten).

Beachten Sie, dass das Auswählen einer Klasse in Firefox nur die Benutzerstile auf dem ausgewählten Element visuell anwendet, nicht die Browserstile. Wenn wir also beispielsweise :hover auswählen, sehen wir nicht die :hover-Stile, die auf unser Element angewendet werden. Wir können jedoch die Benutzeragenten-Stile sehen, die mit dem ausgewählten Zustand für unser ausgewähltes Element in den DevTools übereinstimmen.

Außerdem können wir nicht alle Zustände auf diese Weise testen, und fangen wir mit einem solchen Zustand an.

:disabled

Um zu sehen, wie sich die Stile in diesem Zustand ändern, müssen wir unserem <input type='color'>-Element manuell das disabled-Attribut hinzufügen.

Hmm… es ändert sich nicht viel in irgendeinem Browser!

In Chrome sehen wir, dass die background-color leicht anders ist (rgb(235, 235, 228) im Zustand :disabled gegenüber rgb(221, 221, 221) im normalen Zustand).

Chrome DevTools screenshot showing the background being set to rgb(235, 235, 228) for a :disabled input.
Chrome :disabled-Styling.

Aber der Unterschied ist nur deutlich, wenn man die Informationen in den DevTools betrachtet. Visuell kann ich erkennen, dass es einen leichten Unterschied zwischen einem Input gibt, der :disabled ist, und einem, der es nicht ist, wenn sie nebeneinander liegen, aber wenn ich es nicht vorher gewusst hätte, könnte ich nicht sagen, welcher welcher ist, wenn ich nur einen sehen würde, und wenn ich nur einen sehen würde, könnte ich nicht sagen, ob er aktiviert ist oder nicht, ohne darauf zu klicken.

Disabled and enabled input side by side in Chrome. There is a slight difference in background-color, but it's pretty much impossible to tell which is which just by looking at them.
Deaktiviert (links) vs. aktiviert (rechts) <input type='color'> in Chrome.

In Firefox haben wir die gleichen Werte für den Zustand :disabled wie für den normalen Zustand (außer dem Cursor, der realistischerweise keine unterschiedlichen Ergebnisse liefert, außer in Ausnahmefällen). Was ist los, Firefox?!

Vergleich der in Firefox für <input type='color' data-recalc-dims= in seinem normalen Zustand und seinem :disabled-Zustand gesetzten Stile. Der Padding und der Border, die im :disabled-Fall gesetzt sind, sind genau die gleichen wie im normalen Fall.
Firefox :disabled (oben) vs. normal (unten) Styling.

In Edge sind sowohl die border-color als auch der background-Gradient unterschiedlich.

Chrome DevTools screenshot showing border-color and the background-image being set to slightly different values for a :disabled input.
Edge :disabled-Styling (durch Überprüfung der berechneten Stile).

Wir haben die folgenden Stile für den Normalzustand

border-color: rgb(112, 112, 112);
background-image: linear-gradient(rgb(236, 236, 236), rgb(213, 213, 213));

Und für den :disabled-Zustand

border-color: rgb(186, 186, 186);
background-image: linear-gradient(rgb(237, 237, 237), rgb(229, 229, 229));

Klar unterschiedlich, wenn man sich den Code ansieht, und visuell besser als Chrome, obwohl es immer noch nicht ganz ausreicht.

Disabled and enabled input side by side in Edge. There is a slight difference in background-image and a bigger difference in border-color, but it still may be difficult to tell whether an input is enabled or not at first sight without having a reference to compare.
Deaktiviert (links) vs. aktiviert (rechts) <input type='color'> in Edge.
:focus

Dies ist ein Zustand, den wir testen können, indem wir die DevTools-Pseudoklassen umschalten. Naja, theoretisch. In der Praxis hilft uns das nicht in allen Browsern.

Beginnend mit Chrome können wir sehen, dass wir in diesem Zustand eine outline haben und die outline-color sich zu rgb(77, 144, 254) berechnet, was eine Art Blau ist.

Screenshot der Chrome DevTools, der eine Umrandung für einen Input zeigt, der :focus hat. data-recalc-dims=.
Chrome :focus-Styling.

Ziemlich unkompliziert und leicht zu erkennen.

Weiter geht es mit Firefox, wo die Dinge haarig werden! Im Gegensatz zu Chrome bewirkt das Umschalten der :focus-Pseudoklasse in den DevTools nichts für das Input-Element, aber durch das Fokussieren (durch Klicken mit der Tab-Taste) wird der border blau und wir erhalten ein dotted-Rechteck darin – aber es gibt keine Angabe in den DevTools, was passiert.

Animated gif. Shows how, on :focus, our input gets a blue border and a dark inner dotted rectangle.
Was passiert in Firefox, wenn man mit der Tab-Taste zu unserem Input geht, um ihn zu :focusen.

Wenn wir die forms.css von Firefox prüfen, finden wir eine Erklärung für das gepunktete Rechteck. Dies ist der gepunktete border eines Pseudo-Elements, ::-moz-focus-inner (ein Pseudo-Element, das aus irgendeinem Grund in den DevTools nicht in unserem Input als ::-moz-color-swatch angezeigt wird). Dieser border ist anfangs transparent und wird dann sichtbar, wenn der Input fokussiert wird – die hier verwendete Pseudoklasse (:-moz-focusring) ist praktisch eine alte Firefox-Version des neuen Standards (:focus-visible), der derzeit nur von Chrome hinter dem Flag Experimentelle Webplattform-Features unterstützt wird.

Firefox DevTools screenshot where the inner dotted rectangle on :focus comes from: it is set as a transparent border on the ::-moz-focus-inner pseudo-element and it becomes visible when the input should have a noticeable :focus indicator.
Firefox: Woher kommt das innere gepunktete Rechteck bei :focus.

Was ist mit dem blauen border? Nun, es scheint, dass dieser nicht durch ein Stylesheet, sondern auf OS-Ebene gesetzt wird. Die gute Nachricht ist, dass wir all diese Stile überschreiben können, wenn wir uns dazu entscheiden.

In Edge stehen wir vor einer ähnlichen Situation. Wenn wir die Pseudoklasse :focus in den DevTools umschalten, passiert nichts, aber wenn wir tatsächlich mit der Tab-Taste zu unserem Input gehen, um ihn zu fokussieren, sehen wir ein inneres gepunktetes Rechteck.

Animated gif. Shows how, on :focus, our input gets an inner dotted rectangle.
Was passiert in Edge, wenn man mit der Tab-Taste zu unserem Input geht, um ihn zu :focusen.

Obwohl ich keine Möglichkeit habe, es sicher zu wissen, vermute ich, dass dies, genau wie in Firefox, auf ein Pseudo-Element zurückzuführen ist, das bei :focus sichtbar wird.

:hover

In Chrome deckt das Umschalten dieser Pseudoklasse keine :hover-spezifischen Stile in den DevTools auf. Außerdem scheint das tatsächliche Überfahren des Inputs visuell nichts zu verändern. Es sieht also so aus, als ob Chrome wirklich keine :hover-spezifischen Stile hat?

In Firefox deckt das Umschalten der :hover-Pseudoklasse in den DevTools eine neue Regel im Styles-Bedienfeld auf

Screenshot of Firefox DevTools showing the rule set that shows up for the :hover state.
Firefox :hover-Styling wie in den DevTools zu sehen.

Beim tatsächlichen Überfahren des Inputs wird der background hellblau und der border blau. Der erste Gedanke wäre also, dass hellblau der Wert von -moz-buttonhoverface ist und dass der blaue border wieder auf OS-Ebene gesetzt wird, genau wie im :focus-Fall.

Animiertes GIF. Zeigt, dass bei tatsächlichem Überfahren unseres <input type='color' data-recalc-dims= es einen hellblauen Hintergrund und einen blauen Rand erhält.
Was tatsächlich in Firefox bei :hover passiert.

Wenn wir uns jedoch die berechneten Stile ansehen, sehen wir den gleichen background wie im Normalzustand. Dieser blaue background wird also wahrscheinlich auch auf OS-Ebene gesetzt, obwohl die Regel im Stylesheet forms.css vorhanden ist.

Screenshot of Firefox DevTools showing the computed value for background-color in the :hover state.
Firefox: berechnete background-color eines <input type='color'> bei :hover.

In Edge gibt uns das Umschalten der :hover-Pseudoklasse in den DevTools dem Input einen hellblauen (rgb(166, 244, 255)) background und einen blauen (rgb(38, 160, 218)) border, deren genauen Werte wir im Tab Computed finden können.

Screenshot of Edge DevTools showing the computed value for background-color and border-color in the :hover state.
Edge: berechnete background-color und border-color eines <input type='color'> bei :hover.
:active

Das Überprüfen des :active-Zustands in den Chrome DevTools ändert visuell nichts und zeigt keine spezifischen Regeln im Styles-Bedienfeld an. Wenn wir jedoch tatsächlich auf unseren Input klicken, sehen wir, dass der background-Gradient, der im Normalzustand nicht einmal in den DevTools angezeigt wird, umgekehrt wird.

Screenshot of the input in :active state in Chrome. A very light, almost white, grey to another light, but still darker grey gradient from bottom to top can be seen as the background, not the solid background-color indicated by DevTools.
Wie der eigentliche Input in Chrome im :active-Zustand aussieht. Er scheint einen Gradienten zu haben (umgekehrt zum Normalzustand), obwohl die Informationen in den DevTools uns sagen, dass dies nicht der Fall ist.

In den Firefox DevTools bewirkt das Umschalten des :active-Zustands nichts, aber wenn wir auch den :hover-Zustand aktivieren, erhalten wir eine Regel, die das Inline-padding ändert (das Block-padding ist auf denselben Wert von 0 gesetzt wie in allen anderen Zuständen), den border-style und setzt die background-color zurück auf unseren alten Freund ButtonFace.

Screenshot of Firefox DevTools showing the rule set that shows up for the :active state.
Firefox :active-Styling wie in den DevTools zu sehen.

In der Praxis entspricht jedoch nur die Inline-Verschiebung, die durch die Änderung des logischen padding verursacht wird, den Informationen aus den DevTools. Der background wird ein helleres Blau als im :hover-Zustand, und der border ist blau. Beides geschieht wahrscheinlich ebenfalls auf OS-Ebene.

Animiertes GIF. Zeigt, dass bei tatsächlichem Klicken auf unseren <input type='color' data-recalc-dims= er neben dem Verschieben um 1 Pixel in Inline-Richtung aufgrund der Änderung des Inline-Paddings einen hellblauen Hintergrund und einen blauen Rand erhält.
Was tatsächlich in Firefox im :active-Zustand passiert.

In Edge gibt uns die Aktivierung der :active-Klasse aus den DevTools die gleichen Stile wie für den :hover-Zustand. Wenn wir jedoch sowohl die Zustände :hover als auch :active aktivieren, ändert sich die Situation ein wenig. Wir haben immer noch einen hellblauen background und einen blauen border, aber beide sind jetzt dunkler (rgb(52, 180, 227) für die background-color und rgb(0, 137, 180) für die border-color).

Screenshot of Edge DevTools showing the computed value for background-color and border-color in the :active state.
Die berechnete background-color und border-color eines <input type='color'> bei :active, angesehen in Edge.

Das ist die Quintessenz: Wenn wir konsistente browserübergreifende Ergebnisse für <input type='color'> erzielen wollen, sollten wir unsere eigenen klar unterscheidbaren Stile für all diese Zustände definieren, denn glücklicherweise können fast alle Standardeinstellungen der Browser – mit Ausnahme des inneren Rechtecks, das wir in Edge bei :focus erhalten – überschrieben werden.

Der Swatch-Wrapper

Dies ist eine Komponente, die wir nur in Chrome sehen. Wenn wir also ein browserübergreifendes Ergebnis erzielen möchten, sollten wir wahrscheinlich sicherstellen, dass sie den darin enthaltenen Swatch nicht beeinträchtigt. Das bedeutet, dass sie keine margin, border, padding oder background hat und dass ihre Abmessungen denen des content-box des tatsächlichen Eingabefelds entsprechen.

Um herauszufinden, ob wir diese Eigenschaften (und vielleicht als Folge davon auch andere) ändern müssen oder nicht, sehen wir uns die Standardwerte des Browsers dafür an.

Glücklicherweise haben wir keine margin oder border, daher müssen wir uns darum keine Gedanken machen.

Chrome DevTools screenshot showing the margin and border values for the swatch wrapper.
Die Werte für margin und border des Swatch-Wrappers in Chrome.

Wir haben jedoch eine nicht-null padding (von 4px 2px), daher müssen wir diese auf Null setzen, wenn wir ein konsistentes browserübergreifendes Ergebnis erzielen möchten.

Chrome DevTools screenshot showing the padding values for the swatch wrapper.
Die Werte für padding des Swatch-Wrappers in Chrome.

Die Abmessungen sind beide praktisch auf 100% gesetzt, was bedeutet, dass wir uns nicht darum kümmern müssen.

Chrome DevTools screenshot showing the size values for the swatch wrapper.
Die Grössenwerte für den Swatch-Wrapper in Chrome.

Hier müssen wir anmerken, dass box-sizing auf border-box gesetzt ist, sodass die padding von den für diesen Wrapper festgelegten Abmessungen abgezogen wird.

Chrome DevTools screenshot showing the box-sizing value for the swatch wrapper.
Der Wert für box-sizing des Swatch-Wrappers in Chrome.

Das bedeutet, dass die padding-box, border-box und margin-box unseres Wrappers (alle gleich, da wir keine margin oder border haben) identisch mit der content-box des tatsächlichen <input type='color'> (die in Chrome 44pxx23px beträgt) sind, aber die content-box des Wrappers ergibt sich durch Abzug der padding von diesen Abmessungen. Daraus ergeben sich die Abmessungen 40pxx15px.

Chrome DevTools screenshot showing the box model for the swatch wrapper.
Das Box-Modell für den Swatch-Wrapper in Chrome.

Der background ist auf transparent gesetzt, daher ist dies eine weitere Eigenschaft, um die wir uns beim Zurücksetzen keine Gedanken machen müssen.

Chrome DevTools screenshot showing the background values for the swatch wrapper.
Die Werte für background des Swatch-Wrappers in Chrome.

Es gibt noch eine weitere Eigenschaft, die auf diesem Element gesetzt ist und meine Aufmerksamkeit erregt hat: display. Sie hat den Wert flex, was bedeutet, dass ihre Kinder Flex-Elemente sind.

Chrome DevTools screenshot showing the display value for the swatch wrapper.
Der Wert für display des Swatch-Wrappers in Chrome.

Der Swatch

Dies ist eine Komponente, die wir in Chrome und Firefox gestalten können. Leider wird sie von Edge nicht zur Verfügung gestellt, sodass wir keine Eigenschaften ändern können, die wir vielleicht möchten, wie z. B. border, border-radius oder box-shadow.

Die Eigenschaft box-sizing müssen wir explizit setzen, wenn wir dem Swatch einen border oder padding geben wollen, da ihr Wert in Chrome content-box, in Firefox aber border-box ist.

Comparative screenshots of DevTools in the two browsers showing the computed values of box-sizing for the swatch component.
Die Werte für box-sizing des Swatch, betrachtet in Chrome (oben) und Firefox (unten).

Glücklicherweise wird die font-size vom Eingabefeld selbst geerbt, sodass sie gleich ist.

Comparative screenshots of DevTools in the two browsers showing the computed values of font-size for the swatch component.
Die Werte für font-size des Swatch, betrachtet in Chrome (oben) und Firefox (unten).

Die margin berechnet sich in Chrome und Firefox auf 0.

Comparative screenshots of DevTools in the two browsers showing the computed values of margin for the swatch component.
Die Werte für margin des Swatch, betrachtet in Chrome (oben) und Firefox (unten).

Das liegt daran, dass die meisten Ränder nicht gesetzt wurden, sodass sie letztendlich 0 sind, was der Standard für <div>-Elemente ist. Firefox setzt jedoch die Inline-Ränder auf auto, und wir werden gleich darauf eingehen, warum das 0 ergibt.

Screenshot of Firefox DevTools.
Die Inline-margin für den Swatch wird in Firefox auf auto gesetzt.

Der border ist in beiden Browsern solid 1px. Einzig die border-color unterscheidet sich, die in Chrome rgb(119, 119, 119) und in Firefox grey (oder rgb(128, 128, 128), also etwas heller) ist.

Comparative screenshots of DevTools in the two browsers showing the computed values of border for the swatch component.
Die Werte für border des Swatch, betrachtet in Chrome (oben) und Firefox (unten).

Beachten Sie, dass die berechnete border-width in Firefox (zumindest unter Windows) vom OS-Zoomlevel abhängt, genau wie beim tatsächlichen Eingabefeld.

Die padding ist glücklicherweise in Chrome und Firefox 0.

Comparative screenshots of DevTools in the two browsers showing the computed values of padding for the swatch component.
Die Werte für padding des Swatch, betrachtet in Chrome (oben) und Firefox (unten).

Die Abmessungen entsprechen genau dem, was wir erwarten würden, wenn der Swatch die gesamte content-box seines Elternelements ausfüllt.

Comparative screenshots of DevTools in the two browsers showing the box model for the swatch component.
Das Box-Modell für den Swatch, betrachtet in Chrome (oben) und Firefox (unten).

In Chrome ist der Elternteil des Swatch der weiter oben erwähnte <div>-Wrapper, dessen content-box 4pxx15px beträgt. Dies entspricht der margin-box und der border-box des Swatch (die übereinstimmen, da wir keine margin haben). Da die padding 0 beträgt, sind die content-box und die padding-box des Swatch identisch. Wenn wir den 1px-Rand abziehen, erhalten wir Abmessungen von 38pxx13px.

In Firefox ist der Elternteil des Swatch das tatsächliche Eingabefeld, dessen content-box 44pxx19px beträgt. Dies entspricht der margin-box und der border-box des Swatch (die übereinstimmen, da wir keine margin haben). Da die padding 0 beträgt, sind die content-box und die padding-box des Swatch identisch. Wenn wir den 1px-Rand abziehen, erhalten wir Abmessungen von 42pxx17px.

In Firefox sehen wir, dass der Swatch so gestaltet ist, dass er die content-box seines Elternelements ausfüllt, indem beide seine Abmessungen auf 100% gesetzt werden.

Comparative screenshots of DevTools in the two browsers showing the size values for the swatch component.
Die Grössenwerte für den Swatch, betrachtet in Chrome (oben) und Firefox (unten).

Das ist der Grund, warum der Wert auto für die Inline-margin zu 0 berechnet wird.

Aber was ist mit Chrome? Wir sehen keine tatsächlichen Abmessungen. Nun, dieses Ergebnis ist auf das flex-Layout und die Tatsache zurückzuführen, dass der Swatch ein Flex-Element ist, das so gestreckt wird, dass es die content-box seines Elternelements ausfüllt.

Chrome DevTools screenshot showing the flex value for the swatch wrapper.
Der Wert für flex des Swatch-Wrappers in Chrome.

Abschließende Gedanken

Puh, wir haben hier viel Boden gutgemacht! Auch wenn es erschöpfend erscheinen mag, so tief in ein bestimmtes Element einzudringen, zeigt diese Übung, wie schwierig die browserübergreifende Unterstützung sein kann. Wir haben unsere eigenen Stile, Benutzeragenten-Stile und Betriebssystem-Stile zu durchqueren, und einige davon werden immer so sein, wie sie sind. Aber, wie wir ganz oben besprochen haben, ist dies letztendlich ein Barrierefreiheitsproblem, und etwas, das bei der Implementierung einer praktischen, funktionalen Anwendung eines Farbauswahlfeldes wirklich berücksichtigt werden muss.

Denken Sie daran, dass vieles davon fruchtbarer Boden ist, um sich an Browserhersteller zu wenden und ihnen mitzuteilen, wie sie ihre Implementierungen basierend auf Ihren berichteten Anwendungsfällen aktualisieren können. Hier sind die drei Tickets, die ich zuvor erwähnt habe, wo Sie entweder einen Kommentar abgeben oder sich auf ein neues Ticket beziehen können.