Ein Leitfaden zur CSS-Unterstützung in Browsern
Veröffentlicht: 2022-03-10Wir werden niemals in einer Welt leben, in der jeder, der unsere Sites betrachtet, einen identischen Browser und eine identische Browserversion hat, genauso wie wir niemals in einer Welt leben werden, in der jeder die gleiche Bildschirmgröße und Auflösung hat. Das bedeutet, dass der Umgang mit alten Browsern – oder Browsern, die etwas, das wir verwenden möchten, nicht unterstützen – Teil der Arbeit eines Webentwicklers ist. Allerdings sind die Dinge jetzt viel besser als in der Vergangenheit, und in diesem Artikel werde ich einen Blick auf die verschiedenen Arten von Problemen mit der Browserunterstützung werfen, auf die wir stoßen könnten. Ich werde Ihnen einige Möglichkeiten zeigen, mit ihnen umzugehen, und auch auf Dinge schauen, die bald kommen könnten und die helfen können.
Warum haben wir diese Unterschiede?
Selbst in einer Welt, in der die meisten Browser Chromium-basiert sind, führen diese Browser nicht alle dieselbe Version von Chromium wie Google Chrome aus. Dies bedeutet, dass ein Chromium-basierter Browser wie Vivaldi möglicherweise einige Versionen hinter Google Chrome zurückliegt.
Und natürlich aktualisieren Benutzer ihre Browser nicht immer schnell, obwohl sich diese Situation in den letzten Jahren verbessert hat, da sich die meisten Browser stillschweigend selbst aktualisieren.
Es gibt auch die Art und Weise, wie neue Funktionen überhaupt in Browser gelangen. Es ist nicht so, dass neue Funktionen für CSS von der CSS-Arbeitsgruppe entworfen und eine vollständige Spezifikation mit einer Anweisung zu ihrer Implementierung an die Browseranbieter weitergegeben wird. Sehr oft können erst bei einer experimentellen Implementierung alle Feinheiten der Spezifikation ausgearbeitet werden. Daher ist die Funktionsentwicklung ein iterativer Prozess und erfordert, dass Browser diese Spezifikationen in der Entwicklung implementieren. Während die Implementierung heutzutage meistens hinter einem Flag im Browser stattfindet oder nur in einer Nightly- oder Preview-Version verfügbar ist, wird ein Browser, sobald er eine vollständige Funktion hat, diese wahrscheinlich für alle einschalten, auch wenn noch kein anderer Browser dies unterstützt.
All dies bedeutet, dass wir – so sehr wir es auch mögen mögen – niemals in einer Welt existieren werden, in der Funktionen auf magische Weise auf jedem Desktop und Telefon gleichzeitig verfügbar sind. Wenn Sie ein professioneller Webentwickler sind, dann ist es Ihre Aufgabe, sich mit dieser Tatsache auseinanderzusetzen.
Bugs vs. fehlender Support
Es gibt drei Probleme, mit denen wir in Bezug auf die Browserunterstützung konfrontiert sind:
- Keine Unterstützung einer Funktion
Das erste Problem (und am einfachsten zu lösen) ist, wenn ein Browser die Funktion überhaupt nicht unterstützt. - Umgang mit Browser „Bugs“
Die zweite ist, wenn der Browser behauptet, die Funktion zu unterstützen, dies jedoch auf eine andere Weise tut, als andere Browser die Funktion unterstützen. Ein solches Problem wird von uns als „Browser-Bug“ bezeichnet, da das Endergebnis ein inkonsistentes Verhalten ist. - Teilweise Unterstützung von CSS-Eigenschaften
Dieser wird immer häufiger; eine Situation, in der ein Browser ein Feature unterstützt – aber nur in einem Kontext.
Es ist hilfreich zu verstehen, womit Sie es zu tun haben, wenn Sie einen Unterschied zwischen Browsern feststellen, also lassen Sie uns einen Blick auf jedes dieser Probleme der Reihe nach werfen.
1. Keine Unterstützung einer Funktion
Wenn Sie eine CSS-Eigenschaft oder einen Wert verwenden, den ein Browser nicht versteht, ignoriert der Browser ihn. Dies gilt unabhängig davon, ob Sie eine Funktion verwenden, die nicht unterstützt wird, oder eine Funktion erfinden und versuchen, sie zu verwenden. Wenn der Browser diese CSS-Zeile nicht versteht, überspringt er sie einfach und fährt mit dem nächsten fort, was er versteht.
Dieses Designprinzip von CSS bedeutet, dass Sie neue Funktionen fröhlich nutzen können, in dem Wissen, dass einem Browser ohne Unterstützung nichts Schlimmes passieren wird. Für einige CSS, die nur als Erweiterung verwendet werden, ist das alles, was Sie tun müssen. Verwenden Sie die Funktion, stellen Sie sicher, dass die Erfahrung immer noch gut ist, wenn diese Funktion nicht verfügbar ist, und das war's. Dieser Ansatz ist die Grundidee hinter progressiver Erweiterung, die diese Funktion der Plattform nutzt, die die sichere Verwendung neuer Dinge in Browsern ermöglicht, die sie nicht verstehen.
Wenn Sie überprüfen möchten, ob eine von Ihnen verwendete Funktion von Browsern unterstützt wird, können Sie auf der Can I Use-Website nachsehen. Ein weiterer guter Ort, um nach detaillierten Supportinformationen zu suchen, ist die Seite für jede CSS-Eigenschaft auf MDN. Die Browserunterstützungsdaten dort sind in der Regel sehr detailliert.
Neues CSS versteht altes CSS
Bei der Entwicklung neuer CSS-Features wird darauf geachtet, wie sie mit bestehendem CSS interagieren. Beispielsweise wird in der Grid- und Flexbox-Spezifikation ausführlich beschrieben, wie display: grid
und display: flex
mit Szenarien umgehen, wie beispielsweise wenn ein schwebendes Element zu einem Grid-Element wird oder ein Multicol-Container in ein Grid umgewandelt wird. Das bedeutet, dass bestimmte Verhaltensweisen ignoriert werden, was Ihnen hilft, das CSS für den nicht unterstützenden Browser einfach zu überschreiben. Diese Überschreibungen werden auf der Seite für progressive Erweiterung und Grid-Layout auf MDN detailliert beschrieben.
Erkennen von Support mit Funktionsabfragen
Die obige Methode funktioniert nur, wenn das CSS, das Sie verwenden müssen, keine anderen Eigenschaften benötigt. Möglicherweise müssen Sie Ihrem CSS für ältere Browser zusätzliche Eigenschaften hinzufügen, die dann auch von den Browsern interpretiert werden, die das Feature ebenfalls unterstützen.
Ein gutes Beispiel dafür findet sich bei der Verwendung von Grid Layout. Während ein Floating-Element, das zu einem Rasterelement wird, jegliches Float-Verhalten verliert, ist es wahrscheinlich, dass Sie, wenn Sie versuchen, ein Fallback für ein Rasterlayout mit Float zu erstellen, den Elementen prozentuale Breiten und möglicherweise Ränder hinzugefügt haben.
.grid > .item { width: 23%; margin: 0 1%; }
Diese Breiten und Ränder gelten dann immer noch, wenn das schwebende Element ein Rasterelement ist. Die Breite wird zu einem Prozentsatz der Rasterspur und nicht zur vollen Breite des Containers; Es wird dann ein etwaiger Rand sowie eine eventuell von Ihnen festgelegte Lücke angewendet.
.grid > .item { width: 23%; margin: 0 1%; } .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; }
Glücklicherweise gibt es eine in CSS integrierte und in moderne Browser implementierte Funktion, die uns hilft, mit dieser Situation umzugehen. Funktionsabfragen ermöglichen es uns, den Browser direkt zu fragen, was er unterstützt, und dann auf die Antwort zu reagieren. Genau wie eine Medienabfrage – die auf einige Eigenschaften des Geräts oder Bildschirms testet – testen Funktionsabfragen auf die Unterstützung einer CSS-Eigenschaft und eines CSS-Werts.
Testen Sie für Unterstützung
Das Testen auf Unterstützung ist der einfachste Fall, wir verwenden @supports
und testen dann auf eine CSS-Eigenschaft und einen Wert. Der Inhalt innerhalb der Feature-Abfrage wird nur ausgeführt, wenn der Browser mit true antwortet, dh er unterstützt das Feature.
Test auf keine Unterstützung
Sie können den Browser fragen, ob er eine Funktion nicht unterstützt. In diesem Fall wird der Code in der Funktionsabfrage nur ausgeführt, wenn der Browser angibt, dass er keine Unterstützung hat.
@supports not (display: grid) { .item { /* CSS from browsers which do not support grid layout */ } }
Testen Sie auf mehrere Dinge
Wenn mehr als eine Eigenschaft unterstützt werden soll, verwenden Sie and
.
@supports (display: grid) and (shape-outside: circle()){ .item { /* CSS from browsers which support grid and CSS shapes */ } }
Wenn Sie Unterstützung für die eine oder andere Eigenschaft benötigen, verwenden Sie or
.
@supports (display: grid) or (display: flex){ .item { /* CSS from browsers which support grid or flexbox */ } }
Auswählen einer Eigenschaft und eines Werts zum Testen
Sie müssen nicht jede Eigenschaft testen, die Sie verwenden möchten – nur etwas, das auf die Unterstützung der Funktionen hinweist, die Sie verwenden möchten. Wenn Sie also das Grid-Layout verwenden möchten, können Sie auf display: grid
testen. In Zukunft (und sobald Subgrid-Unterstützung in Browsern landet) müssen Sie möglicherweise spezifischer sein und die Subgrid-Funktionalität testen. In diesem Fall würden Sie auf grid-template-columns: subgrid
testen, um eine echte Antwort nur von den Browsern zu erhalten, die Subgrid-Unterstützung implementiert haben.
Wenn wir jetzt zu unserem Floating-Fallback-Beispiel zurückkehren, können wir sehen, wie Funktionsabfragen es für uns regeln. Was wir tun müssen, ist, den Browser abzufragen, um herauszufinden, ob er das Grid-Layout unterstützt. Wenn dies der Fall ist, können wir die Breite des Elements auf auto
und den Rand auf 0
.
.grid > .item { width: 23%; margin: 0 1%; } @supports(display: grid) { .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } .grid > .item { width: auto; margin: 0; } }
Beachten Sie, dass ich zwar den gesamten Grid-Code in meine Feature-Abfrage eingefügt habe, dies aber nicht erforderlich ist. Wenn ein Browser die Grid-Eigenschaften nicht verstehen würde, würde er sie ignorieren, sodass sie sich sicher außerhalb der Feature-Abfrage befinden könnten. Die Dinge, die in diesem Beispiel in einer Funktionsabfrage enthalten sein müssen, sind die Eigenschaften margin und width, da diese für den alten Browsercode benötigt werden, aber auch von unterstützenden Browsern angewendet würden.
Umfassen Sie die Kaskade
Eine sehr einfache Möglichkeit, Fallbacks anzubieten, besteht darin, die Tatsache zu nutzen, dass Browser CSS ignorieren, die sie nicht verstehen, und die Tatsache, dass dort, wo alles andere die gleiche Spezifität hat, die Quellreihenfolge in Bezug darauf berücksichtigt wird, welche CSS auf ein Element angewendet wird .
Sie schreiben zuerst Ihr CSS für Browser, die das Feature nicht unterstützen. Testen Sie dann die Unterstützung der Eigenschaft, die Sie verwenden möchten, wenn der Browser bestätigt, dass er unterstützt wird, überschreiben Sie den Fallback-Code mit Ihrem neuen Code.
Dies ist so ziemlich das gleiche Verfahren, das Sie verwenden könnten, wenn Sie Medienabfragen für responsives Design verwenden, indem Sie einem Mobile-First-Ansatz folgen. Bei diesem Ansatz beginnen Sie mit Ihrem Layout für kleinere Bildschirme und fügen dann Dinge für größere hinzu oder überschreiben sie, während Sie sich durch Ihre Haltepunkte nach oben bewegen.
Die obige Arbeitsweise bedeutet, dass Sie sich keine Gedanken über Browser machen müssen, die Feature Queries nicht unterstützen. Wie Sie anhand von Can I Use sehen können, werden Feature Queries wirklich großartig unterstützt. Die herausragenden Browser, die sie nicht unterstützen, sind Versionen von Internet Explorer.
Es ist jedoch wahrscheinlich, dass die neue Funktion, die Sie verwenden möchten, auch im IE nicht unterstützt wird. Derzeit werden Sie also fast immer damit beginnen, CSS für Browser ohne Unterstützung zu schreiben, und dann mit einer Feature-Abfrage testen. Diese Funktionsabfrage sollte auf Unterstützung testen.
- Browser, die Funktionsabfragen unterstützen, geben true zurück, wenn sie Unterstützung haben, und daher wird der Code in der Abfrage verwendet, wobei der Code für ältere Browser überschrieben wird.
- Wenn der Browser Funktionsabfragen, aber nicht die getestete Funktion unterstützt, wird "false" zurückgegeben. Der Code in der Funktionsabfrage wird ignoriert.
- Wenn der Browser keine Funktionsabfragen unterstützt, wird alles innerhalb des Funktionsabfrageblocks ignoriert, was bedeutet, dass ein Browser wie IE11 Ihren alten Browsercode verwendet, was sehr wahrscheinlich genau das ist, was Sie wollen!
2. Umgang mit Browser „Bugs“
Das zweite Problem mit der Browserunterstützung wird glücklicherweise immer seltener. Wenn Sie „What We Wished For“ (veröffentlicht Ende letzten Jahres) lesen, können Sie einen kleinen Rundgang durch einige der verwirrenderen Browser-Bugs der Vergangenheit machen. Allerdings kann jede Software Fehler enthalten, Browser sind da keine Ausnahme. Und wenn wir dazu noch die Tatsache hinzufügen, dass aufgrund der kreisförmigen Natur der Spezifikationsimplementierung manchmal ein Browser etwas implementiert hat und sich dann die Spezifikation geändert hat, so dass sie jetzt ein Update herausgeben müssen. Bis dieses Update ausgeliefert wird, befinden wir uns möglicherweise in einer Situation, in der Browser etwas anderes machen.
Funktionsabfragen können uns nicht helfen, wenn der Browser Unterstützung für etwas meldet, das es schlecht unterstützt. Es gibt keinen Modus, in dem der Browser sagen kann: " Ja, aber es wird Ihnen wahrscheinlich nicht gefallen ." Wenn ein tatsächlicher Interoperabilitätsfehler auftaucht, müssen Sie in diesen Situationen möglicherweise etwas kreativer sein.
Wenn Sie glauben, dass Sie einen Fehler sehen, müssen Sie dies zunächst bestätigen. Manchmal, wenn wir denken, dass wir fehlerhaftes Verhalten sehen und Browser andere Dinge tun, liegt der Fehler bei uns. Vielleicht haben wir eine ungültige Syntax verwendet oder versuchen, fehlerhaftes HTML zu formatieren. In diesen Fällen versucht der Browser, etwas zu tun; Da Sie die Sprachen jedoch nicht so verwenden, wie sie entwickelt wurden, kann jeder Browser anders damit umgehen. Eine schnelle Überprüfung, ob Ihr HTML und CSS gültig ist, ist ein ausgezeichneter erster Schritt.
An diesem Punkt würde ich wahrscheinlich eine schnelle Suche durchführen und sehen, ob mein Problem bereits allgemein verstanden wurde. Es gibt einige Repos bekannter Probleme, zB Flexbugs und Gridbugs. Aber selbst nur ein paar gut ausgewählte Schlüsselwörter können Stack Overflow-Beiträge oder Artikel hervorbringen, die das Thema behandeln und Ihnen möglicherweise eine Problemumgehung bieten.
Aber nehmen wir an, Sie wissen nicht wirklich, was den Fehler verursacht, was die Suche nach einer Lösung ziemlich schwierig macht. Der nächste Schritt besteht also darin, einen reduzierten Testfall Ihres Problems zu erstellen, dh alles Irrelevante zu entfernen, um Ihnen zu helfen, genau zu identifizieren, was den Fehler auslöst. Wenn Sie glauben, dass Sie einen CSS-Fehler haben, können Sie JavaScript entfernen oder denselben Stil außerhalb eines Frameworks neu erstellen? Ich verwende CodePen oft, um einen reduzierten Testfall von etwas, das ich sehe, zusammenzustellen; Dies hat den zusätzlichen Vorteil, dass ich den Code so habe, dass ich ihn leicht mit jemand anderem teilen kann, wenn ich danach fragen muss.
Sobald Sie das Problem isoliert haben, ist es meistens möglich, sich einen alternativen Weg auszudenken, um das gewünschte Ergebnis zu erzielen. Sie werden feststellen, dass sich jemand anderes eine schlaue Problemumgehung ausgedacht hat, oder Sie können irgendwo posten, um nach Vorschlägen zu fragen.
Wenn Sie jedoch glauben, dass Sie einen Browserfehler haben und niemanden finden können, der über dasselbe Problem spricht, ist es durchaus möglich, dass Sie etwas Neues gefunden haben, das gemeldet werden sollte. Bei all dem neuen CSS, das in letzter Zeit auf den Markt kam, können manchmal Probleme auftreten, wenn Leute anfangen, Dinge in Kombination mit anderen Teilen von CSS zu verwenden.
Sehen Sie sich diesen Beitrag von Lea Verou zum Melden solcher Probleme an: „Help The Community! Melden Sie Browserfehler!“. Der Artikel enthält auch großartige Tipps zum Erstellen eines reduzierten Testfalls.
3. Teilweise Unterstützung von CSS-Eigenschaften
Die dritte Art von Problemen ist aufgrund der Art und Weise, wie moderne CSS-Spezifikationen entworfen wurden, häufiger geworden. Wenn wir an Grid Layout und Flexbox denken, verwenden diese Spezifikationen beide die Eigenschaften und Werte in Box Alignment Level 3, um die Ausrichtung durchzuführen. Daher werden Eigenschaften wie align-items
, justify-content
und column-gap
so angegeben, dass sie sowohl in Grid als auch in Flexbox und anderen Layoutmethoden verwendet werden.
Zum Zeitpunkt des Schreibens funktionieren die gap
-Eigenschaften jedoch im Grid-Layout in allen Grid-unterstützenden Browsern, und column-gap
funktioniert in Multicol; Allerdings hat nur Firefox diese Eigenschaften für Flexbox implementiert.
Wenn ich Ränder verwenden würde, um einen Fallback für Flexbox zu erstellen, dann auf column-gap
zu testen und die Ränder zu entfernen, haben meine Boxen in Browsern, die column-gap
Abstand sein ENTFERNT.
@supports(column-gap: 20px) { .flex { margin: 0; /* almost everything supports column-gap so this will always remove the margins, even if we do not have gap support in flexbox. */ } }
Dies ist eine aktuelle Einschränkung von Funktionsabfragen. Wir haben keine Möglichkeit, die Unterstützung einer Funktion in einer anderen Funktion zu testen. In der obigen Situation möchte ich den Browser fragen: „Haben Sie Unterstützung für Spaltenlücken in Flexbox?“ Auf diese Weise kann ich eine negative Antwort erhalten, damit ich meinen Fallback verwenden kann.
Es gibt ein ähnliches Problem mit den CSS-Fragmentierungseigenschaften break-before
, break-after
und break-inside
. Da diese besser unterstützt werden, wenn die Seite gedruckt wird, werden Browser häufig Unterstützung beanspruchen. Wenn Sie jedoch auf Unterstützung in Multicol testen, erhalten Sie scheinbar falsch positive Ergebnisse. Ich habe ein Problem bei der CSS-Arbeitsgruppe für dieses Problem angesprochen, aber es ist kein einfaches Problem, das es zu lösen gilt. Wenn Sie Gedanken haben, fügen Sie sie bitte dort hinzu.
Testen für Selektorunterstützung
Derzeit können Funktionsabfragen nur auf CSS-Eigenschaften und -Werte testen. Eine andere Sache, die wir testen möchten, ist die Unterstützung neuer Selektoren, wie z. B. die in Level 4 der Selektoren-Spezifikation. Es gibt eine Erläuterung und auch eine Implementierung hinter einem Flag in Firefox Nightly einer neuen Funktion für Funktionsabfragen, die dies erreichen wird.
Wenn Sie about:config
in Firefox aufrufen und das Flag layout.css.supports-selector.enabled
, können Sie testen, ob verschiedene Selektoren unterstützt werden. Die Syntax ist derzeit sehr einfach, um beispielsweise den :has
-Selektor zu testen:
@supports selector(:has){ .item { /* CSS for support of :has */ } }
Dies ist eine Spezifikation in der Entwicklung, Sie können jedoch sehen, wie Funktionen hinzugefügt werden, die uns helfen, die allgegenwärtigen Probleme der Browserunterstützung zu bewältigen, während wir hier sprechen.
Weiterführende Lektüre
Es kann frustrierend erscheinen, wenn Sie eine Funktion verwenden möchten und feststellen, dass sie von einem großen Browser nicht unterstützt wird, oder wenn sich die Dinge anders zu verhalten scheinen. Ich habe einige praktische weiterführende Lektüre zusammengetragen, die helfen könnte.
- „CSS Grid verwenden: Browser ohne Grid unterstützen“ Optionen für den Umgang mit älteren Browsern und CSS Grid
- „Funktionsabfragen“ MDN-Referenzseite für Funktionsabfragen
- „CSS Grid and Progressive Enhancement“ MDN-Leitfaden zur progressiven Grid-Erweiterung
- „Abwärtskompatibilität von Flexbox“ MDN-Leitfaden zur Flexbox-Unterstützung, einschließlich Details zu älteren Implementierungen mit Präfix
- „Pattern Library First“ Wie man Fallback-Code mit einer Musterbibliothek verwaltet