Sie arbeiten also an einem Design. Sie benötigen ein Element mit voller Breite, da das Design eine Hintergrundfarbe hat, die horizontal von Rand zu Rand reicht. Der Inhalt darin muss jedoch nicht unbedingt von Rand zu Rand reichen. Sie möchten
- die Breite begrenzen (für große Bildschirme)
- die Ränder polstern
- den Inhalt zentrieren
Das ist das „Inside“-Problem im Webdesign. Es ist nicht schwierig, es gibt nur viele Überlegungen.
Das "Inside"-Problem. Zentrierte Container mit max-width/padding innerhalb von Full-Width-Farbstreifen.
Was ist Ihr bevorzugtes Muster?
(Nur eine unterhaltsame Alltagsbeschäftigung mit vielen möglichen Lösungen zum Nachdenken!) pic.twitter.com/pNYf5YsQMp
— Chris Coyier (@chriscoyier) 14. März 2019
Die klassische Lösung ist ein äußeres und ein inneres Element.
Das Elternelement ist von Natur aus so breit wie sein Elternelement, und nehmen wir an, das ist das <body>-Element oder die volle Breite des Browserfensters. Das sorgt für die Hintergrundfarbe und polstert die linken und rechten Seiten. Das innere Element begrenzt die Breite im Inneren und zentriert.
<footer>
<div class="inside">
Content
</div>
</footer>
footer {
--contentWidth: 400px;
background: lightcoral;
padding: 2rem 1rem;
}
.inside {
max-width: var(--contentWidth);
margin: 0 auto;
}
Das ist es, woran mein Gehirn zuerst denkt. Es verwendet nichts Ausgefallenes und fühlt sich perfekt verständlich an. Dieses „innere“ Element ist nicht gerade wünschenswert, nur weil es sich wie Fleißarbeit anfühlt, daran zu denken, es jedes Mal zum Markup hinzuzufügen, wenn dieses Muster verwendet wird, aber es erfüllt seinen Zweck mit wenigen anderen Nachteilen.
Siehe den Stift
Klassisches "Inside"-Element von Chris Coyier (@chriscoyier)
auf CodePen.
Was, wenn Sie nur ein einziges Element verwenden können?
Diese Art von Einschränkungen mag ich nicht besonders, denn ich finde, dass ein gesundes Projekt es Designern und Entwicklern ermöglichen sollte, jede Art von Kontrolle über die endgültige HTML-, CSS- und JavaScript-Ausgabe zu haben, die sie benötigen, um die bestmögliche Arbeit zu leisten. Aber leider ist man manchmal als Auftragnehmer in einer komischen Lage oder hat Probleme mit einem Legacy-CMS oder was auch immer.
Wenn Sie nur ein einziges Element zur Verfügung haben, funktioniert Polsterung *irgendwie irgendwie*. Der Trick besteht darin, calc() zu verwenden und die Hälfte der maximalen Breite des Inhalts von 100% abzuziehen.
<footer>
Content
</footer>
footer {
--contentWidth: 600px;
background: lightcoral;
padding: 2rem calc((100% - var(--contentWidth)) / 2);
}
Siehe den Stift
VOYxOa von Chris Coyier (@chriscoyier)
auf CodePen.
Das Problem hierbei ist, dass es das *Randberühren* nicht verhindert, was dies möglicherweise völlig inakzeptabel macht. Vielleicht könnten Sie innere Elemente auswählen (Absätze und dergleichen...) und ihnen Polsterung hinzufügen (mit einem universellen Selektor wie footer > *). Es ist verlockend, Polsterung ganz oben auf dem <body> oder so etwas zu platzieren, um das Randberühren zu verhindern, aber das funktioniert nicht, weil wir diese Rand-zu-Rand-Hintergrundfarbe wünschen.
Was, wenn Sie sich bereits in einem Container befinden, den Sie nicht kontrollieren können, und daraus ausbrechen müssen?
Nun, Sie können immer die altbewährte Full-Width-Utility-Methode anwenden. Dies funktioniert in einem zentrierten Container beliebiger Breite
.full-width {
width: 100vw;
margin-left: 50%;
transform: translateX(-50%);
}
Aber das lässt auch den Inhalt darin in voller Breite. Sie müssten also wieder zu einem inneren Element greifen.
Siehe den Stift
Full-Width-Element mit innerem Element von Chris Coyier (@chriscoyier)
auf CodePen.
Außerdem, sobald Sie eine vertikale Scrollleiste haben, löst dieser 100vw-Wert eine störende horizontale Scrollleiste aus. Einige Websites können so etwas schaffen, um das zu vermeiden
body { overflow-x: hidden; }
Das ist ziemlich gut. Wenn Sie das jedoch nicht tun können, müssen Sie möglicherweise eine explizite Breite für die Scrollleiste festlegen und diese dann von 100vw abziehen.
body {
scrollbar-width: 20px; /* future standards way */
}
body::-webkit-scrollbar { /* long-standing webkit way */
width: 20px;
}
.full-width {
width: calc(100vw - 20px);
}
Selbst das ist irgendwie ärgerlich, da es bedeutet, dass der Full-Width-Container nicht *ganz* Full-Width ist, wenn keine vertikale Scrollleiste vorhanden ist. Ich würde gerne sehen, wie CSS hier aufholt und hilft, wahrscheinlich mit verbesserter Handhabung von Viewport-Einheiten.
Es gibt eine Vielzahl anderer Möglichkeiten, dieses Full-Width-Container-Problem zu lösen, z. B. das Zurückrücken an die Ränder mit Abständen und Ähnlichem. Sie benötigen jedoch letztendlich alle Viewport-Einheiten und leiden infolgedessen unter demselben Schicksal, das mit Scrollleisten verbunden ist.
Wenn Sie overflow-x beim Elternelement definitiv ausblenden können, können extreme negative Ränder und positive Polsterung den Trick tun.
Das ist irgendwie cool, weil es überhaupt nichts Modernes verwendet. Alles sehr alte CSS-Eigenschaften.
Siehe den Stift
Full Width Bars mit negativen Rändern von Chris Coyier (@chriscoyier)
auf CodePen.
Können CSS Grid oder Flexbox hier helfen?
Meh. Nicht wirklich.
Ich meine, sicher, man könnte ein Dreispalten-Grid einrichten und den Inhalt in die mittlere Spalte setzen, während man die äußeren Spalten als Polsterung verwendet. Ich glaube nicht, dass das eine besonders überzeugende Verwendung von Grid ist und es fügt Komplexität ohne Nutzen hinzu – das heißt, es sei denn, Sie verwenden und nutzen Grid in diesem Umfang bereits.
Erfinden Sie stattdessen die Ränder.
Es gibt kein Gesetz, das besagt, dass die Hintergrundfarbe von einem einzigen kontinuierlichen Element kommen muss. Sie könnten die linken und rechten Seiten immer durch einen riesigen Box-Shadow "erfinden" oder ein Pseudoelement nach Bedarf platzieren.
Ich habe das schon einmal mit Pseudo-
::before- und::after-Elementen erreicht. Es war ein wenig hackig und hatte einige Probleme mit horizontalem Überlauf, aber es hat in sehr restriktiven Situationen, in denen ich keine Kontrolle über die Struktur hatte, funktioniert. Normalerweise erreiche ich dies mit einem<section>-Element, das einen Kind-Container für den Inhalt hat, ähnlich Ihrer "klassischen" Lösung, und die übergeordneten Section-Elemente sind immer Full-Width.Ich denke, Grid ist dafür völlig in Ordnung. Sehen Sie sich den aktualisierten Stift für ein Beispiel an: https://codepen.io/tmassman/pen/JqryVZ
Warum wollen Sie die Berechnungen durchführen, wenn Browser sie für Sie erledigen können? Die von Ihnen gezeigten Techniken sind für Browser, die Grid nicht unterstützen, völlig in Ordnung.
Ein Problem mit der Demo im Moment
Ah, das habe ich total übersehen. Danke für den Tipp! Ich habe den Stift aktualisiert, um die linke/rechte Polsterung zu berücksichtigen
Toller Ansatz, genau das, was ich auch kommentieren wollte, Grid kann dieses Problem definitiv recht einfach lösen.
Für die
.full-width-Utility können Sie meiner Meinung nach die Transformation überspringen (obwohl dies Ihren folgenden Punkt bezüglich Scrollleisten nicht anspricht). Ich glaube, es war Ana Tudor, die das auf Twitter erwähnt hatDas ist ein toller Artikel, Chris. Danke, dass Sie diese verschiedenen Methoden in einem Stück zusammengefasst haben. Ich werde diese Hinweise definitiv in meiner zukünftigen Arbeit verwenden :)
Unsichtbare Ränder könnten zu diesem einzelnen Element hinzugefügt werden, um ein Randberühren zu verhindern. Weit davon entfernt, ideal zu sein, aber wenn Sie keine Kontrolle über Ihr HTML haben, müssen Sie manchmal Kompromisse eingehen.
Für mein letztes Spielprojekt wollte ich die Verwendung von Rändern oder Polsterung komplett vermeiden und gleichzeitig Folgendes erreichen:
Das Elternelement enthält verschiedene Dinge: Überschriften, Absätze, Bilder, Zitate usw. Es könnte ein article-Element sein.
Die meisten Kind-Elemente haben eine maximale Breite, um zu lange Textzeilen zu vermeiden.
Diese Textelemente benötigen auf mobilen Bildschirmen einen Abstand zum linken und rechten Bildschirmrand.
Einige Kind-Elemente gehen über die volle Breite oder eine größere Breite, z. B. Bilder, die "herausspringen" sollen, oder große, schicke Textzitate usw.
Ich habe mit folgender Lösung geendet, die für mich funktioniert hat
Was halten Sie von meinem Ansatz?
Nicht wirklich, was meinen Sie mit Randberühren?
Für die Single-Element-Option könnten Sie einen Polsterwert in Ihre Berechnungen einbeziehen, um sicherzustellen, dass es auf kleineren Bildschirmen keinen Randberührung gibt. Und für die Version, in der Sie aus einem vorhandenen Container ausbrechen, könnten Sie die Hintergrundfarbe einem Pseudoelement zuweisen und diesem eine 100vw-Breite und negative Transformationen geben, während das normale Element unverändert bleibt (außer der Anwendung von position: relative, falls erforderlich).
So machen wir es derzeit
Die einzige Ärgerlichkeit ist die Erstellung des max-width-Breakpoints für den Container, der auf der gewünschten max-width zuzüglich der linken und rechten Polsterung der vorherigen Breakpoints berechnet werden muss, damit Sie einen sauberen Übergang und keine berührenden Kanten haben.
Ich konnte dies ziemlich einfach erreichen, indem ich ein
::before-Element absolut positionierte, ohne seintopanzugeben: https://codepen.io/mpetrovich/pen/zQpjrYAndy Bell bietet einen guten Überblick, Creating a full bleed CSS utility, in seinem Blog: https://andy-bell.design/wrote/creating-a-full-bleed-css-utility/
Ich mache das seit den letzten 4 oder 5 Jahren so ... keine zusätzliche Markup-Struktur erforderlich.
Funktioniert überall dort, wo Viewport-Einheiten unterstützt werden und scheitert gut.
Manchmal sind z-index und overflow-Anpassungen am Body für gute Messung erforderlich, aber ansonsten ziemlich robust.
Wie wäre es mit der Verwendung von Polsterung zur Berechnung des Breakpoints?
https://codepen.io/jricarte/pen/BerqxM
Ich brauchte ein Layout, um eine eingeschränkte 2-Spalten-Zeile mit einem Full-Width-2-Spalten/Farbhintergrund zu ermöglichen. Ich habe im Grunde eine responsive
::beforeFull-Width-Utility für die Spalten verwendet.