Warum das Layout auf dem Handy kippt
Meistens ist genau ein Element zu breit, und ohne den Blick in die Konsole sucht man es an allen Stellen, an denen es nicht sitzt.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Ein einziges zu breites Element schiebt die ganze Seite zur Seite
Auf dem Rechner passt alles. Auf dem Telefon lässt sich die Seite plötzlich seitlich schieben, rechts erscheint ein leerer Streifen, der Kopfbereich endet vor dem Inhalt und ein Hintergrund hört mitten im Bild auf. Der Reflex ist, den Abschnitt zu untersuchen, in dem es auffällt. Genau dort sitzt die Ursache aber selten, weil ein zu breites Element die gesamte Seite verschiebt und der Effekt überall sichtbar wird, nur nicht unbedingt dort, wo er entsteht.
Der Schaden ist unmittelbar: Wer eine Seite seitlich schieben muss, um die Schaltfläche am rechten Rand zu erreichen, findet sie oft gar nicht. Dazu kommt die formale Seite. Die Web Content Accessibility Guidelines verlangen im Kriterium Reflow, dass Inhalte bei einer Breite von 320 CSS-Pixeln ohne Scrollen in zwei Richtungen nutzbar bleiben. Waagerechtes Scrollen über die ganze Seite ist damit nicht nur unschön, sondern ein Befund.
Die naheliegende Reparatur ist auch die schlechteste. overflow-x hidden am body versteckt das Symptom, das Element bleibt zu breit, und die Regel kann als Nebenwirkung position sticky in Kindelementen wirkungslos machen, weil ein Element mit einem anderen Überlaufverhalten als visible einen eigenen Scrollbereich aufmacht. Man tauscht also einen sichtbaren Fehler gegen zwei unsichtbare.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Symptom, Ursache, Lösung
Symptom
Die Seite lässt sich seitlich schieben, aber kein Element sieht auf den ersten Blick zu breit aus.
Ursache
Genau ein Element ragt über den rechten Rand hinaus. Häufige Kandidaten: ein dekoratives Element mit position absolute und einem Versatz nach rechts, eine verborgene Folie eines Karussells, ein Block mit width 100vw innerhalb eines Elternelements mit Innenabstand, oder ein Element, das per transform verschoben wurde. Sichtbar ist meist nur der leere Streifen rechts.
Lösung
In der Konsole alle Elemente gegen die Dokumentbreite prüfen: document.querySelectorAll('*').forEach(el => { const r = el.getBoundingClientRect(); if (r.right > document.documentElement.clientWidth + 1 || r.left < -1) console.log(el, r.left, r.right) }). So findest du auch Elemente, die nach links überstehen. Das gefundene Element bekommt eine Höchstbreite, verliert seinen Versatz oder wandert in einen Container mit overflow clip. overflow-x hidden am body ist keine Lösung: Es versteckt das Symptom und kann position sticky in Kindelementen abschalten.
Symptom
Zwei oder drei Kacheln stehen auf dem Telefon weiter nebeneinander, und der Text darin bricht nach jedem zweiten Wort um.
Ursache
Das Raster hat eine feste Spaltenzahl, etwa grid-template-columns repeat(3, 1fr). Ein solches Raster bricht nicht um. Es verteilt den vorhandenen Platz auf drei Spalten, egal wie schmal die dabei werden. Ohne Media Query bleibt es bei drei Spalten bis hinunter auf jede Bildschirmbreite.
Lösung
grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)) setzen. Die Spalten legen selbst fest, wie viele nebeneinander passen. Das min() ist der Teil, den man weglässt und dann sucht: Ohne ihn ist die Mindestbreite von 18rem auch auf einem 320 Pixel breiten Bildschirm bindend, und aus dem Raster wird genau der Überlauf, den du beheben wolltest.
Symptom
Ein Element in einem Flex-Container quillt über, obwohl width 100 Prozent gesetzt ist.
Ursache
Flex-Kinder haben von sich aus min-width auto. Sie schrumpfen also nicht unter die Mindestbreite ihres Inhalts, und die legt eine Tabelle, ein Codeblock oder ein langes Wort fest. Die Angabe width 100 Prozent bezieht sich dann auf einen Platz, den das Kind selbst aufgebläht hat, und ändert nichts.
Lösung
min-width 0 am Flex-Kind setzen, in Rastern entsprechend minmax(0, 1fr) an der Spalte. Der Inhalt bekommt zusätzlich overflow-wrap anywhere, damit lange Zeichenketten umbrechen dürfen. Für Codeblöcke ist die bessere Wahl ein eigener Scrollbereich, weil ein umgebrochener Codeblock schwer zu lesen ist.
Symptom
Die Preistabelle zieht die gesamte Seite in die Breite.
Ursache
Eine Tabelle bricht nicht um. Ihre Mindestbreite ergibt sich aus den Spaltenüberschriften und dem längsten Zellinhalt und steht damit fest, bevor irgendeine Regel im Stylesheet greift. Auch table-layout fixed hilft nur bedingt, weil dann zwar die Spaltenbreiten fest sind, der Inhalt aber weiterhin herausragen kann.
Lösung
Die Tabelle in einen eigenen Container mit overflow-x auto setzen und diesem Container tabindex 0 sowie eine Beschriftung geben, damit der Scrollbereich auch mit der Tastatur erreichbar ist und angesagt wird. Bei wenigen Spalten ist die Alternative, unterhalb einer bestimmten Breite auf eine Kartenansicht umzuschalten und die Spaltenüberschrift je Zelle über ein data-Attribut einzublenden.
Symptom
Ein Abschnitt mit height 100vh ist auf dem Telefon zu hoch, der untere Rand verschwindet hinter der Adressleiste.
Ursache
Die Einheit vh rechnet mit der größtmöglichen Ansicht, also mit eingeklappter Adressleiste. Solange die Leiste ausgeklappt ist, und das ist sie beim Aufruf der Seite, ist der sichtbare Bereich kleiner als 100vh.
Lösung
svh nimmt die kleinste, lvh die größte und dvh die gerade gültige Ansichtshöhe. Für einen Startbereich, der vollständig sichtbar sein soll, ist 100svh die verlässliche Angabe. dvh ändert sich beim Scrollen mit und kann dabei selbst Sprünge im Layout erzeugen, taugt also nicht für Elemente, die im Fluss stehen.
Fünf Ursachen, die fast alle Fälle abdecken
- 01 Eine feste Pixelbreite bricht, sobald sie mit Innenabstand und Rahmen breiter wird als der Bildschirm.
- 02 100vw rechnet die Scrollleiste mit und ist breiter als der nutzbare Inhaltsbereich.
- 03 Ein Raster mit fester Spaltenzahl bricht nicht um, es quetscht die Spalten zusammen.
- 04 Flex-Kinder schrumpfen von sich aus nicht unter die Breite ihres Inhalts.
- 05 Tabellen und lange Wörter setzen eine Mindestbreite, die niemand geschrieben hat.
Was du danach in ein paar Minuten selbst findest
Die Suche nach der Ursache ist keine Frage der Erfahrung, sondern der Reihenfolge. Zuerst das Element benennen, das über den Rand hinausragt, dann prüfen, welche der fünf üblichen Ursachen dahintersteckt, und erst danach eine Regel schreiben. Wer in dieser Reihenfolge arbeitet, braucht für die meisten Fälle keine zehn Minuten.
Das schuldige Element benennen
Ein kurzer Schnipsel in der Konsole vergleicht jedes Element mit der Breite des Dokuments und gibt die Ausreißer aus. Damit endet das Durchklicken im Elementebaum, bevor es anfängt.
Feste Breiten und ihre Verstecke kennen
Nicht nur width in Pixeln, sondern auch min-width an einem Formularfeld, eine feste Breite an einer Grafik, ein size-Attribut an einem Eingabefeld und jede Angabe in 100vw, die die Scrollleiste mitrechnet.
Raster umbrechen lassen, ohne für jede Breite eine Regel zu schreiben
Spalten mit auto-fit und minmax entscheiden selbst, wie viele nebeneinander passen. Der Teil, der dabei regelmäßig fehlt, ist die Absicherung der Mindestbreite gegen sehr schmale Bildschirme.
Flex-Kinder daran hindern, ihren Inhalt durchzudrücken
Flex-Kinder schrumpfen von sich aus nicht unter die Mindestbreite ihres Inhalts. Eine Tabelle, ein Codeblock oder ein langes Wort setzt damit eine Breite, die niemand geschrieben hat.
Lange Wörter und Tabellen bändigen
Fremdtexte enthalten Produktnamen, Adressen und Dateipfade ohne Trennstelle. Tabellen haben eine Mindestbreite aus ihrem Inhalt. Beides braucht eine ausdrückliche Regel, sonst gewinnt der Inhalt.
Auf 320 Pixel prüfen statt auf dem eigenen Gerät
Das eigene Telefon ist fast immer breiter als der kritische Fall. 320 CSS-Pixel ist die sinnvolle untere Grenze und zugleich die Breite, die die Richtlinien zur Zugänglichkeit nennen.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Warum es fast immer genau ein Element ist
Die Breite des sichtbaren Bereichs steht fest. Das Dokument wird in dem Moment seitlich scrollbar, in dem eine einzige Box darüber hinausragt. Die richtige Frage lautet deshalb nicht, welcher Abschnitt kaputt aussieht, sondern welche Box breiter ist als document.documentElement.clientWidth. Weil sich beim Scrollen die ganze Seite bewegt, wirkt der Fehler in jedem Abschnitt, entsteht aber nur in einem.
Dass die Box oft unsichtbar ist, hat wenige, immer gleiche Gründe: dekorative Elemente mit absoluter Position und einem Versatz nach rechts, verborgene Folien eines Karussells, die trotzdem Platz beanspruchen, und Elemente, die mit transform verschoben wurden, denn eine Verschiebung nach rechts erzeugt sehr wohl scrollbaren Überlauf. Alle drei sieht man im Layout nicht, im Vergleich der Kantenpositionen dagegen sofort.
Wenn du statt des einzelnen Elements den Container suchst, in dem der Überlauf zuerst entsteht, hilft ein zweiter Weg: vom body abwärts jedes Element daraufhin prüfen, ob scrollWidth größer ist als clientWidth. Das erste Element, bei dem das zutrifft, ist der Container, in dem der Überlauf beginnt, und meist reicht eine Regel an dieser Stelle.
Feste Breiten und ihre Verstecke
Die offensichtliche Variante ist width mit einem Pixelwert. Die weniger offensichtlichen sind zahlreicher: ein min-width an einem Formularfeld, ein size-Attribut an einem input, eine feste Breite an einer eingebetteten Grafik, eine Mindestbreite an einer Schaltflächenleiste, und jedes Element, dessen Breite sich aus mehreren Spalten mit festen Werten addiert. Als Regel für Komponenten hat sich bewährt: Komponenten bekommen eine Höchstbreite, die tatsächliche Breite bestimmt das Layout um sie herum.
Die Einheit vw ist ein eigener Fall. Sie bezieht sich auf die Breite des Anzeigebereichs einschließlich einer sichtbaren Scrollleiste. Auf dem Rechner ist ein Block mit width 100vw damit systematisch breiter als der Inhaltsbereich, und in einem Elternelement mit Innenabstand ohnehin. Für Blöcke, die über die volle Breite laufen sollen, ist die verlässlichere Konstruktion ein Container ohne Innenabstand plus width 100 Prozent.
Und dann box-sizing. Ohne border-box addieren sich Innenabstand und Rahmen auf die angegebene Breite. Ein Element mit width 100 Prozent und einem Innenabstand von 1rem ist damit breiter als sein Elternelement. Die Zeile, die box-sizing border-box global setzt, gehört in jedes Projekt und ist in den verbreiteten Rahmenwerken bereits enthalten. Fehlt sie, erklärt sie einen erheblichen Teil aller Überläufe auf einen Schlag.
Raster, die nicht umbrechen wollen
auto-fit und auto-fill sehen gleich aus und verhalten sich unterschiedlich. auto-fill legt so viele Spalten an, wie hineinpassen, und lässt leere Spalten stehen. auto-fit klappt die leeren zusammen, sodass die vorhandenen Elemente den Platz füllen. Bei drei Kacheln in einem breiten Bereich ist das der sichtbare Unterschied zwischen drei breiten Kacheln und drei schmalen Kacheln neben einer Leerstelle.
Die Konstruktion minmax(min(18rem, 100%), 1fr) sieht umständlich aus und löst genau ein Problem: Eine Mindestbreite von 18rem ist bindend, auch wenn der verfügbare Platz kleiner ist. Auf einem 320 Pixel breiten Bildschirm erzeugt sie damit selbst den Überlauf. Das min() sorgt dafür, dass die Mindestbreite nie größer wird als der vorhandene Platz.
Mit Flexbox erreichst du dasselbe über flex-wrap wrap und eine Basis wie flex 1 1 18rem, mit einem Unterschied im Ergebnis: Die letzte Zeile verteilt den Rest auf die vorhandenen Elemente, statt sie an einem Raster auszurichten. Für Komponenten, die an unterschiedlichen Stellen unterschiedlich viel Platz haben, ist inzwischen die Container Query der bessere Weg: Die Karte entscheidet dann anhand der Breite ihres Containers über ihr Layout, nicht anhand der Breite des Fensters. Genau das ist der Fall, in dem eine Media Query die falsche Frage stellt.
Prüfen ohne Gerätepark
Die Geräteleiste in den Entwicklerwerkzeugen reicht für den größten Teil der Arbeit, wenn du sie auf eine Breite von 320 CSS-Pixeln stellst statt auf ein Gerät aus der Liste. Diese Breite ist die sinnvolle untere Grenze und zugleich die Breite, die im Kriterium Reflow der Richtlinien genannt wird. Was dort funktioniert, funktioniert auf allen verbreiteten Telefonen.
Zum Aufspüren gibt es neben dem Konsolenschnipsel einen zweiten Trick: eine vorübergehende Regel, die jedem Element eine Kontur gibt. Eine Kontur ist dafür geeignet, weil sie im Gegensatz zu einem Rahmen keinen Platz beansprucht und damit nicht selbst Überlauf erzeugt. Man sieht dann sofort, welche Box über den Rand hinausläuft, und braucht keine Konsole.
Was die Emulation nicht abbildet, holst du dir über die Fernsteuerung eines echten Geräts: Android über die Entwicklerwerkzeuge von Chrome, iPhone über den Web-Inspektor von Safari. Drei Dinge sieht man nur dort: das tatsächliche Verhalten der Adressleiste, eine im Betriebssystem hochgestellte Schriftgröße und die tatsächliche Größe der Berührungsflächen. Die hochgestellte Schrift ist der häufigste Grund dafür, dass ein Layout auf einem echten Gerät bricht und im Emulator hält.
Was nach dem Flicken bleibt
Zwei Regeln als Voreinstellung im Projekt verhindern die Mehrzahl der Fälle: Bilder und eingebettete Elemente bekommen max-width 100 Prozent und height auto, und jeder Container, der fremden Text aufnehmen kann, bekommt min-width 0 zusammen mit overflow-wrap. Fremder Text heißt hier alles, was aus einem Redaktionssystem, einer Schnittstelle oder einer Eingabe kommt, also praktisch jeder Inhalt außer der Beschriftung von Schaltflächen.
In die Abnahmeliste gehören zwei Zeilen: einmal auf 320 Pixel ansehen und einmal mit einem sehr langen Produktnamen befüllen. Beides dauert zusammen zwei Minuten und findet die Fälle, die sonst erst nach dem Ausliefern auffallen, wenn der erste Datensatz mit einer langen Bezeichnung im System landet.
Und eine Gewohnheit lohnt sich: keine festen Breiten in Komponenten. Eine Karte, ein Formular oder eine Tabelle sollten sich in jede Umgebung einfügen. Die Breite bestimmt das Layout, in dem sie steht. Wer diese Trennung durchhält, kann Komponenten verschieben, ohne jedes Mal neu auf Überlauf zu prüfen.
Dazu passende Kurse
Woher waagerechtes Scrollen auf kleinen Bildschirmen kommt und wie man es dauerhaft abstellt, gehört in den CSS-Kursen bei cmt zum festen Programm.
Wer Raster, Bilder und Typografie im Zusammenspiel von Grund auf aufbauen will, findet im Angebot rund um Webentwicklung den passenden Einstieg.
Wie sicher bist du beim Thema wirklich?
Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.
Wo du genau das übst
Ein sehr gutes, praxisorientiertes und nachhaltiges Seminar. So sollte es immer sein. Vielen Dank.
Die Schulung ist gerade für Einsteiger oder Entwickler*innen mit eingestaubtem Basiswissen sehr hilfreich.
Ich bin sehr glücklich Franz als Trainer gehabt zu haben. Er hat offensichtlich unglaublich viel Wissen zu den Themen, und schafft es, dieses auch interaktiv und verständlich weiterzugeben.
Häufige Fragen
Hilft overflow-x hidden am body?
Welche Breite ist die kleinste, auf die ich prüfen sollte?
Brauche ich noch Media Queries, wenn es Container Queries gibt?
Warum sieht es im Emulator gut aus und auf dem Telefon nicht?
Deine Ansprechpartner
Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.
Yves Hoppe
Weiterbildung & Beratung
Hilft dir, aus dem Webentwicklung-Programm den passenden Kurs für deinen Stand zu finden.
Norbert Jansen
Beratung & Inhouse
Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.
Layouts, die auch auf 320 Pixel halten
In den CSS- und Webdesign-Kursen bei cmt baust du Raster, Tabellen und Bildbereiche so auf, dass der Umbruch von selbst passt und nicht mit Ausnahmen erzwungen werden muss.