[ad_1]
Wir alle wissen, wie man Responsive Design macht, oder? Wir verwenden Medienanfragen. Nun nein, wir verwenden Containerabfragen Nun, nicht wahr? Manchmal werden wir erfinderisch Flexbox oder Automatisch fließende Gitter. Wenn wir uns wirklich abenteuerlustig fühlen, können wir danach greifen flüssige Typografie.
Es ist mir etwas unangenehm, dass Responsive Design oft in diskrete Abschnitte aufgeteilt wird, wie zum Beispiel „Layout A bis zu dieser Größe, dann Layout B, bis genug Platz für Layout C ist.“ Es ist in Ordnung, es funktioniert und passt in einen Workflow, in dem Bildschirme als statische Layouts in PhotoFigVa entworfen werden (Vorbehalt, das habe ich mir ausgedacht). Aber der Prozess fühlt sich für mich wie ein Kompromiss an. Ich bin seit langem davon überzeugt, dass responsives Design für den Benutzer nahezu unsichtbar sein sollte. Wenn sie meine Website auf einem mobilen Gerät besuchen, während sie in der Schlange auf K-Pop-Tickets warten, sollten sie nicht bemerken, dass es anders ist als noch vor einer Stunde, als sie an dem riesigen gebogenen Gaming-Monitor saßen, von dem sie ihrem Chef überzeugt hatten, dass er ihn brauchte.
Betrachten Sie dieses einfache Heldenbanner und sein mobiles Äquivalent. Entschuldigung für das schlichte Design. Das Bild ist KI-generiert, aber es ist das Einzige an diesem Artikel.
Das Erdmännchen und der Text sind alle unterschiedlich positioniert und unterschiedlich groß. Der traditionelle Weg, dies zu erreichen, besteht darin, zwei Layouts zu haben, die von a ausgewählt werden MedienEntschuldigung, Containerabfrage. In jedem Layout könnte es eine gewisse Flexibilität geben, vielleicht die Zentrierung des Inhalts und eine etwas flüssige Typografie auf dem font-size
aber wir werden einen Punkt wählen, an dem wir das Layout in die gestapelte Version hinein- und wieder herausdrehen. Daher ist es wahrscheinlich, dass es in der Nähe des Haltepunkts Breiten gibt, bei denen das Layout entweder etwas leer oder etwas überfüllt aussieht.
Gibt es einen anderen Weg?
Es stellt sich dort heraus Ist. Wir können das Konzept der flüssigen Typografie auf fast alles anwenden. Auf diese Weise können wir ein Layout erstellen, das sich fließend mit der Größe des übergeordneten Containers ändert. Nur wenige Benutzer werden den Übergang jemals sehen, aber sie alle werden die Ergebnisse zu schätzen wissen. Ehrlich gesagt, das werden sie.
Lassen Sie uns das aufpeppen
Lassen Sie uns im ersten Schritt die Layouts individuell gestalten, ähnlich wie wir es bei der Verwendung von Breitenabfragen und einem Haltepunkt tun würden. Lassen Sie uns tatsächlich eine Containerabfrage und einen Haltepunkt zusammen verwenden, damit wir leicht erkennen können, welche Eigenschaften geändert werden müssen.
Dies ist der Markup für unseren Helden, und er wird sich nicht ändern:
LookOut
Eagle Defense System
Dies ist das relevante CSS für die breite Version:
#hero {
container-type: inline-size;
max-width: 1200px;
min-width: 360px;
.details {
position: absolute;
z-index: 2;
top: 220px;
left: 565px;
h1 { font-size: 5rem; }
p { font-size: 2.5rem; }
}
&::before {
content: '';
position: absolute;
z-index: 1;
top: 0; left: 0; right: 0; bottom: 0;
background-image: url(../meerkat.jpg);
background-origin: content-box;
background-repeat: no-repeat;
background-position-x: 0;
background-position-y: 0;
background-size: auto 589px;
}
}
Ich habe das Hintergrundbild an a angehängt ::before
Pseudoelement, damit ich Containerabfragen darauf verwenden kann (da Container sich nicht selbst abfragen können). Wir werden dies später aufbewahren, damit wir es verwenden können Inline-Containerabfrage (cqi
) Einheiten. Hier ist zunächst die Containerabfrage, die nur die Werte anzeigt, die wir fließend machen werden:
@container (max-width: 800px) {
#hero {
.details {
top: 50px;
left: 20px;
h1 { font-size: 3.5rem; }
p { font-size: 2rem; }
}
&::before {
background-position-x: -310px;
background-position-y: -25px;
background-size: auto 710px;
}
}
}
Sie können sehen, wie der Code in a ausgeführt wird Live-Demo – Es ist völlig statisch, die Grenzen eines typischen Ansatzes aufzuzeigen.
Lassen Sie uns flüssig werden
Jetzt können wir diese Start- und Endpunkte für die Größe und Position von Text und Hintergrund verwenden und sie fließend gestalten. Die Textgröße verwendet flüssige Typografie auf eine Weise, die Sie bereits kennen. Hier ist das Ergebnis – ich erkläre die Ausdrücke, sobald Sie sich den Code angesehen haben.
Zuerst die Änderungen an der Position und Größe des Textes:
/* Line changes
* -12,27 +12,32
*/
.details {
/* ... lines 14-16 unchanged */
/* Evaluates to 50px for a 360px wide container, and 220px for 1200px */
top: clamp(50px, 20.238cqi - 22.857px, 220px);
/* Evaluates to 20px for a 360px wide container, and 565px for 1200px */
left: clamp(20px, 64.881cqi - 213.571px, 565px);
/* ... lines 20-25 unchanged */
h1 {
/* Evaluates to 3.5rem for a 360px wide container, and 5rem for 1200px */
font-size: clamp(3.5rem, 2.857rem + 2.857cqi, 5rem);
/* ... font-weight unchanged */
}
p {
/* Evaluates to 2rem for a 360px wide container, and 2.5rem for 1200px */
font-size: clamp(2rem, 1.786rem + 0.952cqi, 2.5rem);
}
}
Und hier ist die Hintergrundposition und -größe für das Erdmännchenbild:
/* Line changes
* -50,3 +55,8
*/
/* Evaluates to -310px for a 360px wide container, and 0px for 1200px */
background-position-x: clamp(-310px, 36.905cqi - 442.857px, 0px);
/* Evaluates to -25px for a 360px wide container, and 0px for 1200px */
background-position-y: clamp(-25px, 2.976cqi);
/* Evaluates to 710px for a 360px wide container, and 589px for 1200px */
background-size: auto clamp(589px, 761.857px - 14.405cqi, 710px);
Jetzt können wir die Containerabfrage vollständig fallen lassen.
Lassen Sie uns diese erklären clamp()
Ausdrücke. Wir beginnen mit dem Ausdruck für top
Eigentum.
/* Evaluates to 50px for a 360px wide container, and 220px for 1200px */
top: clamp(50px, 20.238cqi - 22.857px, 220px);
Sie werden bemerkt haben, dass es dort einen Kommentar gibt. Diese Ausdrücke sind ein gutes Beispiel dafür Magische Zahlen sind eine schlechte Sache. Aber wir können sie hier nicht vermeiden, da sie das Ergebnis der Lösung einiger gleichzeitiger Gleichungen sind – was CSS nicht kann!
Die oberen und unteren Grenzen werden übergeben clamp()
sind klar genug, aber der Ausdruck in der Mitte stammt aus diesen simultanen Gleichungen:
f + 12v = 220
f + 3.6v = 50
…Wo f
ist die Anzahl der Längeneinheiten fester Größe (d. h. px
) Und v
ist die Einheit variabler Größe (cqi
). In der ersten Gleichung sagen wir, dass der Ausdruck ausgewertet werden soll 220px
Wann 1cqi
ist gleich 12px
. In der zweiten Gleichung sagen wir, wir wollen 50px
Wann 1cqi
Ist 3.6px
was zu Folgendem führt:
f = -22.857
v = 20.238
…und das schafft Ordnung 20.238cqi – 22.857px
in einem calc()
-freundlicher Ausdruck.
Wenn die feste Einheit unterschiedlich ist, müssen wir die Größe der variablen Einheiten entsprechend ändern. Also für die
Elemente font-size
wir haben;
/* Evaluates to 2rem for a 360px wide container, and 2.5rem for 1200px */
font-size: clamp(2rem, 1.786rem + 0.952cqi, 2.5rem);
/* Evaluates to 2rem for a 360px wide container, and 2.5rem for 1200px */
font-size: clamp(2rem, 1.786rem + 0.952cqi, 2.5rem);
Dies löst diese Gleichungen, da bei einer Containerbreite von 1200px
, 1cqi
ist das gleiche wie 0.75rem
(meine Rems sind relativ zum Standard-UA-Stylesheet, 16px
) und bei 360px
breit, 1cqi
Ist 0.225rem
.
f + 0.75v = 2.5
f + 0.225v = 2
Dies ist wichtig zu beachten: Die Gleichungen unterscheiden sich je nachdem, auf welche Einheit Sie abzielen.
Ehrlich gesagt ist das jedes Mal langweilige Mathematik Ich habe einen Taschenrechner erstellt, den Sie verwenden können. Es löst nicht nur die Gleichungen für Sie (bis auf drei Dezimalstellen, um Ihr CSS sauber zu halten), sondern bietet auch einen hilfreichen Kommentar, den Sie neben dem Ausdruck verwenden können, damit Sie sehen können, woher sie kommen, und magische Zahlen vermeiden können. Fühlen Sie sich frei, es zu verwenden. Ja, es gibt viele ähnliche Taschenrechner, aber sie konzentrieren sich auf Typografie und sind daher (zu Recht) darauf fixiert rem
Einheiten. Sie könnten das JavaScript wahrscheinlich portieren, wenn Sie einen CSS-Präprozessor verwenden.
Der clamp()
Die Funktion ist an dieser Stelle nicht unbedingt erforderlich. In jedem Fall sind die Grenzen von clamp()
werden auf die Werte gesetzt, wenn der Container entweder ist 360px
oder 1200px
breit. Da der Container selbst durch die Einstellung auf diese Grenzen beschränkt ist min-width
Und max-width
Werte – die clamp()
Der Ausdruck sollte niemals eine der beiden Bindungen aufrufen. Allerdings behalte ich es lieber clamp()
für den Fall, dass wir jemals unsere Meinung ändern (was wir gleich tun werden), denn implizite Grenzen wie diese sind schwer zu erkennen und aufrechtzuerhalten.
Verletzungen vermeiden
Wir könnten unsere Arbeit als erledigt betrachten, aber das sind wir noch nicht. Das Layout funktioniert immer noch nicht ganz. Der Text verläuft direkt über dem Kopf des Erdmännchens. Obwohl man mir versichert hat, dass dies dem Erdmännchen keinen Schaden zufügt, gefällt mir das Aussehen nicht. Nehmen wir also einige Änderungen vor, damit der Text nicht auf das Erdmännchen trifft.
Das erste ist einfach. Wir bewegen das Erdmännchen schneller nach links, damit es ihm aus dem Weg geht. Dies lässt sich am einfachsten erreichen, indem man das untere Ende der Interpolation auf einen breiteren Container umstellt. Wir stellen es so ein, dass das Erdmännchen vollständig zurückbleibt 450px
statt auf 360px
. Es gibt keinen Grund, warum die Start- und Endpunkte für alle unsere flüssigen Ausdrücke auf die gleiche Breite ausgerichtet sein müssen, damit wir die anderen Ausdrücke auf flüssig beschränken können 360px
.
Mit meinem zuverlässigen Taschenrechner müssen wir nur das ändern clamp()
Ausdrücke für die background-position
Eigenschaften:
/* Line changes
* -55,5 +55,5
*/
/* Evaluates to -310px for a 450px wide container, and 0px for 1200px */
background-position-x: clamp(-310px, 41.333cqi - 496px, 0px);
/* Evaluates to -25px for a 450px wide container, and 0px for 1200px */
background-position-y: clamp(-25px, 3.333cqi - 40px, 0px);
Das verbessert die Dinge, aber nicht vollständig. Ich möchte es nicht noch schneller verschieben, also schauen wir uns als Nächstes den Weg an, den der Text nimmt. Im Moment bewegt es sich geradlinig, etwa so:

