Wir können nicht über Webentwicklung sprechen, ohne über Responsive Design zu sprechen. Es ist heutzutage selbstverständlich und das schon seit vielen Jahren. Media Queries sind ein Teil von Responsive Design und werden uns erhalten bleiben. Seit der Einführung von Media Queries (buchstäblich vor Jahrzehnten) hat sich CSS so weit entwickelt, dass es viele Tricks gibt, die uns helfen können, die Nutzung von Media Queries drastisch zu reduzieren. In einigen Fällen zeige ich Ihnen, wie Sie mehrere Media Queries durch nur eine CSS-Deklaration ersetzen können. Diese Ansätze können zu weniger Code führen, leichter zu warten sein und besser an den vorliegenden Inhalt angepasst sein.
Betrachten wir zunächst einige weit verbreitete Methoden, um responsive Layouts ohne Media Queries zu erstellen. Keine Überraschung hier – diese Methoden beziehen sich auf Flexbox und Grid.
Verwendung von flex und flex-wrap
In der obigen Demo setzt flex: 400px eine Basisbreite für jedes Element im Grid, die gleich 400px ist. Jedes Element bricht in eine neue Zeile um, wenn nicht genügend Platz in der aktuellen Zeile vorhanden ist, um es aufzunehmen. Währenddessen wachsen/dehnen sich die Elemente jeder Zeile aus, um jeden verbleibenden Platz im Container auszufüllen, falls die Zeile kein weiteres 400px Element aufnehmen kann, und sie schrumpfen wieder bis auf 400px, wenn ein weiteres 400px Element dort hineinpasst.
Erinnern wir uns auch daran, dass flex: 400px ein Kurzschreibweise ist, die flex: 1 1 400px entspricht (flex-grow: 1, flex-shrink: 1, flex-basis: 400px).
Was wir bisher haben
- ✔️ Nur zwei Codezeilen
- ❌ Einheitliche Elementbreiten in der Fußzeile
- ❌ Kontrolle der Anzahl der Elemente pro Zeile
- ❌ Kontrolle, wann die Elemente umbrechen
Verwendung von auto-fit und minmax
Ähnlich wie bei der vorherigen Methode legen wir eine Basisbreite fest – dank repeat(auto-fit, minmax(400px, 1fr)) – und unsere Elemente brechen um, wenn genügend Platz vorhanden ist. Diesmal greifen wir jedoch auf CSS Grid zurück. Das bedeutet, dass sich die Elemente jeder Zeile auch ausdehnen, um jeglichen verbleibenden Platz auszufüllen, aber im Gegensatz zur Flexbox-Konfiguration behält die letzte Zeile die gleiche Breite wie die restlichen Elemente.
Damit haben wir eine Anforderung erfüllt und eine weitere gelöst, aber auch ein neues Problem eingeführt, da unsere Elemente nicht kleiner als 400px werden können, was zu einem Überlauf führen kann.
- ✔️ Nur eine Codezeile
- ✔️ Einheitliche Elementbreiten in der Fußzeile
- ❌ Kontrolle der Anzahl der Elemente pro Zeile
- ❌ Elemente wachsen, aber schrumpfen nicht
- ❌ Kontrolle, wann die Elemente umbrechen
Beide betrachteten Techniken sind gut, aber wir sehen nun auch, dass sie einige Nachteile haben. Aber wir können diese mit etwas CSS-Trickerei überwinden.
Kontrolle der Anzahl der Elemente pro Zeile
Nehmen wir unser erstes Beispiel und ändern flex: 400px zu flex: max(400px, (100% - 20px)/3).
Verkleinern Sie den Bildschirm und bemerken Sie, dass jede Zeile nie mehr als drei Elemente enthält, selbst auf einem superbreiten Bildschirm. Wir haben jede Zeile auf maximal drei Elemente begrenzt, was bedeutet, dass jede Zeile zu jeder Zeit nur zwischen einem und drei Elementen enthält.
Zerlegen wir den Code
- Wenn die Bildschirmbreite zunimmt, nimmt auch die Breite unseres Containers zu, was bedeutet, dass
100%/3irgendwann größer als400pxwird. - Da wir die
max()-Funktion als Breite verwenden und100%durch3darin teilen, ist das Maximum für jedes einzelne Element nur ein Drittel der Gesamtbreite des Containers. So erhalten wir maximal drei Elemente pro Zeile. - Wenn die Bildschirmbreite klein ist, übernimmt
400pxdie Führung und wir erhalten unser ursprüngliches Verhalten.
Sie fragen sich vielleicht auch: *Was zum Teufel ist dieser 20px-Wert in der Formel?*
Es ist das Doppelte des gap-Werts der Grid-Vorlage, also 10px mal zwei. Wenn wir drei Elemente in einer Zeile haben, gibt es zwei Lücken zwischen den Elementen (eine links und eine rechts vom mittleren Element), also sollten wir für N Elemente max(400px, (100% - (N - 1) * gap)/N) verwenden. Ja, wir müssen den gap bei der Definition der Breite berücksichtigen, aber keine Sorge, wir können die Formel noch optimieren, um ihn zu entfernen!
Wir können max(400px, 100%/(N + 1) + 0.1%) verwenden. Die Logik ist: Wir sagen dem Browser, dass jedes Element eine Breite hat, die gleich 100%/(N + 1) ist, also N + 1 Elemente pro Zeile, aber wir fügen einen winzigen Prozentsatz (0.1%) hinzu – damit bricht eines der Elemente um und wir haben nur N Elemente pro Zeile. Clever, oder? Kein Kopfzerbrechen mehr über den gap!
Jetzt können wir die maximale Anzahl von Elementen pro Zeile kontrollieren, was uns eine teilweise Kontrolle über die Anzahl der Elemente pro Zeile gibt.
Das Gleiche kann auch auf die CSS Grid-Methode angewendet werden
Beachten Sie, dass ich hier benutzerdefinierte Eigenschaften eingeführt habe, um die verschiedenen Werte zu steuern.
Wir kommen der Sache näher!
- ✔️ Nur eine Codezeile
- ✔️ Einheitliche Elementbreiten in der Fußzeile
- ⚠️ Teilweise Kontrolle über die Anzahl der Elemente pro Zeile
- ❌ Elemente wachsen, aber schrumpfen nicht
- ❌ Kontrolle, wann die Elemente umbrechen
Elemente wachsen, aber schrumpfen nicht
Wir haben zuvor festgestellt, dass die Verwendung der Grid-Methode zu einem Überlauf führen kann, wenn die Basisbreite größer ist als die Containerbreite. Um dies zu überwinden, ändern wir
max(400px, 100%/(N + 1) + 0.1%)
...zu
clamp(100%/(N + 1) + 0.1%, 400px, 100%)
Aufschlüsselung
- Wenn die Bildschirmbreite groß ist, wird
400pxauf100%/(N + 1) + 0.1%geklemmt, wodurch unsere Kontrolle über die maximale Anzahl von Elementen pro Zeile erhalten bleibt. - Wenn die Bildschirmbreite klein ist, wird
400pxauf100%geklemmt, sodass unsere Elemente niemals die Containerbreite überschreiten.
Wir kommen der Sache noch näher!
- ✔️ Nur eine Codezeile
- ✔️ Einheitliche Elementbreiten in der Fußzeile
- ⚠️ Teilweise Kontrolle über die Anzahl der Elemente pro Zeile
- ✔️ Elemente wachsen und schrumpfen
- ❌ Kontrolle, wann die Elemente umbrechen
Kontrolle, wann die Elemente umbrechen
Bisher hatten wir keine Kontrolle darüber, wann Elemente von einer Zeile in eine andere umbrechen. Wir wissen nicht wirklich, wann das passiert, da es von einer Reihe von Faktoren abhängt, wie z. B. der Basisbreite, dem Abstand, der Containerbreite usw. Um dies zu kontrollieren, werden wir unsere letzte clamp()-Formel ändern, von dieser
clamp(100%/(N + 1) + 0.1%, 400px, 100%)
...zu
clamp(100%/(N + 1) + 0.1%, (400px - 100vw)*1000, 100%)
Ich kann Sie schreien hören wegen dieser verrückt aussehenden Mathematik, aber bleiben Sie geduldig. Es ist einfacher, als Sie denken. Hier ist, was passiert:
- Wenn die Bildschirmbreite (
100vw) größer als400pxist, ergibt(400px - 100vw)einen negativen Wert, und er wird auf100%/(N + 1) + 0.1%geklemmt, was ein positiver Wert ist. Dies ergibt N Elemente pro Zeile. - Wenn die Bildschirmbreite (
100vw) kleiner als400pxist, ist(400px - 100vw)ein positiver Wert und wird mit einem großen Wert multipliziert, der auf100%geklemmt wird. Dies ergibt ein einziges Vollbreiten-Element pro Zeile.
Hey, wir haben unsere erste Media Query ohne eine echte Media Query erstellt! Wir aktualisieren die Anzahl der Elemente pro Zeile von N auf 1 dank unserer clamp()-Formel. Es sollte angemerkt werden, dass 400px in diesem Fall als Breakpoint fungiert.
Was ist mit: von N Elementen pro Zeile zu M Elementen pro Zeile?
Das können wir absolut machen, indem wir die geklemmte Breite unseres Containers aktualisieren
clamp(100%/(N + 1) + 0.1%, (400px - 100vw)*1000, 100%/(M + 1) + 0.1%)
Ich denke, Sie haben den Trick inzwischen verstanden. Wenn die Bildschirmbreite größer als 400px ist, greift die erste Regel (N Elemente pro Zeile). Wenn die Bildschirmbreite kleiner als 400px ist, greift die zweite Regel (M Elemente pro Zeile).
Da haben wir es! Wir können jetzt die Anzahl der Elemente pro Zeile steuern und wann sich diese Anzahl ändern soll – mit nur CSS Custom Properties und einer CSS-Deklaration.
- ✔️ Nur eine Codezeile
- ✔️ Einheitliche Elementbreiten in der Fußzeile
- ✔️ Volle Kontrolle über die Anzahl der Elemente pro Zeile
- ✔️ Elemente wachsen und schrumpfen
- ✔️ Kontrolle, wann die Elemente umbrechen
Weitere Beispiele!
Die Kontrolle der Anzahl von Elementen zwischen zwei Werten ist gut, aber es für mehrere Werte zu tun ist noch besser! Versuchen wir, von N Elementen pro Zeile zu M Elementen pro Zeile, bis zu einem Element pro Zeile zu gehen.
Unsere Formel wird
clamp(clamp(100%/(N + 1) + 0.1%, (W1 - 100vw)*1000,100%/(M + 1) + 0.1%), (W2 - 100vw)*1000, 100%)
Ein clamp() innerhalb eines clamp()? Ja, es wird langsam lang und verwirrend, aber immer noch leicht verständlich. Beachten Sie die Variablen W1 und W2 darin. Da wir die Anzahl der Elemente pro Zeile zwischen drei Werten ändern, benötigen wir zwei "Breakpoints" (von N zu M und von M zu 1).
Hier ist, was passiert
- Wenn die Bildschirmbreite kleiner als
W2ist, wird auf100%geklemmt, also ein Element pro Zeile. - Wenn die Bildschirmbreite größer als
W2ist, wird auf das ersteclamp()geklemmt. - In diesem ersten Clamp wird, wenn die Bildschirmbreite kleiner als
W1ist, auf100%/(M + 1) + 0.1%)geklemmt, also M Elemente pro Zeile. - In diesem ersten Clamp wird, wenn die Bildschirmbreite größer als
W1ist, auf100%/(N + 1) + 0.1%)geklemmt, also N Elemente pro Zeile.
Wir haben zwei Media Queries mit nur einer CSS-Deklaration erstellt! Nicht nur das, sondern wir können diese Deklaration dank der CSS Custom Properties anpassen, was bedeutet, dass wir unterschiedliche Breakpoints und eine unterschiedliche Anzahl von Spalten für verschiedene Container haben können.
Wie viele Media Queries haben wir im obigen Beispiel? Zu viele, um sie zu zählen, aber wir werden nicht aufhören. Wir können noch mehr haben, indem wir ein weiteres clamp() verschachteln, um von N Spalten zu M Spalten zu P Spalten zu einer Spalte zu gelangen. (😱)
clamp(
clamp(
clamp(100%/(var(--n) + 1) + 0.1%, (var(--w1) - 100vw)*1000,
100%/(var(--m) + 1) + 0.1%),(var(--w2) - 100vw)*1000,
100%/(var(--p) + 1) + 0.1%),(var(--w3) - 100vw)*1000,
100%), 1fr))

