Der Unterschied zwischen einer guten CSS-Erfahrung und einer langen, frustrierenden liegt oft in wenigen kleinen Details. CSS ist tatsächlich nuanciert. Einer der häufigsten Bereiche, in denen ich Schwierigkeiten sehe, ist das Layout. Persönlich studiere ich gerne Muster. Ich merke, dass ich dazu neige, eine kleine Gruppe von Mustern zu verwenden, um die Mehrheit meiner Layout-Probleme zu lösen. Dieser Artikel handelt von diesen CSS-Mustern, die ich verwende, um Layout-Herausforderungen zu meistern. Es geht auch darum, Situationen unvoreingenommen anzugehen, unabhängig von den verwendeten CSS-Methoden, sei es SMACSS, BEM oder sogar das heiß diskutierte CSS-in-JS, da sie sich alle auf die Eigenschaften selbst konzentrieren und nicht auf Architektur, Organisation oder Strategie.
Zum Spaß, fangen wir mit einem Test an
Wir werden eine Plattform verwenden, die ich zufällig erstellt habe, namens Questionable.io, und ich habe sie verwendet, um einen Test zu erstellen, den wir unten finden. Keine Sorge, es werden keine persönlichen Daten gesammelt, die Ergebnisse sind anonym und es ist völlig kostenlos.
Der Zweck des Tests ist es zu sehen, ob Sie spezifische CSS-Verhaltensweisen und Probleme im Kontext erkennen können, ohne zuerst mit dem Material konfrontiert zu werden. Ich habe nicht versucht, den Test schwierig zu machen, aber die Nuancen von CSS-Layouts sind tendenziell etwas komplex, besonders ohne viel Erfahrung damit. Denken Sie daran, das alles ist zum Spaß. Die Ergebnisse sind keine Indikation für Ihre Großartigkeit, aber hoffentlich ziehen Sie daraus einen Nutzen.
Der Test umfasst 10 Fragen und sollte 10 Minuten oder weniger dauern.
Machen Sie den CSS-Layout-Quiz
Interessiert am Test, möchten ihn aber nicht machen? Hier ist ein Link zu den Fragen mit den richtigen Antworten.
Schon fertig? Großartig! Gehen wir die Fragen eins nach dem anderen durch, um ein besseres Verständnis der im Test behandelten Layout-Muster zu bekommen.
Frage 1: Box-Modell
Das Erlernen des Box-Modells sollte für jeden ganz oben auf der Prioritätenliste stehen. Obwohl dieser Artikel über das CSS-Box-Modell von CSS-Tricks etwas alt sein mag, unterschätzen Sie seinen Wert und seine Relevanz für modernes CSS nicht. Das Box-Modell ist Grundvoraussetzung für fast jedes CSS-Thema im Zusammenhang mit Layout.
Diese spezielle Frage testet, wie die *berechnete* Breite des Box-Modells ermittelt wird. Die Box hat offensichtlich width: 100px;, aber es stellt sich heraus, dass die Standardregeln des Box-Modells die width-Eigenschaften auf die Inhaltsebene der Box anwenden. Die berechnete Breite (wie breit sie auf der Seite gerendert wird) ist die Summe aus Inhaltsebene, Padding-Ebene und Randebene. Aus diesem Grund ist die Antwort 112px.
.box {
width: 100px; /* Take this */
height: 50px;
padding: 5px; /* Plus this x2 for left and right */
border: 1px solid red; /* Plus this x2 for left and right */
background-color: red;
/* = 112px of computed width */
}
Wenn Sie auf eine Situation gestoßen sind, in der die letzte Spalte oder der letzte Tab in einer Benutzeroberfläche nach unten umgebrochen ist und Sie sicher waren, dass fünf Tabs (alle auf width: 20%; eingestellt) sich zu 100 % summieren, dann ist es sehr gut möglich, dass dies das Problem war. Fünf Tabs mit 20 % Breite ergeben zwar 100 %, aber wenn Padding und/oder Ränder beteiligt sind, addieren sich diese zur Breite, sodass nicht genügend Platz für den letzten Tab auf derselben Zeile vorhanden ist.
Um die Einführung von CSS3 herum kam ein neues Werkzeug namens box-sizing zu CSS. Dies ermöglicht es uns, zu ändern, auf welche Ebene des Box-Modells wir width anwenden möchten. Zum Beispiel können wir box-sizing: border-box; verwenden, was bedeutet, dass wir möchten, dass alle width-Regeln außerhalb der Randebene und nicht der Inhaltsebene angewendet werden. In dieser Testfrage wäre die berechnete Breite 100 Pixel, wenn box-sizing: border-box; angewendet worden wäre.
Das ist für einige von Ihnen nichts Neues, aber eine gute Erinnerung für Profis und Anfänger gleichermaßen.
Es gibt eine Reihe von Artikeln über das Box-Modell und wie man box-sizing als Reset verwendet, so dass es auf Ihr gesamtes Projekt auf einmal angewendet wird. Box Sizing und Inheriting box-sizing Probably Slightly Better Best-Practice sind zwei großartige Artikel direkt auf CSS-Tricks, um damit zu beginnen.
Frage 2: Ränder sind aufdringlich
Die zweite Testfrage könnte fast als „Teil Zwei“ der ersten Frage betrachtet werden. Denken Sie daran, es ist eine Sache zu lesen: „Das Box-Modell hat Ebenen und sie alle tragen zur berechneten Breite und Höhe bei.“ Es ist etwas anderes, ein Box-Modell-Problem in einer realen Situation erkennen zu können. Dieses spezielle Problem ist unter denen, die schon eine Weile mit CSS arbeiten, ein Klassiker. Es ergibt sich aus der Tatsache, dass Ränder Platz einnehmen und Dinge verschieben, da sie Teil des Box-Modells sind. Das Einführen von Rändern während eines Zustandsübergangs, wie z. B. :hover, bedeutet, dass Boxen größer werden und somit nachfolgende Boxen nach unten verschieben. Es kann auch zu einer ruckeligen Erfahrung führen.
Siehe den Pen CSS-Tricks: Borders are Dimension von Brad Westfall (@bradwestfall) auf CodePen.
Von allen möglichen Lösungen in der Testfrage wäre die Anwendung von border: 2px solid transparent im ursprünglichen „nicht-gehoverten“ Zustand die einzige, die das Problem behebt. box-sizing behebt dieses Problem nicht, da wir keine explizite Höhe festlegen. Hätten wir dies getan, wäre der Rand innerhalb der Höhe berücksichtigt worden und es hätte keine Verschiebung gegeben – aber das war hier nicht der Fall.
Es gibt auch andere Lösungen, die nicht als mögliche Antworten erwähnt wurden. Eine davon sind Faux-Ränder mit box-shadow und die andere ist die Verwendung von outline anstelle von border. Beides hätte dazu geführt, dass bei Zustandsänderungen keine Verschiebungen auftreten, da sie keine Ebenen im Box-Modell sind. Hier ist ein weiterer CSS-Tricks-Artikel, um mehr über diese Lösungen zu erfahren.
Beachten Sie, dass outline border-radius nicht unterstützt.
Frage 3: Absolute Position im Vergleich zu Fixed Position
Abgesehen davon, zu wissen, wann jede verwendet werden soll und wie sie sich im visuellen Verhalten unterscheiden, ist es auch sehr wichtig, die Regeln dafür zu kennen, wie jede Positionierungsmethode an ein Elternelement mit ihren top, right, bottom oder left Eigenschaften gebunden ist.
Zuerst, lassen Sie uns den Containing Block überprüfen. Die Kurzdefinition ist, dass ein Containing Block meistens das Elternelement jedes gegebenen Elements ist. Die Regeln für den Containing Block sind jedoch unterschiedlich zwischen absoluten und festen Elementen.
1. Für absolute Elemente: Der Containing Block ist der nächstgelegene Vorfahrene, der nicht static ist. Zum Beispiel, wenn ein Element absolut positioniert ist und top, right, bottom oder left Eigenschaften enthält, wird es relativ zu jedem Elternteil positioniert, das eine Position von absolute, relative, fixed oder sticky hat.
2. Für feste Elemente: Der Containing Block ist der Viewport, unabhängig von allen Elternteilen, die andere Positionswerte als static haben. Auch das Scrollverhalten ist anders als bei absolute, da position: fixed; Elemente beim Scrollen „fest“ im Viewport bleiben, daher der Name.
Viele Entwickler glauben, dass absolut positionierte Elemente nur den nächstgelegenen position: relative; Elternteil suchen. Dies ist ein weit verbreiteter Irrtum, einfach weil position: relative am häufigsten mit position: absolute; gepaart wird, um einen Containing Block zu erstellen. Der Grund, warum es häufig verwendet wird, ist, dass relative den Elternteil im Fluss hält, was oft das gewünschte Verhalten ist. Es gibt jedoch Zeiten, in denen der Containing Block eines absolut positionierten Elements ebenfalls absolut positioniert ist. Das ist je nach Situation völlig in Ordnung. Wenn alle Elternteile statisch sind, wird sich das absolut positionierte Element am Viewport orientieren – aber auf eine Weise, die mit dem Viewport scrollt.
Siehe den Pen CSS-Tricks: Position Absolute Scrolling von Brad Westfall (@bradwestfall) auf CodePen.
Es gibt einen weniger bekannten Vorbehalt zu den beiden obigen Regeln: Jedes Mal, wenn ein Elternteil eine transform-Eigenschaft hat (neben einigen anderen) mit einem Wert außer none, wird dieser Elternteil zum Containing Block für absolut und fest positionierte Elemente. Dies kann in diesem Pen beobachtet werden, wo die Notiz position: fixed; ist und der Elternteil transform hat, aber nur, wenn er gehovert wird.
Siehe den Pen CSS-Tricks: Containing Blocks von Brad Westfall (@bradwestfall) auf CodePen.
Frage 4: Kollabierende Ränder von Elternelementen und ersten/letzten Kindern
Das ist eines dieser CSS-Details, die dich wirklich beißen können, wenn du nicht weißt, wie es funktioniert. Es gibt ein CSS-Konzept namens Kollabierende Ränder und viele Leute sind mit der Form vertraut, die als Kollabierende Ränder von benachbarten Geschwistern bezeichnet wird. Es gibt jedoch eine weitere Form, die als Kollabierende Ränder von Elternelementen und ersten/letzten Kindern bezeichnet wird und weniger bekannt ist. Hier ist eine Demo von beiden.
Siehe den Pen CSS-Tricks: Collapsing Margins von Brad Westfall (@bradwestfall) auf CodePen.
Jeder Absatz hat einen oberen und unteren Rand von 1em, die vom Browser bereitgestellt werden. Das ist bisher der einfache Teil. Aber warum ist der Abstand zwischen den Absätzen nicht 2em (die Summe von oben und unten)? Das nennt man Kollabierende Ränder von benachbarten Geschwistern. Die Ränder überlappen sich so, dass der größere der beiden Ränder die Gesamtgröße des Abstands ist, somit ist der Abstand in diesem Fall 1em.
Es passiert jedoch noch etwas Seltsames. Haben Sie bemerkt, dass der obere Rand des ersten Absatzes keinen Abstand zwischen ihm und dem blauen Container-Div erzeugt? Anstatt eines Abstands, ist es fast so, als würde er den Rand zum Elternelement „beitragen“, als ob das Div den oberen Rand hätte. Das nennt man Kollabierende Ränder von Elternelementen und ersten/letzten Kindern. Diese Form der kollabierenden Ränder tritt unter bestimmten Umständen nicht auf, wenn das Elternelement eines der folgenden Elemente hat.
- Oberes/unteres Padding mit einem Wert größer als 0.
- Oberer/unterer Rand mit einer Breite größer als 0.
- Block Formatting Context, der durch Dinge wie
overflow: hidden;undoverflow: auto;erzeugt werden kann). display: flow-root(nicht gut unterstützt).
Wenn ich das Vergnügen habe, dieses kleine CSS-Detail zu erklären und es mit Padding oder Border zu lösen, ist die Antwort fast immer: „Was ist mit Padding oder Border von 0?“ Nun, das funktioniert nicht, weil der Wert eine positive Ganzzahl sein muss.
Im vorherigen Beispiel erlaubt uns bereits 1px Padding, zwischen der Verwendung und der Verhinderung von Eltern/Kind-kollabierenden Rändern zu wechseln. Der Abstand, der zwischen den ersten/letzten Absätzen und dem Elternteil angezeigt wird, ist das 1px Padding, aber jetzt wird der Rand auf der Innenseite des Containers berücksichtigt, da die Padding-Schicht eine Barriere bildet, die kollabierende Ränder verhindert.
Bezüglich der Frage bin ich zuversichtlich, dass Sie das Problem in dieser Benutzeroberfläche erkennen können.
Siehe den Pen CSS-Tricks: Parent/Child Collapsing Margins von Brad Westfall (@bradwestfall) auf CodePen.
Der erste .comment (ohne die Klasse .moderator) erlebt kollabierende Ränder. Selbst ohne den Code zu betrachten, sehen wir, dass der Moderator-Kommentar einen Rand hat und der Nicht-Moderator-Kommentar keinen. In der Frage gab es tatsächlich drei Antworten, die als korrekt galten. Jede von ihnen ist tatsächlich bereits im Quellcode des Pens angewendet, sie sind nur auskommentiert.
Ein Grund, warum diese Form der kollabierenden Ränder nicht so bekannt ist wie die anderen, ist die breite Palette an Möglichkeiten, wie wir sie „versehentlich“ vermeiden können. Flexbox und Grid-Elemente erstellen einen Block Formatting Context, sodass wir diese Form der kollabierenden Ränder dort nicht sehen. Wenn unsere „Kommentar“-Benutzeroberfläche ein echtes Projekt wäre, hätten wir wahrscheinlich auf allen vier Koordinaten Padding gehabt, um Abstände rundherum zu schaffen, was alle kollabierenden Ränder für uns beheben würde. So selten es auch sein mag, ich möchte nicht, dass Sie einen ganzen Tag damit verbringen, sich den Kopf zu zerbrechen, daher ist es gut, dies bei der Arbeit mit Layouts im Hinterkopf zu behalten.
Hier sind einige CSS-Tricks-Artikel zu diesem Thema.
Frage 5: Prozent von was?
Wenn es um die Verwendung von Prozenteinheiten geht, heißt es, dass der Prozentsatz auf der Breite oder Höhe des Containing Blocks basiert (normalerweise im Zusammenhang mit dem Elternelement). Wie wir bereits erwähnt haben, wird ein Element mit transform zu einem Containing Block. Wenn also ein Element transform verwendet, basieren die Prozenteinheiten (nur für transform) auf seiner eigenen Größe und nicht auf der des Elternelements.
In diesem Beispiel sehen wir, dass 50% je nach Kontext zwei verschiedene Dinge bedeuten. Der erste rote Block hat margin-left: 50%; und der zweite rote Block verwendet transform: translateX(50%);.
Siehe den Pen CSS-Tricks – Percentage and Transform von Brad Westfall (@bradwestfall) auf CodePen.
Frage 6: Das Box-Modell schlägt wieder zu... was für ein Kater!
Gerade als Sie dachten, wir wären fertig mit dem Box-Modell…
Siehe den Pen CSS-Tricks: Left: 0 Right: 0 von Brad Westfall (@bradwestfall) auf CodePen.
Der Kater rührt daher, dass wir width: 100%; für den Footer verwenden und auch Padding hinzufügen. Der Container ist 500 Pixel breit, was bedeutet, dass die Inhaltsebene des Footers (die 100 % beträgt) 500 Pixel breit ist, bevor das Padding auf die Außenseite dieser Ebene angewendet wird.
Der Kater kann mit einer dieser beiden gängigen Techniken behoben werden:
- Verwenden Sie
box-sizingdirekt auf dem Footer oder über ein Reset, wie wir es bereits besprochen haben. - Entfernen Sie die
widthund verwenden Sie stattdessenleft: 0; right: 0;. Dies ist ein großartiger Anwendungsfall dafür, einenleft-Wert und einenright-Wert gleichzeitig zu verwenden. Dadurch werden Box-Modell-Probleme vermieden, da diewidthihren Standardwertautoverwendet, um jeden verfügbaren Platz zwischen Padding und Rändern einzunehmen, wennleft: 0; right: 0;gesetzt sind.
Eine der Optionen war „Entferne das Padding vom Footer“. Dies würde *technisch* funktionieren, um den Kater zu beheben, da die Inhaltsebene, die 100% beträgt, kein Padding oder Rand hätte, um sie über die Breite des Containers hinaus zu erweitern. Aber ich denke, diese Lösung ist der falsche Ansatz, da wir unsere Benutzeroberfläche nicht ändern sollten, um Box-Modell-Probleme zu berücksichtigen, die leicht vermieden werden können.
Die Realität für mich ist, dass ich box-sizing: border-box; immer als Teil meines Resets habe. Wenn Sie das auch tun, dann sehen Sie dieses Problem vielleicht nicht oft. Aber ich mache den left: 0; right: 0;-Trick trotzdem gerne, weil er im Laufe der Zeit stabiler war (zumindest meiner Erfahrung nach) als sich mit Box-Modell-Problemen auseinandersetzen zu müssen, die aus width: 100%; auf positionierten Elementen entstehen.
Frage 7: Zentrierung von absoluten und festen Elementen
Jetzt kombinieren wir wirklich die meisten der bisherigen Materialien mit der Zentrierung von absoluten und festen Elementen.
Siehe den Pen CSS-Tricks: Modal (Lightbox) Centering von Brad Westfall (@bradwestfall) auf CodePen.
Da wir bereits die meisten Materialien in dieser Testfrage behandelt haben, werde ich einfach darauf hinweisen, dass horizontale und vertikale Zentrierung auf die „alte Schule Weise“ mit negativen Rändern oder die neuere „irgendwie alte Schule, aber immer noch gut“ Weise mit Transformationen erfolgen kann. Hier ist ein erstaunlicher CSS-Tricks-Leitfaden zu allen Dingen der Zentrierung.
Früher hieß es, wenn wir die Breite und Höhe der Box kennen, sollten wir negative Ränder verwenden, da diese stabiler sind als Übergänge, die neu für Browser waren. Jetzt, da Übergänge stabil sind, verwende ich sie fast immer dafür, es sei denn, ich muss einen Containing Block vermeiden.
Wissen Sie auch, dass wir hier keine margin: auto;-Tricks verwenden können, da wir möchten, dass sich Modale über den Inhalt „legen“, weshalb position normalerweise verwendet wird, um sie aus dem Normal Flow herauszunehmen.
Wo wir gerade dabei sind, kommen wir zur nächsten Frage, die sich mit der Zentrierung im Normal Flow beschäftigt.
Frage 8: Zentrierung von Elementen mit Normal Flow
Flexbox hat uns viele erstaunliche Werkzeuge zur Lösung schwieriger Layout-Probleme gebracht. Vor seiner Veröffentlichung hieß es, vertikales Zentrieren sei eines der schwierigsten Dinge in CSS. Jetzt ist es einigermaßen trivial.
.parent { display: flex; }
.child { margin: auto; }
Siehe den Pen CSS-Tricks: Flexbox Centering (Vertical and Horizontal) von Brad Westfall (@bradwestfall) auf CodePen.
Beachten Sie, dass bei Flexbox-Elementen margin: auto oben, rechts, unten und links angewendet wird, um vertikal und horizontal zu zentrieren. Vertikales Zentrieren mit auto funktionierte in der Vergangenheit bei Block-Level-Elementen nicht, weshalb margin: 0 auto üblich ist.
Frage 9: Berechnen gemischter Einheiten
Die Verwendung von calc() ist perfekt, wenn zwei Einheiten, die wir nicht selbst addieren können, gemischt werden müssen oder wenn wir Brüche einfacher lesbar machen müssen. Diese Testfrage fordert uns auf, herauszufinden, was calc(100% + 1em) sein würde, basierend auf der Tatsache, dass die Breite des Divs 100px beträgt. Dies war ein wenig knifflig, weil es tatsächlich keine Rolle spielt, dass das Div 100 Pixel breit ist. Der Prozentsatz basiert auf der Breite des Elternelements, daher ist die Antwort: *Was auch immer 100 % der Breite des Containing Blocks (Elternteil) plus 1em sind*.
Es gibt ein paar Schlüsselbereiche, in denen ich regelmäßig auf calc() zurückgreife. Einer davon ist, wenn ich etwas um 100 % versetzen möchte, aber auch einen festen zusätzlichen Betrag hinzufügen möchte. Dropdown-Menüs können ein gutes Beispiel dafür sein.
Siehe den Pen CSS Tricks: Calculate Mixed Units von Brad Westfall (@bradwestfall) auf CodePen.
Der Trick hier ist, dass wir ein „Dropdown-System“ erstellen möchten, bei dem das Dropdown-Menü mit unterschiedlichen Auslösergrößen (in diesem Fall zwei verschiedene Button-Größen) verwendet werden kann. Wir wissen nicht, wie hoch der Auslöser sein wird, aber wir wissen, dass top: 100%; oben im Menü und ganz unten am Auslöser platziert wird. Wenn jedes Menü am unteren Rand seines jeweiligen Auslösers plus 0,5em sein muss, dann kann das mit top: calc(100% + 0.5em); erreicht werden. Sicher, wir könnten auch top: 110%; verwenden, aber diese zusätzlichen 10 % wären kontextabhängig von der Höhe des Auslösers *und* des Containers.
Frage 10: Negative Ränder
Im Gegensatz zu positiven Rändern, die von ihren Geschwistern wegdrängen, ziehen negative Ränder sie enger zusammen, *ohne die Geschwisterelemente zu verschieben*. Diese letzte Testfrage bietet zwei Lösungen, die technisch funktionieren, um den doppelten Rand in unserer Button-Gruppe zu eliminieren, aber ich bevorzuge die Technik mit negativen Rändern, da das Entfernen von Rändern das Ausführen bestimmter Tricks wie dieses Hover-Effekts viel schwieriger machen würde.
Siehe den Pen CSS Tricks: Negative Margins with Button Groups von Brad Westfall (@bradwestfall) auf CodePen.
Der Effekt ist ein „gemeinsamer Rand“, der zwischen den Buttons angezeigt wird. Buttons können tatsächlich keinen gemeinsamen Rand teilen, daher benötigen wir diesen Trick mit negativen Rändern, um die beiden Ränder überlappen zu lassen. Dann verwende ich einen z-index, um zu steuern, welcher Rand je nach Hover-Zustand oben liegen soll. Beachten Sie, dass z-index hier auch ohne absolute Positionierung nützlich ist, aber ich musste position: relative setzen. Hätte ich die Technik verwendet, den linken Rand des zweiten Buttons zu entfernen, wäre dieser Effekt schwieriger zu erzielen gewesen.
Das summiert sich!
Es gibt noch eine letzte Demo, die ich Ihnen zeigen möchte und die viele der bisher besprochenen Tricks nutzt. Die Aufgabe ist es, UI-Kacheln zu erstellen, die sich bis zu den linken und rechten Kanten des Containers mit Abständen erstrecken. Mit Kacheln meine ich die Fähigkeit, eine Liste von Blöcken zu haben, die sich in die nächste Zeile umbrechen, wenn kein Platz mehr vorhanden ist. Hovern Sie über die Kacheln, um den vollen Effekt zu sehen.
Siehe den Pen CSS-Tricks: Flexbox Tiles (Edge-to-Edge) von Brad Westfall (@bradwestfall) auf CodePen.
Die Hürde bei dieser Aufgabe sind die Abstände. Ohne Abstände wäre es trivial, die Kacheln an den linken und rechten Rand des Containers zu bringen. Das Problem ist, dass die Abstände durch den Rand erzeugt werden, und wenn wir allen Seiten der Kachel einen Rand hinzufügen, erzeugen wir zwei Probleme:
- Drei Kacheln mit
width: 33,33%;in Kombination mit Margin bedeuten, dass drei Kacheln nicht in eine Zeile passen. Währendbox-sizinges uns erlaubt, Padding und Ränder auf der.tilezu haben, die innerhalb von 33,33 % enthalten sind, hilft es uns nicht bei den Rändern – das bedeutet, dass die berechnete Breite der drei Kacheln mehr als 100 % beträgt, was die letzte Kachel in die nächste Zeile zwingt. - Kacheln ganz links und ganz rechts berühren die Kanten des Containers nicht mehr.
Das erste Problem kann mit calc((100% / 3) - 1em) gelöst werden. Das sind 33,33 % abzüglich der linken und rechten Ränder jeder Kachel. Kollabierende Ränder von benachbarten Geschwistern gelten hier nicht, da es so etwas wie kollabierende Ränder bei linken und rechten Rändern nicht gibt. Infolgedessen ist der horizontale Abstand zwischen jeder Kachel die Summe der beiden Ränder (1em). Dies gilt auch nicht in diesem Fall für die oberen und unteren Ränder, da die erste und die vierte Kachel technisch gesehen keine benachbarten Geschwister sind, auch wenn sie visuell zufällig direkt nebeneinander liegen.
Mit dem calc()-Trick passen drei Kacheln auf eine Zeile, aber sie reichen immer noch nicht bis zu den Rändern des Containers. Dafür können wir negative Ränder in der Höhe des linken und rechten Randes jeder Kachel verwenden. Die grüne gepunktete Linie im Beispiel ist der Container, auf den wir negative Ränder anwenden, um die Kacheln so zu ziehen, dass sie dem Rand des umgebenden Inhalts entsprechen. Wir sehen, wie sie in den Padding-Bereich ihres Elternelements (das main-Element) hineinragen. Das ist in Ordnung, da negative Ränder benachbarte Elemente nicht verschieben.
Das Endergebnis ist, dass die Kacheln schöne Abstände haben, die von Kante zu Kante reichen, so dass sie an den angrenzenden Absatz-Tags außerhalb der Kacheln ausgerichtet sind.
Es gibt viele Möglichkeiten, Kacheln zu lösen (und sie haben normalerweise ihre eigenen Vor- und Nachteile). Zum Beispiel gibt es eine ziemlich elegante Lösung mit CSS Grid, die von Heydon Pickering diskutiert wird und die mit einer Technik, die Containerabfragen imitiert (aber mit Grid-Magie), responsiv ist. Letztendlich ist seine Grid-Lösung für Kacheln viel schöner als die Flexbox-Lösung, die ich vorgestellt habe, aber sie hat auch weniger Browserunterstützung. Dennoch ist die Flexbox-Lösung immer noch eine großartige Möglichkeit, alle Tricks aus diesem Artikel gleichzeitig zu demonstrieren.
Vielleicht kennst du Heydons Arbeit bereits. Er ist bekannt für clevere Tricks wie den Lobotomized Owl Selektor. Wenn du ihn nicht kennst, ist es sicherlich lohnenswert, ihn kennenzulernen, und ich habe ein Video, in dem ich darüber spreche.
Zusammenfassung
Ich habe am Anfang gesagt, dass ich dazu neige, nach Mustern zu suchen, wenn ich Probleme löse. Dieser Artikel handelt nicht unbedingt von den exakten Demo-Szenarien von oben; es geht mehr um eine Reihe von Werkzeugen, die verwendet werden können, um diese und viele andere Layout-Probleme zu lösen, denen wir wahrscheinlich alle begegnen werden. Ich hoffe, diese Werkzeuge bringen dich weit und ich freue mich darauf, deine Beiträge in den Kommentaren zu hören.
Übrigens gibt es eine Reihe von ausgezeichneten Ressourcen, die das Box-Modell gründlich behandeln, insbesondere die von Rachel Andrews und Jen Simmons, die es sich auf jeden Fall lohnt, anzuschauen. Rachel hat sogar einen Newsletter, der ausschließlich dem Layout gewidmet ist.
- Box Alignment Cheatsheet – Großartige Ressource mit visuellen Darstellungen, die die verschiedenen Eigenschaften hervorheben, die beeinflussen, wie Elemente ausgerichtet werden, entweder für sich allein oder relativ zu anderen Elementen.
- Jen Simmons Labs – Eine Fülle von hilfreichen Beiträgen, Demos und Experimenten mit modernen Layout-Methoden.
Ich glaube, die Antwort auf Frage 9 ist falsch.
margin-left:100% wird nicht 100px (die Div-Breite) sein, es wird die Breite des enthaltenden Blocks sein (nehmen wir hier den Viewport an). Daher sollte die Antwort die Breite des enthaltenden Blocks + 1 em sein.
Es sei denn, ich irre mich :)
Sie haben Recht. Ich habe die Frage und den Artikel entsprechend aktualisiert. Danke für den Fund, Paul!
Die Webseite des Fragebogens (https://app.questionable.io/test-review/527/pZnrnE6z) erlaubte weder in Firefox noch in Chrome unter Linux Mint Klicks/Auswahlen von Antworten. Zur Info…
Danke Vanderson, das ist der Link für den „Test-Review“-Modus. Er erlaubt kein Hervorheben/Kopieren von Code. Der Testmodus tut das tatsächlich auch nicht. Der Grund ist, dass Questionable.io am häufigsten für Beurteilungen bei Einstellungen verwendet wird und dies dazu gedacht ist, Testteilnehmer davon abzuhalten, Antworten leicht durch Kopieren/Einfügen nachzuschlagen.
Ich bin etwas verwirrt wegen Frage Nr. 9. Sollte die richtige Antwort nicht „die Breite des Containers des Elements plus 1em“ lauten, nicht die Breite des Elements selbst plus 1em? Hier ist das Beispiel, bei dem das Element mit den gegebenen Stilen einen anderen resultierenden Rand hat als die Antwort vermuten lässt: http://jsfiddle.net/kt9q3x5z/
Ja, Paul hat das oben angesprochen. Es ist jetzt behoben. Danke, Ilya.
Zu Frage 7: Ich dachte, transform/translate könnten zu verschwommenen Kanten und anders gerendertem Text führen (vielleicht gab es kein Subpixel-Anti-Aliasing?). Es ist also gut für Animationen, bei denen subtile Unschärfe nicht auffällt, aber nicht für statische Elemente wie dieses Modal. Aber das Modal sieht perfekt aus. Erinnere ich mich falsch? Kein Problem mehr?
Ich glaube, das passiert in einigen Fällen, aber nicht in allen. Ich erinnere mich nicht mehr genau.
#Frage 6 ist irreführend.
Die Frage lautet: „Welche dieser Lösungen behebt den Überhang?“ Und „Entferne den Rand am Footer“ behebt definitiv den Überhang, daher sollte es nicht als falsche Antwort betrachtet werden.
Wenn Sie nach einer Antwort suchen, die die Benutzeroberfläche nicht verändert, machen Sie in der Frage deutlich, dass die Benutzeroberfläche nicht verändert werden soll.
Ich schätze das Feedback Ian, wirklich! Aber ich stimme einfach nicht zu. Wenn eine Lösung die Benutzeroberfläche auf drastisch negative Weise verändert, ist sie keine gute Lösung, besonders wenn eine andere Lösung, die so einfach ist, die Benutzeroberfläche gar nicht verändert. Denken Sie auch daran, dass es nur zum Spaß ist und die Fragen nicht der Kernpunkt sein sollten, sondern der Inhalt.
Außerdem, wenn es einen Innenabstand am Container gibt oder Inhalt vorhanden ist, würde „left: 0; right: 0;“ den Footer immer noch größer machen als seinen sichtbaren Inhalt.
Verstehe ich einfach nicht, was Sie mit „Verwenden Sie calc(), um die Mitte mit oben und links zu messen“ bei Frage 7 meinen? Denn das Vertauschen der negativen Ränder gegen `calc()`-ierte Links/Oben-Eigenschaften ist ebenfalls eine Lösung für dieses Problem.
Hallo Jesse, tut mir leid, dass es verwirrend war. Wenn ich jetzt darüber nachdenke, haben Sie Recht. Ich werde eine bessere „falsche“ Antwort finden.
Ich habe 1 falsch und mir nicht bewusst, dass eine der früheren Fragen mehrere Antworten zuließ. Nur eine der späteren Fragen enthielt Anweisungen, die eindeutig darauf hindeuteten, dass ich mehr als eine Antwort auswählen könnte.
Schöner Test, habe 9 von 12 richtig gemacht.
Es wäre toll gewesen, die Fragen mit mehreren Antwortmöglichkeiten mit einer Checkbox und nicht mit einem Radio-Button anzuzeigen, ich schätze, viele Leute werden das übersehen.
Das hat mich auch erwischt. Radio-Buttons implizieren stark, dass nur eine Antwort ausgewählt werden kann.
Danke für den Artikel und den lustigen Test :)
Hoffentlich stört es Sie nicht, dass ich Vorschläge zur Verbesserung des Tests mache :)
Erstens
Ich kann Frage 4 nicht verstehen; Ich denke und denke und denke, ich kann keine andere Erklärung finden als: Sie müssen einen Fehler gemacht haben :D
Wie kann ein Rand an einem Element dazu führen, dass sein eigener Hintergrund und Rand erweitert werden?
Und warum passiert das nur im Gelben, nicht im Blauen?
Der Pen unterstützt meine Behauptung, was mich ziemlich erleichtert hat :D https://codepen.io/katerlouis/pen/dwrxaQ – bitte klären Sie mich auf, wenn ich hier etwas übersehe.
Frage 6 ist etwas unfair und sollte spezifischer formuliert werden. Sie sagen nie, dass der Abstand am Footer eine Voraussetzung ist, also behebt das Entfernen des Abstands technisch gesehen den Überhang. Aber das ist keine reale Lösung. Natürlich ist der Abstand erforderlich und Sie sagen zu Recht, dass dies keine korrekte Antwort ist. Aber die Frage lässt das meiner Meinung nach nicht zu :)
Bei Frage 7 finde ich es verwirrend, dass beide gültigen Lösungen, Antwort 1 (transform) und Antwort 3 (calc()), nicht beide zusammen ausgewählt werden können, wie Sie es bei anderen Fragen zulassen. Das kann Benutzer unsicher machen; aber ich frage mich, ob das beabsichtigt ist.
Ich weiß, dass dies nur ein kleiner Test und eine lustige Nebenbeschäftigung sein soll, um sich für den Artikel aufzuwärmen; aber wenn Sie ihn verbessern möchten, empfehle ich, Design-Ergebnisse zu den „realen Welt“-Beispielen hinzuzufügen (wie den Menü-Sprung in Frage 2 und den Footer-Überhang in Frage 6).
Ich denke, die korrekte/beste Lösung für den Menü-Sprung erfordert/wird durch eine Designentscheidung gegeben.
– Transparenter Rand im Nicht-Hover-Zustand sorgt für zusätzlichen vertikalen Abstand zwischen den Elementen
– Blauer Rand (wie der Hintergrund) würde dem Button mehr visuellen Abstand geben
– `border-style: inset` beim Hover würde visuellen Abstand vom Button wegnehmen
Während dies sicherlich eine Code-Frage ist, kann sie nur beantwortet werden, indem zuerst die Designfrage gestellt wird.
Das mag einigen kleinlich erscheinen; aber meiner Meinung nach sind diese Details entscheidend wichtig.
Wie ich sehe (und glücklicherweise auch meine Agentur), können gute Ergebnisse nur erzielt werden, wenn alle Parteien so eng wie möglich zusammenarbeiten.
Hallo René.
4. Es ist korrekt. Gehen Sie in Ihrem Codepen zu Einstellungen und entfernen Sie Ihren CSS-Reset. Ich weiß nicht, welcher Reset das ist, aber er entfernt wahrscheinlich standardmäßig den Abstand von H1.
6. Ich habe gerade in den Kommentar eines anderen geantwortet.
7. Das wollte ich gestern Abend noch beheben, sorry.
Kann auf das Quiz nicht zugreifen, der Link führt zu einer Questionable.io-Fehlerseite mit der Meldung „We apologize, but we’re experiencing some errors.“
Ich konnte die Fragen richtig beantworten, aber die „Punktzahl“ am Ende zeigte nur 83 % und „1“ Punkt an.
Warum ist das passiert?
Eine der Fragen hatte mehrere richtige Antworten, jede war einen Bruchteil eines Punktes wert.
Toller Test mit einigen schönen kleinen „Fangmomenten“, besonders der zweite, bei dem `box-sizing: border-box;` normalerweise funktionieren würde, aber eine explizite Breite erfordert.
Ich kenne mich mit CSS-Layout nicht so gut aus, ich versuche immer noch herauszufinden, wie ich unbenutztes CSS von meiner Seite entfernen kann, weil Google Page Speed mir sagt, dass es meine Seite verlangsamt.
Bei der zweiten Frage würde das Verschieben des Rands in den Anfangszustand das Problem nicht lösen? Ich weiß, es würde den Anfangszustand optisch verändern, aber es würde das Springen lösen, oder?
Toller Artikel (und Test). Ich bereite mich gerade auf ein Vorstellungsgespräch vor, daher hätte dies besser kommen können.
Cheers, ich habe viel gelernt!
Yup. Ich weiß nichts.
Das sind einige der schwierigen Teile von CSS. Ich bin sicher, Sie wissen Gutes. Es geht darum, ständig mehr zu lernen.
Ich habe 8 von 10 mit viel Zeit übrig. Ich wollte die erste Frage wirklich nicht beantworten, weil das Box-Modell nicht vorgegeben war, also fühlte ich mich ein wenig gefangen, aber ich hätte erkennen müssen, dass das Standard-Box-Modell impliziert wurde. Doh!
Und die zweite war die vertikale/horizontale Positionierung mit Flexbox + margin: auto. Das war mir tatsächlich nicht bewusst, dass das möglich ist, also habe ich etwas Neues gelernt! Ich dachte, `align-items` und `justify-content` wären für die VERTIKALE Zentrierung erforderlich (ich wusste, dass es für horizontal funktionieren würde).
Danke fürs Posten! Das hat Spaß gemacht.
Guter Artikel. Ich bin etwas verärgert, dass die letzte Frage nur einen halben Punkt ergab.
Ein weiteres Problem beim Entfernen eines Randes wie diesem ist, dass man kein schönes Rechteck erhält – wenn der Rand dicker ist oder man einen hochauflösenden Bildschirm hat, sind die Kanten des offenen Randes abgewinkelt / erzeugen visuelle Artefakte.
Liebe den Test, Brad! Tolle Arbeit! Ich glaube, es gibt einen Fehler in der Formulierung der richtigen Antwort für Nr. 5. Die Antwortmöglichkeit lautet „die Hälfte der Breite des roten Kastens (50px)“, aber der Kasten ist 50×50, also ist die Hälfte seiner Breite 25px.
Behoben. Danke.
Fantastischer Test.
Ich finde Frage 2 am Ende in ihrer Formulierung etwas irreführend. Meiner Meinung nach bedeutet „das Design gleich zu halten“, dass die Größe der Schaltflächen unverändert bleibt. Das Hinzufügen eines Randes macht sie jedoch einige Pixel höher. Das hat mich dazu gebracht, die falsche Antwort zu wählen, obwohl ich wusste, dass das Problem durch das Hinzufügen von Rändern gelöst werden konnte.
Das Hinzufügen einer festen Höhe und die Anpassung der `box-sizing`-Eigenschaften halten das Design in diesem Fall „gleich“.
Ich lasse hier mal schnell einen Link zu meinem albernen kleinen Twitter-Quiz von vor ein paar Wochen, weil es irgendwie relevant ist.
Schöner Test, aber bitte stylen Sie niemals wieder Checkboxen als Radiobuttons. Ich ging davon aus, dass ich nur eine Antwort pro Frage ankreuzen könnte. ;-)
Dennoch gute Arbeit geleistet, nur diese teilweise (un)korrekten.
Das Problem mit der Anzeige einer „Checkbox-ähnlicheren“ Benutzeroberfläche bei Fragen mit mehreren richtigen Antworten wurde veröffentlicht. Entschuldigung für jegliche Verwirrung.
Technisch gesehen positioniert `position: fixed;` (bezüglich Frage #3) ein Element relativ zum Viewport, es sei denn, ein Vorfahre hat eine `transform-, perspective- oder filter`-Eigenschaft gesetzt, die etwas anderes als `none` ist. Quelle: https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed
Das hat mich mehr genervt, als ich zugeben möchte…