Aber können wir es biegen? Ja, das können wir.
Eine Kurve im Weg
Eine Möglichkeit, dies zu erreichen, besteht darin, zwei verschiedene Interpolationen für zu definieren top
Koordinate, die die Linie in verschiedenen Winkeln platziert, und dann den kleinsten Winkel auswählen. Auf diese Weise kann die steilere Linie bei größeren Behälterbreiten „gewinnen“, und die flachere Linie wird zum Wert, der gewinnt, wenn der Behälter schmaler als etwa ist 780px
. Das Ergebnis ist eine Linie mit einer Krümmung, die das Erdmännchen verfehlt.
Alles, was wir ändern, ist der Spitzenwert, aber wir müssen zuerst zwei Zwischenwerte berechnen:
/* Line changes
* -18,2 +18,9 @@
*/
/* Evaluates to 220px for a 1200px wide container, and -50px for 360px */
--top-a: calc(32.143cqi - 165.714px);
/* Evaluates to 120px for a 1200px wide container, and 50px for 360px */
--top-b: calc(20px + 8.333cqi);
/* By taking the max, --topA is used at lower widths, with --topB taking over when wider.
We only need to apply clamp when the value is actually used */
top: clamp(50px, max(var(--top-a), var(--top-b)), 220px);
Anstatt diese Werte formal anhand eines sorgfältig gewählten Mittelpunkts zu berechnen, experimentierte ich mit den Endpunkten, bis ich das gewünschte Ergebnis erhielt. Experimente sind genauso sinnvoll wie Berechnungen, um das gewünschte Ergebnis zu erzielen. In diesem Fall habe ich mit Duplikaten der Interpolation in benutzerdefinierten Variablen begonnen. Ich hätte den Pfad mithilfe einer Containerabfrage in explizite Abschnitte aufteilen können, aber das verringert nicht den mathematischen Aufwand und die Verwendung von min()
Die Funktion ist für mein Auge sauberer. Außerdem geht es in diesem Artikel nicht ausschließlich um Containerabfragen, oder?
Nun bewegt sich der Text entlang dieses Pfades. Öffne das Live-Demo um es in Aktion zu sehen.