N Spalten zu M Spalten zu P Spalten zu 1 SpalteWie ich ganz am Anfang dieses Artikels erwähnt habe, haben wir ein responsives Layout ohne eine einzige Media Query, indem wir nur eine CSS-Deklaration verwenden – sicher, es ist eine langwierige Deklaration, aber sie zählt trotzdem als eine.
Eine kurze Zusammenfassung dessen, was wir haben
- ✔️ Nur eine Codezeile
- ✔️ Einheitliche Elementbreiten in der Fußzeile
- ✔️ Volle Kontrolle über die Anzahl der Elemente pro Zeile
- ✔️ Elemente wachsen und schrumpfen
- ✔️ Kontrolle, wann die Elemente umbrechen
- ✔️ Einfach zu aktualisieren mit CSS Custom Properties
Lassen Sie uns Container Queries simulieren
Alle sind begeistert von Container Queries! Was sie so gut macht, ist, dass sie die Breite des Elements und nicht die des Viewports/Bildschirms berücksichtigen. Die Idee ist, dass sich ein Element basierend auf der Breite seines übergeordneten Containers anpassen kann, um eine feinere Kontrolle darüber zu erhalten, wie Elemente auf verschiedene Kontexte reagieren.
Container Queries werden zum Zeitpunkt der Erstellung dieses Artikels noch nicht offiziell unterstützt, aber wir können sie sicherlich mit unserer Strategie nachahmen. Wenn wir 100vw durch 100% im gesamten Code ersetzen, basieren die Dinge auf der Breite des Elements .container anstatt auf der Viewport-Breite. So einfach ist das!
Verkleinern Sie die folgenden Container und sehen Sie die Magie in Aktion.
Die Anzahl der Spalten ändert sich basierend auf der Containerbreite, was bedeutet, dass wir Container Queries simulieren! Wir machen das im Grunde nur, indem wir Viewport-Einheiten durch relative Prozentwerte ersetzen.
Weitere Tricks!
Jetzt, da wir die Anzahl der Spalten kontrollieren können, wollen wir weitere Tricks erkunden, die uns ermöglichen, bedingte CSS basierend auf der Bildschirmgröße (oder Elementgröße) zu erstellen.
Bedingte Hintergrundfarbe
Vor einiger Zeit fragte jemand auf StackOverflow ob es möglich sei, die Farbe eines Elements basierend auf seiner Breite oder Höhe zu ändern. Viele sagten, es sei unmöglich oder würde eine Media Query erfordern.
Aber ich habe einen Trick gefunden, es ohne Media Query zu tun
div {
background:
linear-gradient(green 0 0) 0 / max(0px,100px - 100%) 1px,
red;
}
- Wir haben eine lineare Gradient-Ebene mit einer Breite von
max(0px,100px - 100%)und einer Höhe von1px. Die Höhe ist eigentlich egal, da der Gradient standardmäßig wiederholt wird. Außerdem ist es ein einfarbiger Gradient, daher ist jede Höhe ausreichend. 100%bezieht sich auf die Breite des Elements. Wenn100%einen Wert größer als100pxergibt, liefertmax()0px, was bedeutet, dass der Gradient nicht angezeigt wird, aber der mit Komma getrenntered-Hintergrund schon.- Wenn
100%einen Wert kleiner als100pxergibt, wird der Gradient angezeigt und wir erhalten stattdessen einengreen-Hintergrund.
Mit anderen Worten, wir haben eine Bedingung basierend auf der Breite des Elements im Vergleich zu 100px erstellt!
Diese Demo unterstützt zum Zeitpunkt der Erstellung Chrome, Edge und Firefox.
Die gleiche Logik kann basierend auf der Höhe eines Elements angewendet werden, indem neu angeordnet wird, wohin der Wert von 1px geht: 1px max(0px,100px - 100%). Wir können auch die Bildschirmdimensionen berücksichtigen, indem wir vh oder vw anstelle von % verwenden. Wir können sogar mehr als zwei Farben haben, indem wir mehr Gradient-Ebenen hinzufügen.
div {
background:
linear-gradient(purple 0 0) 0 /max(0px,100px - 100%) 1px,
linear-gradient(blue 0 0) 0 /max(0px,300px - 100%) 1px,
linear-gradient(green 0 0) 0 /max(0px,500px - 100%) 1px,
red;
}

