Schrumpfen überbreiter Seitenelemente

In der Vergangenheit konnte der Webseiten-Designer sich darauf verlassen, dass die Bildschirme der Nutzer relativ breit waren, auf jeden Fall praktisch immer breiter als hoch. Nach der Invasion der Wischofone ist dem nicht mehr so, und die besonders im Hochformat eher schmalen Handhelds stellen den Designer vor neue Herausforderungen.

Für einen Teil dieser Aufgabe gibt es heute triviale technische Lösungen:

  • Es lassen sich für Hochformat und Querformat unterschiedliche Layout-Regeln angeben (CSS-Media-Query: @media screen and (min‑aspect‑ratio: 4/3)) und so zum Beispiel eine seitliche Navigationsleiste an den oberen oder unteren Rand des Bildschirms verschieben oder ganz verstecken und nur bei Bedarf anzeigen.
  • Dito für Bildschirme unter oder über einer gewissen Breite (@media screen and (max‑width: 72em)).
  • Wortumbruch im Fließtext kann man unterstützen durch:
    • Angabe von bedingten Trennstrichen (mit shy) in langen Wörtern,
    • Aktivieren der automatischen Silbentrennung (mit hyphens: auto),
    • Erlaubnis zu aggressivem Wortumbruch an beliebigen Stellen in überlangen Wörtern ohne Trennmöglichkeit (mit word‑wrap: break‑word):
      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keine dieser Methoden aber ist geeignet für Tabellen, Programm-Listings und ASCII-Grafiken; diese würden durch Umbruch bis zur Unleserlichkeit verunstaltet. Will man ein seitliches Scrollen der gesamten Seite vermeiden, gibt es bei Überbreite dieser Elemente nur zwei Möglichkeiten:

  1. Seitliches Scrollen des Elementes (Demo);
  2. Schrumpfung des Elementes (Demo).

Das seitliche Scrollen des Elementes wird trivial realisiert durch einen Container mit overflow‑x: auto; für das automatische Schrumpfen habe ich ein kleines Skript erstellt.

Das Skript

Wie bei meinen Skripten üblich enthält das Skript shrink-to-fit.js weder Texte noch Layout und es belegt es keine globalen Namen.

Es durchsucht nach dem Laden die Seite nach HTML-Elementen, die mit class="shrink‑to‑fit" markiert sind, und merkt sich diese. Danach misst es die Breite der Elemente und reduziert deren Fontgröße so, dass die Elemente in der Breite passen und kein seitliches Scrollen nötig ist. Diese Anpassung wird wiederholt:

  • nach Änderung der Bildschirm-Breite (zum Beispiel durch Drehen des Bildschirms),
  • nach Änderung des Element-Inhaltes bei dynamischen Elementen (Demo).

Die Klasse shrink‑to‑fit wird nicht für das Layout benutzt, sie dient ausschließlich zur Markierung der relevanten Elemente.

Einbindung

  1. Markieren Sie die Elemente, die automatisch geschrumpft werden sollen, durch Aufnahme in die Klasse shrink-to-fit:
    <table class="shrink-to-fit"> ... </table>

    Achten Sie darauf, dass das Elternelement sich über die volle Breite des Dokuments erstreckt; markieren Sie also eine gesamte Tabelle, nicht aber eine einzelne Tabellen-Zelle.

  2. Binden Sie das Skript so ein, dass es erst gestartet wird, wenn die Webseite geladen ist: Fügen Sie es also am Ende der Seite ein oder markieren Sie es im Seitenkopf mit defer:
    <head>
        [...]
        <script defer="defer" src="shrink-to-fit.js"></script>
        [...]
    </head>

Das war' schon.

Konfiguration

Sie können das Skript konfigurieren. Dazu hinterlegen Sie die Konfigurationswerte in data-Attributen eines HTML-Elementes und markieren dieses Element mit id="shrink-to-fit". Im Beispiel nutzen wir das body-Element:

<body id="shrink-to-fit"
    data-shrink-to-fit-classes="schrumpf-mich, mach-mich-kleiner"
    data-shrink-to-fit-selectors="table, pre.autoschrumpf">
  • Mit dem data-shrink-to-fit-classes-Attribut wählen Sie die Klassen, die an Stelle der shrink-to-fit-Klasse die zu schrumpfenden Elemente auswählen.
  • Flexibler können Sie Elemente mit CSS-Selektoren auswählen, die sie im data-shrink-to-fit-selectors-Attribut hinterlegen.

Wechselwirkung mit MathJax

Das JavaScript-Paket MathJax erzeugt sehr schöne mathematische Formeln (Demo) aus einer textuellen Beschreibung in AsciiMath, LaTeX oder MathML. Dieses Rendern erfolgt direkt nach dem Laden der Seite, also genau dann, wenn wir zum ersten Mal die Fontgröße unserer Elemente bestimmen. Das führt zu Konflikten.

Um solche Konflikte zu vermeiden, benutzen Sie den Konfigurationsparameter data-shrink-to-fit-delayed:

<body id="shrink-to-fit"
    data-shrink-to-fit-classes="schrumpf-mich, nicht-beim-start"
    data-shrink-to-fit-delayed="nicht-beim-start">

und markieren mit der so konfigurierten Klasse alle Elemente, die nicht sofort beim Start, sondern erst nach dem Rendern (z. B. durch MathJax) geschrumpft werden sollen.

Download

Sie können das Skript und zwei Demoseiten als Zip-Datei shrink-to-fit.zip herunterladen.