CSS kann nicht alles
Als letzte Anmerkung zu den Berechnungen sei darauf hingewiesen, dass es Einschränkungen hinsichtlich dessen gibt, was wir tun können und was nicht. Das erste, das wir bereits ein wenig abgeschwächt haben, ist, dass diese Interpolationen linear sind. Das bedeutet, dass ein nachlassendes Ein- oder Aussteigen oder ein anderes komplexes Verhalten nicht möglich ist.
Eine weitere große Einschränkung besteht darin, dass CSS auf diese Weise nur Längenwerte generieren kann. Daher gibt es in reinem CSS keine Möglichkeit, beispielsweise Deckkraft oder einen Drehwinkel anzuwenden, der basierend auf der Container- oder Ansichtsfenstergröße fließend ist. Auch Präprozessoren können uns hier nicht weiterhelfen, da die Einschränkung auf dem Weg ist calc()
Funktioniert im Browser.
Beide Einschränkungen können aufgehoben werden, wenn Sie bereit sind, sich auf ein wenig JavaScript zu verlassen. Es sind lediglich ein paar Zeilen erforderlich, um die Breite des Containers zu beobachten und eine benutzerdefinierte CSS-Eigenschaft ohne Einheiten festzulegen. Ich werde das verwenden, um den Text einer quadratischen Bezier-Kurve folgen zu lassen, etwa so:

