Spaßfakt: Es ist möglich, responsive Komponenten komplett ohne Media Queries zu erstellen. Sicherlich wären Container Queries sehr nützlich für Responsive Design auf Komponentenebene. Aber die haben wir nicht. Dennoch können wir, ob mit oder ohne Container Queries, Dinge tun, um unsere Komponenten überraschend responsiv zu gestalten. Wir werden Konzepte aus Intrinsic Web Design verwenden, präsentiert von Jen Simmons.
Tauchen wir gemeinsam in den unten beschriebenen Anwendungsfall ein, die Lösungen im Hinblick auf den aktuellen Stand von CSS und einige weitere Tricks, die ich Ihnen geben werde.
Eine responsive „Kochrezept“-Karte
Ich habe kürzlich ein Video und einen Pen von einer responsiven Card-Demo getwittert, die ich am Beispiel eines Pizzarezepts erstellt habe. (Für die Technologie hier nicht wichtig, aber ich habe das Rezept am Ende abgeladen, weil es köstlich und glutenfrei ist.)
Responsive Pizza Rezept Komponente ohne Media Queries.https://#/upft4Vpkp1
— Geoffrey Crofte 🔥 (@geoffreycrofte) 18. Juli 2020
Arbeit in progress basierend auf einem Design von @WalterStephanie. Viel Spaß beim Ändern der Größe Ihres Browserfensters 😊 pic.twitter.com/FHK2ghMb91
Die Demo hier war ein erster Versuch, basierend auf einem Konzept aus einem der Vorträge von Stéphanie Walter. Hier ist ein Video, das Ihnen zeigt, wie die Karte funktionieren wird
Und wenn Sie jetzt damit spielen möchten, hier ist der Pen.
Lassen Sie uns das responsive Layout definieren
Ein Schlüssel zur Planung ist das Wissen um die tatsächlichen Inhalte, mit denen Sie arbeiten, und die Bedeutung dieser Details. Nicht, dass wir Inhalte zu irgendeinem Zeitpunkt verstecken sollten, aber aus Layout- und Designgründen ist es gut zu wissen, was zuerst kommuniziert werden muss und so weiter. Wir werden dieselben Inhalte unabhängig von der Größe oder Form des Layouts anzeigen.
Stellen wir uns die Inhalte mit einer Mobile-First-Mentalität vor, um uns auf das Wichtigste zu konzentrieren. Wenn der Bildschirm dann größer wird, wie auf einem Desktop, können wir den zusätzlichen Platz für Dinge wie * gloriosen * Weißraum und größere Typografie nutzen. Normalerweise reicht eine solche Priorisierung aus, um sicherzustellen, welche Inhalte für die Karten bei allen und jedem Viewport-Größen benötigt werden.
Nehmen wir das Beispiel eines Kochrezept-Teasers