Umschalten der Sichtbarkeit eines Elements
Um ein Element basierend auf der Bildschirmgröße ein- oder auszublenden, greifen wir normalerweise auf eine Media Query zurück und fügen dort ein klassisches display: none ein. Hier ist eine andere Idee, die dasselbe Verhalten simuliert, nur ohne Media Query.
div {
max-width: clamp(0px, (100vw - 500px) * 1000, 100%);
max-height: clamp(0px, (100vw - 500px) * 1000, 1000px);
overflow: hidden;
}
Basierend auf der Bildschirmbreite (100vw) wird entweder ein 0px-Wert für max-height und max-width geklemmt (was bedeutet, dass das Element versteckt ist) oder 100% (was bedeutet, dass das Element sichtbar ist und niemals breiter als die volle Breite wird). Wir vermeiden die Verwendung eines Prozentsatzes für max-height, da dies fehlschlägt. Deshalb verwenden wir einen großen Pixelwert (1000px).
Beachten Sie, wie die grünen Elemente auf kleinen Bildschirmen verschwinden.
Es sollte beachtet werden, dass diese Methode nicht mit dem Umschalten des Display-Werts gleichwertig ist. Es ist eher ein Trick, um dem Element 0×0-Dimensionen zu geben und es unsichtbar zu machen. Es ist möglicherweise nicht für alle Fälle geeignet, also verwenden Sie es mit Vorsicht! Es ist eher ein Trick für dekorative Elemente, bei denen wir keine Barrierefreiheitsprobleme haben werden. Chris hat darüber geschrieben, wie man Inhalte verantwortungsbewusst versteckt.
Es ist wichtig zu beachten, dass ich 0px und nicht 0 innerhalb von clamp() und max() verwende. Letzteres macht die Eigenschaft ungültig. Ich werde hier nicht ins Detail gehen, aber ich habe eine Stack Overflow-Frage zu dieser Eigenart beantwortet, wenn Sie mehr Details wünschen.
Ändern der Position eines Elements
Der folgende Trick ist nützlich, wenn wir mit einem fixierten oder absolut positionierten Element arbeiten. Der Unterschied hier ist, dass wir die Position basierend auf der Bildschirmbreite aktualisieren müssen. Wie beim vorherigen Trick verlassen wir uns immer noch auf clamp() und eine Formel, die wie folgt aussieht: clamp(X1,(100vw - W)*1000, X2).
Im Grunde werden wir zwischen den Werten X1 und X2 wechseln, basierend auf der Differenz 100vw - W, wobei W die Breite ist, die unseren Breakpoint simuliert.
Nehmen wir ein Beispiel. Wir möchten, dass ein Div am linken Rand platziert wird (top: 50%; left:0), wenn die Bildschirmgröße kleiner als 400px ist, und es woanders platziert wird (sagen wir top: 10%; left: 40%), sonst.
div {
--c:(100vw - 400px); /* we define our condition */
top: clamp(10%, var(--c) * -1000, 50%);
left: clamp(0px, var(--c) * 1000, 40%);
}
Zuerst habe ich die Bedingung mit einer CSS Custom Property definiert, um Wiederholungen zu vermeiden. Beachten Sie, dass ich sie auch mit dem zuvor gezeigten Trick zum Umschalten der Hintergrundfarbe verwendet habe – wir können entweder (100vw - 400px) oder (400px - 100vw) verwenden, aber achten Sie später auf die Berechnung, da beide nicht dasselbe Vorzeichen haben.
Dann beginnen wir innerhalb jeder clamp() *immer* mit dem kleinsten Wert für jede Eigenschaft. Gehen Sie nicht fälschlicherweise davon aus, dass Sie zuerst den Wert für kleine Bildschirme angeben müssen!
Schließlich definieren wir das Vorzeichen für jede Bedingung. Ich habe (100vw - 400px) gewählt, was bedeutet, dass dieser Wert negativ ist, wenn die Bildschirmbreite kleiner als 400px ist, und positiv, wenn die Bildschirmbreite größer als 400px ist. Wenn ich möchte, dass der kleinste Wert von clamp() unter 400px berücksichtigt wird, ändere ich nichts am Vorzeichen der Bedingung (ich lasse sie positiv), aber wenn ich möchte, dass der kleinste Wert über 400px berücksichtigt wird, muss ich das Vorzeichen der Bedingung umkehren. Deshalb sehen Sie (100vw - 400px)*-1000 bei der Eigenschaft top.
OK, ich verstehe. Das ist nicht das einfachste Konzept, also machen wir die umgekehrte Überlegung und verfolgen unsere Schritte, um eine bessere Vorstellung davon zu bekommen, was wir tun.
Für top haben wir clamp(10%,(100vw - 400px)*-1000,50%), also...
- Wenn die Bildschirmbreite (
100vw) kleiner als400pxist, dann ist die Differenz (100vw - 400px) ein negativer Wert. Wir multiplizieren ihn mit einem anderen großen negativen Wert (-1000in diesem Fall), um einen großen positiven Wert zu erhalten, der auf50%geklemmt wird: Das bedeutet, wir bleiben beitop: 50%, wenn die Bildschirmgröße kleiner als400pxist. - Wenn die Bildschirmbreite (
100vw) größer als400pxist, erhalten wir stattdessen:top: 10%.
Die gleiche Logik gilt für das, was wir bei der Eigenschaft left deklarieren. Der einzige Unterschied ist, dass wir mit 1000 statt mit -1000 multiplizieren.
Hier ist ein Geheimnis: Sie brauchen nicht wirklich all diese Mathematik. Sie können experimentieren, bis Sie perfekte Werte erhalten, aber zum Zweck des Artikels muss ich Dinge so erklären, dass sie zu konsistentem Verhalten führen.
Es sollte beachtet werden, dass ein solcher Trick mit jeder Eigenschaft funktioniert, die Längenwerte akzeptiert (padding, margin, border-width, translate, etc.). Wir sind nicht darauf beschränkt, die position zu ändern, sondern auch andere Eigenschaften.
Demos!
Die meisten von Ihnen fragen sich wahrscheinlich, ob eines dieser Konzepte in einem realen Anwendungsfall praktisch ist. Lassen Sie mich Ihnen ein paar Beispiele zeigen, die Sie (hoffentlich) überzeugen werden.
Fortschrittsanzeige
Der Trick zum Ändern der Hintergrundfarbe eignet sich hervorragend für eine Fortschrittsanzeige oder jedes ähnliche Element, bei dem wir eine andere Farbe basierend auf dem Fortschritt anzeigen müssen.
Diese Demo unterstützt zum Zeitpunkt der Erstellung Chrome, Edge und Firefox.
Diese Demo ist ein ziemlich einfaches Beispiel, bei dem ich drei Bereiche definiere:
- Rot: [
0% 30%] - Orange: [
30% 60%] - Grün: [
60% 100%]
Es gibt kein wildes CSS oder JavaScript, um die Farbe zu aktualisieren. Eine "magische" Hintergrund-Eigenschaft ermöglicht es uns, eine dynamische Farbe zu haben, die sich basierend auf berechneten Werten ändert.
Bearbeitbarer Inhalt
Es ist üblich, Benutzern die Möglichkeit zu geben, Inhalte zu bearbeiten. Wir können die Farbe basierend auf dem eingegebenen Text aktualisieren.
Im folgenden Beispiel erhalten wir eine gelbe "Warnung", wenn wir mehr als drei Textzeilen eingeben, und eine rote "Warnung", wenn wir sechs Zeilen überschreiten. Dies kann eine Möglichkeit sein, JavaScript zu reduzieren, das die Höhe erkennen und dann eine bestimmte Klasse hinzufügen/entfernen müsste.
Diese Demo unterstützt zum Zeitpunkt der Erstellung Chrome, Edge und Firefox.
Timeline-Layout
Timelines sind großartige Muster zur Visualisierung wichtiger Momente in der Zeit. Diese Implementierung verwendet drei Tricks, um eine ohne Media Queries zu erhalten. Ein Trick ist die Aktualisierung der Anzahl der Spalten, ein anderer das Ausblenden einiger Elemente auf kleinen Bildschirmen und der letzte ist die Aktualisierung der Hintergrundfarbe. Wieder keine Media Queries!
Wenn die Bildschirmbreite unter 600px liegt, werden alle Pseudoelemente entfernt, wodurch sich das Layout von zwei Spalten zu einer Spalte ändert. Dann ändert sich die Farbe von einem Blau/Grün/Grün/Blau-Muster zu einem Blau/Grün/Blau/Grün-Muster.
Responsive Karte
Hier ist ein responsiver Kartenansatz, bei dem sich CSS-Eigenschaften basierend auf der Viewport-Größe aktualisieren. Normalerweise würden wir erwarten, dass das Layout von zwei Spalten auf großen Bildschirmen zu einer Spalte auf kleinen Bildschirmen übergeht, wobei das Kartenbild entweder über oder unter dem Inhalt gestapelt ist. In diesem Beispiel ändern wir jedoch die Position, Breite, Höhe, Polsterung und den Radius des Bildes, um ein völlig anderes Layout zu erhalten, bei dem das Bild neben dem Kartentitel liegt.
Sprechblasen
Benötigen Sie ein paar gut aussehende Testimonials für Ihr Produkt oder Ihre Dienstleistung? Diese responsiven Sprechblasen funktionieren fast überall, sogar ohne Media Queries.
Fixierter Button
Sie kennen diese Buttons, die manchmal am linken oder rechten Bildschirmrand fixiert sind, meist um ein Kontaktformular oder eine Umfrage zu verlinken? Wir können so etwas auf großen Bildschirmen haben und es dann in einen permanenten runden Button in der unteren rechten Ecke auf kleinen Bildschirmen verwandeln, für bequemere Taps.
Fixierter Hinweis
Noch eine Demo, diesmal für etwas, das für diese DSGVO-Cookie-Hinweise funktionieren könnte.
Fazit
Media Queries sind seit der Erfindung des Begriffs Responsive Design eine Kernkomponente für responsive Layouts. Sie werden uns zwar erhalten bleiben, aber wir haben eine Reihe neuer CSS-Funktionen und -Konzepte behandelt, die es uns ermöglichen, uns bei der Erstellung responsiver Layouts weniger oft auf Media Queries zu verlassen.
Wir haben uns Flexbox und Grid, clamp(), relative Einheiten angesehen und sie kombiniert, um alle möglichen Dinge zu tun, vom Ändern des Hintergrunds eines Elements basierend auf seiner Containerbreite, dem Verschieben von Positionen bei bestimmten Bildschirmgrößen bis hin zum Nachahmen von noch nicht veröffentlichten Container Queries. Aufregende Sache! Und das alles ohne eine einzige @media im CSS.
Das Ziel hier ist nicht, Media Queries abzuschaffen oder sie vollständig zu ersetzen, sondern vielmehr, die Menge des Codes zu optimieren und zu reduzieren, insbesondere da CSS sich stark weiterentwickelt hat und wir jetzt einige leistungsstarke Werkzeuge haben, um bedingte Stile zu erstellen. Mit anderen Worten, es ist großartig zu sehen, wie sich die CSS-Funktionspalette so weiterentwickelt, dass sie unser Leben als Front-End-Entwickler einfacher macht und uns gleichzeitig Superkräfte verleiht, um zu steuern, wie sich unsere Designs verhalten, wie wir es noch nie zuvor hatten.
Hier gibt es einige clevere Sachen, aber...
Vielleicht ist es *zu* clever?
Manchmal ist das Schreiben von ausdrucksstärkerem, lesbarerem Code besser. Insbesondere in größeren Teams oder Teams mit unterschiedlichen Fähigkeiten/Kenntnissen.
Media Queries sind selbstdokumentierend.
Ich denke, einige der oben genannten Beispiele würden umfangreiche Kommentare benötigen, um die Logik zu erklären, und das untergräbt den Zweck, weniger Code zu schreiben.
Aber das ist nur meine (bescheidene) Meinung. ;)
Das Ziel ist hier nicht, Media Queries abzuschaffen oder sie vollständig zu ersetzen. Ich untersuche verschiedene Techniken/Ideen, die es Ihnen ermöglichen, bedingtes CSS basierend auf der Bildschirmbreite (oder Containerbreite) zu haben.
Am Ende des Artikels werden Sie zusätzlich zu Media Queries weitere Tricks zur Hand haben, und es liegt an Ihnen, sie korrekt anzuwenden.
Ich würde Ihnen nicht raten, überall Spaghetti-Code mit clamp() zu erstellen, aber in einigen Fällen können Sie zwei (oder mehr) Media Queries durch ein einziges clamp() ersetzen, das Sie mit CSS-Variablen anpassen können. Dazu fügen Sie ein paar Kommentare neben den CSS-Variablen hinzu, und Ihr Code ist perfekt ;)
Sie sagten "Media Queries sind selbstdokumentierend", und das liegt daran, dass sie seit mehr als 10 Jahren verwendet werden. Ich schlage "neue" Tricks vor, und nichts Neues ist immer leicht zu verdauen. Tatsächlich sind die Leute, wenn sie ein clamp() im Code finden, etwas überrascht, aber in Zukunft wird es etwas Triviales sein und durch einfaches Betrachten des Codes können wir leicht verstehen, was dort vor sich geht ;)
Nochmal, ich sage nicht "benutze keine Media Queries". Ich sage: "Hey, man kann das auch so machen, ganz ohne Media Queries" :)
Danke für den Artikel! Genau das hätte ich von einer Website namens "CSS Tricks" erwartet ;)
Das alles ist ein großartiges Beispiel für kreative CSS-Meisterschaft, aber ich stimme Kev zu, dass es extrem schwierig sein kann, Ihren Code ohne die Schritt-für-Schritt-Anleitung, die Sie gegeben haben, zu rekonfigurieren :)
Wie auch immer, als jemand, der diese magische Natur von CSS liebt, hat es mir wirklich gefallen!
Ich stimme dem "ausdrucksstarken, lesbaren Code" vollkommen zu, aber in diesem Fall hätten Sie definitiv einen SASS-Mixin daraus machen und es für Ihre Entwicklerkollegen nett gestalten können.
Ich muss Kev hier zustimmen. Das würde ich nicht verwenden, da Media Queries/Container Queries für dieses Verhalten gedacht sind, clamp aber nicht.
Nichtsdestotrotz hat mir dieser Artikel gefallen. Es ist ein cooler Hack zum Ausprobieren und gut zu wissen, dass er existiert, aber nicht für Produktionscode.
Zu clever für Safari in einigen Beispielen oben... aber das wird sich mit der Zeit lernen.
Was mir hier wirklich gefällt, ist, dass die Reaktionsfähigkeit *innerhalb* der Stilregel bleibt.
Zu oft sieht man, wie Media Query/Queries, die an eine Stilregel "angehängt" sind, von der Stilregel im Code vollständig getrennt werden, insbesondere bei älteren Codebasen.
Das wird noch schlimmer, wenn jemand (hust) beschließt, den gesamten responsiven CSS-Code für verschiedene Elemente in eine einzige Breakpoint-Media-Query zu integrieren, um die Anzahl der Wiederholungen derselben Media-Query und die Gesamtgröße des CSS zu minimieren.
Mit guten Absichten, aber eine Qual zum Arbeiten und am besten geeignet für die Erstellung von Tools/Plugins wie postcss-combine-media-query
Genau! und zusätzlich zur Reaktionsfähigkeit innerhalb der Stilregel können wir sie leicht mit CSS-Variablen anpassen, was uns die Möglichkeit gibt, unterschiedliche reaktionsfähige Verhaltensweisen für verschiedene Elemente zu haben, ohne Code zu duplizieren ;)
Um Private Frazer aus "Dad’s Army" zu zitieren: "Wir sind dem Untergang geweiht".
Container Queries werden kommen. Wir werden alle "Halleluja" sagen, Webkit wird die Implementierung lange genug verzögern, um den App Store noch ein bisschen zu stützen, Eichhörnchen werden hektisch npm-Pakete und Abhängigkeiten aktualisieren, Dinge werden kaputt gehen und repariert werden, Polyfills werden sich vermehren und alle werden sich unter dem neuen Code vereinen.
In der Zwischenzeit gibt es Ihre Lösung. Ich kann mir nur keinen passenden atomaren Klassennamen ausdenken, um Wiederholungen zu vermeiden.
Erstaunlicher Artikel, und ich mag es, dass Sie die Formeln erklären.
Ich bevorzuge dies stark gegenüber Media Queries, obwohl die Formeln immer gut kommentiert sein sollten, sonst könnte die Bedeutung verloren gehen. Ich weiß nicht, ob ich den meisten Programmierern vertraue, sich überhaupt damit zu befassen.
Bitte, Gott, bring Sub Grid in alle Browser, nur um die Dinge einfacher zu machen. Worauf warten sie?
Danke für diese großartige Erkundung! Das ist wirklich hochqualitativer Edge-Content.
Toller Beitrag!
Ich würde jedoch diese sehr langen, komplizierten CSS-Zeilen in Variablen mit aussagekräftigen Namen aufteilen.
Das ist wunderbar!
Indem ich dem folgte, war es für mich einfach zu sehen, wie ich Bootstraps Grid-Layout abschaffen könnte. In einer Welt, in der wir versuchen, Code kleiner zu machen, eliminiert dies die Notwendigkeit, dieses letzte Stück mit einigen kleinen Ergänzungen zu importieren.
Danke für diesen großartigen Artikel, ich habe viel daraus gelernt,
Ich denke, diese Art der Reaktionsfähigkeit erschwert das Lesen von CSS. Mit Media Queries haben wir einen genauen Pixel-Breakpoint, und jeder kann es ohne Lesen des Codes verstehen.
Hier muss ich widersprechen
"mit Media Queries haben wir einen genauen Pixel-Breakpoint" -> Ich habe hier auf die gleiche Weise einen genauen Pixel-Breakpoint wie Media Queries. Ich simuliere das gleiche Verhalten von Media Queries mit weniger Code.
"und jeder kann es ohne Lesen des Codes verstehen." -> Sie sagen das, weil Sie Media Queries schon seit langem kennen und Media Queries seit mehr als 10 Jahren verfügbar sind. Die Tatsache, dass Media Queries weit verbreitet sind, macht sie "einfach", aber immer noch kann niemand sie auf den ersten Blick verstehen. Sie haben keine Ahnung, wie viele Leute zwischen min-width/max-width, der Syntax von Media Queries oder der Reihenfolge von Media Queries verwirrt sind. Ganz zu schweigen von den Spezifitätsproblemen. Sie müssen immer noch das Handbuch von Media Queries lesen, um sie zu verstehen, sie sind nicht intuitiv.
Meine Logik ist "einfacher" als Media Queries, ABER es ist etwas Neues und alles Neue erscheint immer schwierig, weil wir es nicht gewohnt sind. Wir müssen ihm Zeit geben und wenn Leute damit arbeiten, wird es "einfach" sein, weil solcher Code weit verbreitet und dokumentiert sein wird. Vergessen wir nicht die Tatsache, dass meine Logik auf CSS-Variablen basiert, also müssen Sie nur diese Variablen aktualisieren. Wenn sie gut dokumentiert sind, müssen Sie den Code nicht einmal überprüfen. Das Gleiche können wir von Media Queries nicht sagen.
Ich habe beim Ausprobieren des Responsive Card-Beispiels festgestellt, dass Sie nicht das gewünschte Ergebnis erzielen, wenn die Viewport-Breite dem Wert der benutzerdefinierten Eigenschaft
--wentspricht, sodass alle Eigenschaften zwischen den minimalen und maximalen Clamp-Werten wechseln. Wenn sie gleich sind, ist--c: (100vw - var(--w))0px, daher ist der Wert vonvar(--c)*-1000undvar(--c)*1000gleich, 0px, und der minimale Clamp-Wert wird für alle verwendet, anstatt dass einer zum maximalen Wert und der andere zum minimalen Wert wechselt.Dies scheint vermieden werden zu können, indem ein Wert verwendet wird, der niemals gleich der Viewport-Breite ist. Das heißt, verwenden Sie eine nicht-ganzzahlige Zahl wie
--w: 450.1px;. Alternativ können Sie einen kleinen Prozentsatz hinzufügen, wie--c: (100vw - var(--w) + .1%);, was vielleicht besser ist, damit der "Breakpoint"-Wert eine schöne, runde Zahl bleibt.Was ist mit den exakten 450px im Responsive Card-Beispiel? https://codepen.io/t_afif/pen/abyLYGy das Layout ist kaputt.
Sie können solche Probleme vermeiden, indem Sie Werte wie 450,05px oder 450,99px verwenden. Ein Wert, den der Browser nicht verwenden kann (oder selten verwendet) als Breite.
Hallo, gibt es eine Möglichkeit, Divs zu zentrieren, wenn sie in eine neue Zeile umgebrochen werden?
In diesem Codepen sind sie nicht zentriert. https://codepen.io/t_afif/pen/bGqbgYY
Leider ist das mit dieser Konfiguration und CSS Grid im Allgemeinen nicht möglich. Sie müssen etwas anderes mit Flexbox versuchen.
Eigentlich sehe ich nicht, wie die Reaktionsfähigkeitstricks mit der Zentrierung kombiniert werden können.