Es gibt zu viel Code, um ihn hier aufzulisten, und zu viel Mathematik, um die Bezier-Kurve zu erklären, aber schauen Sie sich das in Aktion an diese Live-Demo.
Wir bräuchten nicht einmal JavaScript, wenn Ausdrücke wie calc(1vw / 1px)
ist in CSS nicht fehlgeschlagen. Es gibt keinen Grund, sie zu versagen, da sie ein Verhältnis zwischen zwei Längen darstellen. So wie es sie gibt 2.54cm
In 1in
es gibt 8px
In 1vw
wenn das Ansichtsfenster ist 800px
breit, also calc(1vw / 1px)
sollte zu einer Einheit ohne Einheit ausgewertet werden 8
Wert.
Sie scheitern jedoch, also können wir nur unseren Standpunkt darlegen und weitermachen.
Flüssiges Alles löst nicht alle Layouts
Natürlich wird es immer einige Layouts geben, die Größenabfragen erfordern; Einige Designs müssen Änderungen einfach an festen Haltepunkten einrasten lassen. Es gibt keinen Grund, das zu vermeiden, wenn es richtig ist. Es gibt auch keinen Grund, eine Vermischung der beiden zu vermeiden, indem man beispielsweise die Größe und Positionierung des Hintergrunds fließend verändert und gleichzeitig eine Abfrage verwendet, um zwischen Rasterdefinitionen für die Textplatzierung zu wechseln. Mein Erdmännchen-Beispiel ist aus Demonstrationsgründen bewusst einfach gehalten.
Eine Sache, die ich hinzufügen möchte, ist, dass ich von der Möglichkeit, das Neue zu nutzen, ziemlich begeistert bin Ankerpositionierungs-API für flüssige Positionierung. Es besteht die Möglichkeit, die Ankerpositionierung zu verwenden, um zu definieren, wie zwei Elemente zusammen über den Bildschirm fließen könnten, aber das steht auf einem anderen Blatt.
[ad_2]
Source link