In ihrem Vortrag hatte Stéphanie die Arbeit bereits erledigt und die Inhalte priorisiert für unsere Karten. Hier ist, was sie in der Reihenfolge der Wichtigkeit skizziert hat:
- Bild: Weil es ein Rezept ist, isst man mit den Augen!
- Titel: Um sicherzugehen, was Sie kochen werden.
- Schlüsselwörter: Um wichtige Informationen auf den ersten Blick zu erfassen.
- Bewertungsinformationen: Für sozialen Beweis.
- Kurze Beschreibung: Für die Leute, die lesen.
- Call to Action: Was Sie erwarten, dass der Benutzer mit dieser Karte macht.
Das mag nach viel klingen, aber wir können all das in ein einziges intelligentes Kartenlayout packen!
Nicht skalierbare Typografie
Eine der Einschränkungen der Technik, die ich Ihnen zeigen werde, ist, dass Sie keine skalierbare Typografie basierend auf der Containerbreite erhalten. Skalierbare Typografie (z. B. „fluid type“) wird üblicherweise mit der Viewport-Breite (vw) Einheit gemacht, die auf dem Viewport basiert, nicht auf dem Elternelement.
Während wir also versucht sein könnten, Fluid-Typografie als nicht-media-query-basierte Lösung für den Inhalt unserer Karten zu verwenden, können wir Fluid-Typografie leider nicht auf Basis eines Prozentsatzes der Containerbreite oder der Elementbreite selbst verwenden. Das wird uns jedoch nicht von unserem Ziel abhalten!
Ein kurzer Hinweis zur „Pixelgenauigkeit“
Sprechen wir beide Seiten an…
Designer: Pixelgenauigkeit ist super ideal, und wir können sicherlich auf Komponentenebene präzise sein. Aber auf Layout-Ebene muss es einen Kompromiss geben. Das bedeutet, Sie müssen einige Variationen bereitstellen, aber die Zwischenzustände flexibel lassen. Dinge verschieben sich in responsiven Layouts und Präzision bei jeder möglichen Bildschirmbreite ist eine schwierige Anforderung. Wir können aber trotzdem dafür sorgen, dass die Dinge in jeder Skalierung gut aussehen!
Entwickler: Sie müssen in der Lage sein, die Lücken zwischen den Layouts zu füllen, für die vorgegebene Designs existieren, damit die Inhalte zwischen diesen Zuständen lesbar und konsistent sind. Als gute Praxis empfehle ich auch, so viel wie möglich einen natürlichen Fluss beizubehalten.
Sie können auch den hervorragenden Artikel von Ahmad über den Zustand der Pixelgenauigkeit lesen.
Ein Rezept für null Media Queries
Denken Sie daran, dass wir nicht nur eine responsive Karte anstreben, sondern eine, die keine Media Queries benötigt. Es ist nicht so, dass Media Queries vermieden werden sollten; es geht vielmehr darum, dass CSS mächtig und flexibel genug ist, um uns auch andere Optionen zur Verfügung zu stellen.
Um unsere responsive Karte zu erstellen, fragte ich mich, ob Flexbox ausreichen würde oder ob ich es stattdessen mit CSS Grid machen müsste. Es stellt sich heraus, dass Flexbox diesmal tatsächlich ausreicht, indem wir das Verhalten und die Magie der Eigenschaften flex-wrap und flex-basis in CSS nutzen.
Der Kern von flex-wrap ist, dass es Elementen erlaubt, auf eine neue Zeile zu springen, wenn der Platz für Inhalte zu knapp wird. Sie können den Unterschied zwischen Flex ohne Zeilenumbruch und mit Zeilenumbruch in dieser Demo sehen.
Der flex-basis-Wert von 200px ist mehr eine Anweisung als ein Vorschlag für den Browser, aber wenn der Container nicht genug Platz dafür bietet, rutschen die Elemente nach unten in eine neue Zeile. Der Abstand zwischen den Spalten erzwingt sogar den anfänglichen Zeilenumbruch.
Ich habe diese Umbruchlogik verwendet, um die Basis meiner Karte zu erstellen. Adam Argyle hat sie auch in der folgenden Demo verwendet, die vier Formularlayouts mit nur 10 Zeilen CSS zeigt.
In seinem Beispiel verwendet Adam flex-basis und flex-grow (gemeinsam in der Kurzform flex-Eigenschaft) ), um dem E-Mail-Eingabefeld zu erlauben, dreimal so viel Platz einzunehmen wie das Namensfeld oder der Button. Wenn der Browser abschätzt, dass nicht genug Platz vorhanden ist, um alles in derselben Zeile anzuzeigen, bricht das Layout von selbst in mehrere Zeilen um, ohne dass wir die Änderungen mit Media Queries verwalten müssen.
Ich habe auch die clamp() Funktion verwendet, um noch mehr Flexibilität hinzuzufügen. Diese Funktion ist sozusagen magisch. Sie erlaubt uns, eine min()- und eine max()-Berechnung in einer einzigen Funktion zu lösen. Die Syntax lautet:
clamp(MIN, VALUE, MAX)
Es ist, als würde man eine Kombination aus den Funktionen max() und min() lösen.
max(MIN, min(VAL, MAX))
Sie können sie für alle Arten von Eigenschaften verwenden, die Folgendes abdecken: <length>, <frequency>, <angle>, <time>, <percentage>, <number> oder <integer>.
Die „No-Media Query Responsive Card“-Demo
Mit all diesen neuartigen CSS-Kräften habe ich eine flexible responsive Karte ohne Media Queries erstellt. Es ist vielleicht am besten, diese Demo in einem neuen Tab anzuzeigen oder mit einer 0,5-fachen Option in der eingebetteten Version unten.
Etwas, das Sie sofort bemerken möchten, ist, dass der HTML-Code für die 2 Karten genau derselbe ist; der einzige Unterschied ist, dass die erste Karte in einem 65 % breiten Container und die zweite in einem 35 % breiten Container liegt. Sie können auch die Abmessungen Ihres Fensters anpassen, um die Responsivität zu testen.
Der wichtige Teil des Codes in dieser Demo befindet sich bei diesen Selektoren
.recipeist der übergeordnete Flex-Container..pizza-boxist ein Flex-Item, das der Container für das Kartenbild ist..recipe-contentist ein zweites Flex-Item und der Container für den Karteninhalt.
Jetzt, da wir wissen, wie flex-wrap funktioniert und wie flex-basis und flex-grow die Elementgröße beeinflussen, müssen wir nur noch kurz die clamp()-Funktion erklären, da ich sie für die responsive Schriftgrößenanpassung anstelle von Fluid-Typografie verwendet habe.
Ich wollte calc() und benutzerdefinierte Eigenschaften verwenden, um Schriftgrößen basierend auf der Breite des übergeordneten Containers zu berechnen, aber ich konnte keinen Weg finden, da ein 100%-Wert je nach Kontext unterschiedlich interpretiert wird. Ich habe ihn für den mittleren Wert meiner clamp()-Funktion beibehalten, aber das Endergebnis war überdimensioniert und funktionierte nicht wie erhofft oder erwartet.
/* No need, really */
font-size: clamp(1.4em, calc(.5em * 2.1vw), 2.1em);
Hier bin ich stattdessen gelandet
font-size: clamp(1.4em, 2.1vw, 2.1em);
Das habe ich getan, um die Größe des Kartentitels an die Bildschirmgröße anzupassen, aber wie wir bereits weiter oben beim Thema Fluid-Typografie besprochen haben, werden wir den Text nicht nach der Breite des übergeordneten Containers skalieren können.
Stattdessen sagen wir mit dieser einen Zeile CSS im Grunde genommen:
Ich möchte, dass die
font-size2,1vw (2,1% der Viewport-Breite) entspricht, aber bitte lassen Sie sie nicht unter 1,4em oder über 2,1em gehen.
Dies bewahrt die priorisierte Bedeutung des Titels, indem er größer als der Rest des Inhalts bleibt, aber dennoch lesbar ist. Und er wächst und schrumpft mit der Bildschirmgröße!
Und vergessen wir nicht die responsiven Bilder. Die Inhaltsanforderungen besagen, dass das Bild das wichtigste Element ist, also müssen wir es definitiv berücksichtigen und sicherstellen, dass es in allen Bildschirmgrößen gut aussieht. Nun, Sie möchten vielleicht so etwas tun und es dabei belassen.
max-width: 100%;
height: auto;
Aber das führt nicht immer zur besten Darstellung eines Bildes. Stattdessen haben wir die object-fit-Eigenschaft, die nicht nur auf die Höhe und Breite der Content-Box des Bildes reagiert, sondern es uns auch erlaubt, das Bild zuzuschneiden und zu steuern, wie es in der Box gestreckt wird, wenn es mit der object-position-Eigenschaft verwendet wird.
img {
max-width: 100%;
min-height: 100%;
width: auto;
height: auto;
object-fit: cover;
object-position: 50% 50%;
}
Wie Sie sehen, ist das eine Menge von Eigenschaften aufzulisten. Dies ist zwingend erforderlich wegen der expliziten Breiten- und Höhenangaben im HTML-<img>-Code. Wenn Sie den HTML-Teil entfernen (was ich aus Performance-Gründen nicht empfehle), können Sie die object-*-Eigenschaften in CSS belassen und die anderen entfernen.
Ein alternatives Rezept für keine Media Queries
Eine weitere Technik ist die Verwendung von flex-grow als einheitlichen Wachstumsfaktor mit einem absurd riesigen Wert für flex-basis. Die Idee ist direkt aus Heydon Pickerings großartiger „Holy Albatross“-Demo gestohlen.
Der interessante Teil des Codes ist dieser:
/* Container */
.recipe {
--modifier: calc(70ch - 100%);
display: flex;
flex-wrap: wrap;
}
/* Image dimension */
.pizza-box {
flex-grow: 3;
flex-shrink: 1;
flex-basis: calc(var(--modifier) * 999);
}
/* Text content dimension */
.recipe-content {
flex-grow: 4;
flex-shrink: 1;
flex-basis: calc(var(--modifier) * 999);
}
Proportionale Abmessungen werden durch flex-grow erzeugt, während die flex-basis-Abmessung entweder ungültig oder extrem hoch sein kann. Der Wert wird extrem hoch, wenn calc(70ch - 100%), der Wert von --modifier, einen positiven Wert erreicht. Wenn die Werte extrem hoch sind, füllt jeder von ihnen den Raum und erzeugt ein Spaltenlayout; wenn die Werte ungültig sind, ordnen sie sich inline an.
Der Wert von 70ch wirkt wie der *Breakpoint* im Rezept-Komponente (fast wie eine Container Query). Ändern Sie ihn je nach Bedarf.
Zerlegen wir die Zutaten noch einmal
Hier sind die CSS-Zutaten, die wir für eine kartenlose Komponentenkomponente verwendet haben:
- Die
clamp()-Funktion hilft bei der Auflösung eines „bevorzugten“ im Gegensatz zu einem „minimalen“ oder „maximalen“ Wert. - Die Eigenschaft
flex-basismit einem negativen Wert bestimmt, wann das Layout in mehrere Zeilen umbricht. - Die Eigenschaft
flex-growwird als Einheitswert für proportionale Wachstumswerte verwendet. - Die
vw-Einheit hilft bei responsiver Typografie. - Die
object-fit-Eigenschaft bietet feinere Responsivität für das Kartenbild, da sie es uns ermöglicht, die Abmessungen des Bildes zu ändern, ohne es zu verzerren.
Weiter geht's mit Mengenabfragen
Ich habe noch einen weiteren Trick für Sie: Wir können das Layout je nach *Anzahl* der Elemente im Container anpassen. Das ist keine echte Responsivität, die durch die Dimension eines Containers entsteht, sondern eher durch den Kontext, in dem der Inhalt liegt.
Es gibt keine *echte* Media Query für die Anzahl der Elemente. Es ist ein kleiner CSS-Trick, um die Anzahl der Elemente rückwärts zu zählen und Stiländerungen entsprechend anzuwenden.
Die Demo verwendet den folgenden Selektor
.container > :nth-last-child(n+3),
.container > :nth-last-child(n+3) ~ * {
flex-direction: column;
}
Sieht schwierig aus, oder? Dieser Selektor erlaubt uns, Stile *vom* letzten Kind und all seinen Geschwistern aus anzuwenden. Nett!
Una Kravets erklärt dieses Konzept sehr gut. Wir können diesen speziellen Anwendungsfall wie folgt übersetzen:
.container > :nth-last-child(n+3): Das dritte oder größere .container-Element *vom Ende* der .container-Gruppe..container > :nth-last-child(n+3) ~ *: Genau das Gleiche, aber wählt jedes .container-Element *nach* dem letzten aus. Dies hilft, andere Karten, die wir hinzufügen, zu berücksichtigen.
Kitty Giraudels „Selectors Explained“-Tool hilft wirklich, komplexe Selektoren in einfacher Sprache zu übersetzen, falls Sie eine weitere Übersetzung wünschen, wie diese Selektoren funktionieren.
Eine weitere Möglichkeit, „Mengen“-Container in CSS zu erhalten, ist die Verwendung von binären Bedingungen. Aber die Syntax ist nicht einfach und scheint etwas hacky. Sie können mich auf Twitter erreichen, wenn Sie über diese – oder andere Tricks und Tipps zu CSS oder Design – sprechen möchten.
Ist das zukunftssicher?
Alle Techniken, die ich Ihnen hier vorgestellt habe, können heute in einer Produktionsumgebung eingesetzt werden. Sie werden gut unterstützt und bieten Möglichkeiten für graceful degradation.
Im schlimmsten Fall? Ein Browser, der etwas nicht unterstützt, wie z. B. Internet Explorer 9, wird das Layout nicht gemäß den von uns angegebenen Bedingungen ändern, aber der Inhalt wird trotzdem lesbar sein. Es ist also unterstützt, aber vielleicht nicht für das ideale Erlebnis „optimiert“.
Vielleicht werden wir eines Tages endlich den Heiligen Gral der Container Queries in Aktion erleben. Hoffentlich resonierten die Intrinsic Web Design-Muster, die wir hier verwendet haben, mit Ihnen und helfen Ihnen in der Zwischenzeit, flexible und „intrinsisch-responsive“ Komponenten zu bauen.
Kommen wir zum „wirklichen“ Grund für diesen Beitrag … der Pizza! 🍕
Glutenfreies Pfannenpizza-Rezept
Sie können die Beläge wählen. Das Wichtigste ist der Teig, und hier ist er:
Zutaten
- 3¼ Tassen (455g) glutenfreies Mehl
- 1 Esslöffel plus 1 Teelöffel (29g) brauner Zucker
- 2 Teelöffel koscheres Salz
- ½ Würfel Hefe
- 2½ Tassen (400 ml) Vollmilch
- 4 Esslöffel geschmolzene Margarine
- 1 Esslöffel Maisstärke
Anleitung
- Alle trockenen Zutaten vermischen.
- Flüssigkeiten hinzufügen.
- 2 Stunden gehen lassen, bis sich die Masse verdoppelt hat. Ich empfehle, ein feuchtes Geschirrtuch über Ihre Schüssel mit dem Teig zu legen und die Schüssel in die Nähe eines heißen Bereichs zu stellen (aber nicht zu heiß, da wir ihn nicht sofort backen wollen).
- In die Pfanne mit Öl geben. Ca. 1 Stunde gehen lassen, bis sich die Masse verdoppelt hat.
- Im Ofen bei 250 Grad 20 Minuten backen.
Danke Stéphanie für das Rezept 😁
Ich möchte nur sagen, Ihr Karten-Styling ist atemberaubend.
Hallo Chris :)
Danke für das Feedback!
Danke für die Tipps und die Videos! Ich muss sagen, ich liebe dieses Pizzarezept! Chapeau!
Kann das auch mit CSS Grid gemacht werden?
Liebe das
Danke für das Pizzarezept
Gern geschehen
Immer wenn ich an diese Technik denke, wünsche ich mir, dass es (in CSS) eine Möglichkeit gäbe, die visuelle Beziehung eines Elements zu dem vorhergehenden abzufragen. So könnte man sagen: Wenn
.recipe-contentin einer Zeile mit.pizza-boxist, mache dies. Oder wenn.recipe-content(visuell) eine Blockbeziehung zu.pizza-boxhat, wende diese Stile an. Das fühlt sich sehr CSS-artig an und wäre wirklich leistungsstark.Ich kann Sam hier nicht mehr zustimmen
...und NICHT zugänglich. Sie basiert nicht auf der Textgröße des Browsers des Benutzers oder anderen benutzerdefinierten Einstellungen. Bitte vermeiden Sie die Verwendung.
Hallo Bobby,
Danke für Ihre Besorgnis über die Barrierefreiheit! Ich stimme zu, dass
vwnicht einfach so verwendet werden sollte.Deshalb habe ich eine
clamp()-Funktion verwendet, um sie flexibler und „zoomfreundlicher“ zu machen. Ich war mir nicht sicher, aber da sowohl max als auch min inem-Einheiten angegeben sind, ist die Schriftart mit den Texteinstellungen des Benutzers kompatibel. Ich habe es gerade unter Chrome und Firefox mit Textzoom und Interfacezoom getestet. Alles gut.Und was ist mit IE? Die meisten Unternehmen verwenden Windows, und viele Benutzer und Unternehmen verwenden immer noch IE10 oder IE11, und das wird nicht funktionieren.
Ich habe Media-Query-freie Karten und Seiten erstellt, aber es nützt mir nichts, wenn es für die Hälfte der Leute, die ich erreichen möchte, nicht funktioniert.
Es ist sicherlich kein Zuckerschlecken, die CSS-Konstruktion für beide Szenarien erstellen zu müssen, und ich versuche immer noch, sie zum Laufen zu bringen.
Hallo Rita,
Es tut mir leid, dass Sie immer noch IE10 und IE11 unterstützen müssen. Ich würde sagen, dass dies hier eine Unternehmensentscheidung und keine CSS-Entscheidung ist, aber ich werde mich nicht auf diesen Weg begeben.
Sie können @supports verwenden, um die von mir vorgeschlagene Lösung zu nutzen und eine Lösung für IE auf Basis von Floating Elements zu überschreiben. Wir haben früher eine Technik für responsive E-Mails mit Floating Tables verwendet, das sollte für jede Art von Element funktionieren. Eine weitere Lösung ist, sich auf JavaScript zu verlassen, um ein präzises Verhalten basierend auf dem Elternelement der Komponente zu definieren.
Leider gibt es keine magische Lösung, wenn man versucht, moderne Probleme mit alten und unsicheren Werkzeugen zu lösen.
Gute Lösung, danke. Ich habe jedoch ein Problem bei meiner Implementierung, bei der die Stile direkt aus Ihrer ersten Lösung übernommen wurden – das Bild deckt seinen Bereich nicht vollständig ab, wenn ich die Breite und Höhe von .pizza-box nicht auf 100 % setze – es sieht so aus, als ob max-width und max-height nichts bewirken. Wissen Sie, was dieses Verhalten verursachen könnte?
Hallo Miloš,
Ich kann ohne einen Auszug Ihres Codes keine sichere Antwort geben, denn selbst das HTML könnte das Verhalten hier beeinflussen. Tatsächlich könnte die Darstellung variieren, wenn Sie keine Breiten- und Höhenattribute im Bild haben.
Wichtiger Hinweis auch: Ich habe nicht viel Aufwand in das Bildverhältnis gesteckt, Sie müssen das CSS vielleicht ein wenig anpassen, wenn die erste HTML-Lösung nicht funktioniert.
Viel Spaß :)
wie man Spalten umbricht
1 2 3
4 5 6
in der mobilen Ansicht sollte es so aussehen
1 2
4 5
3 6
Hallo Rakesh,
Sie sollten versuchen, CSS Grid Layout für diese Art von Anforderungen zu verwenden. Suchen Sie danach auf CSS Tricks.