Lernen: Tutorial

Tutorial: Horizontaler Text-Scroll mit optimaler Spaltenaufteilung

Einleitung

Nachdem ein hilfesuchender Member der dev community eine Frage zu folgendem Problem hatte, entschied ich mich für dieses Tutorial.

In diesem Tutorial lernen wir, wie man einen Text in einer Box mit fester Höhe horizontal scrollbar macht, wobei der Text automatisch in optimale Spalten aufgeteilt wird. Dies ist quasi die "umgekehrte" Variante zum klassischen vertikalen Scroll bei fester Breite.

Die Problemstellung

Stell dir vor, du hast:

  • Einen beliebig langen Text
  • Eine Container-Box mit fester Höhe
  • Der Text soll horizontal scrollbar sein
  • Die Scroll-Breite soll minimal sein
  • Der Text soll die verfügbare Höhe optimal ausnutzen

Warum ist das schwierig?

Das normale CSS-Verhalten ist:

  • Bei fester Breite umbricht Text automatisch und scrollt vertikal
  • Bei white-space: nowrap bleibt der Text in einer Zeile (verschwendet Höhe)
  • CSS columns funktioniert nur mit fester Spaltenanzahl oder -breite, nicht optimal

Die Herausforderung: Wir müssen den Text intelligent aufteilen, so dass jede Spalte die verfügbare Höhe maximal ausnutzt.


Die Lösung: CSS + JavaScript

Wir kombinieren CSS für das Layout mit JavaScript für die intelligente Textaufteilung.

Schritt 1: HTML-Struktur
<div class="horizontal-text-container" id="container">
    <div id="textContent">
        Dein langer Text hier...
    </div>
</div>

Schritt 2: CSS-Styling
.horizontal-text-container {
    width: 300px;           /* Container-Breite */
    height: 60px;           /* Feste Höhe */
    border: 1px solid #000;
    overflow-x: auto;       /* Horizontal scrollbar */
    overflow-y: hidden;     /* Kein vertikales Scrollen */
    padding: 5px;
    white-space: nowrap;    /* Wichtig für horizontales Layout */
}

.text-columns {
    display: inline-block;
    vertical-align: top;
    width: 150px;           /* Feste Spaltenbreite */
    height: 100%;
    margin-right: 15px;     /* Abstand zwischen Spalten */
    white-space: normal;    /* Text in Spalte kann umbrechen */
    overflow: hidden;
}
Wichtige CSS-Eigenschaften:

  • white-space: nowrap im Container verhindert Umbruch zwischen Spalten
  • display: inline-block bei Spalten ermöglicht horizontale Anordnung
  • white-space: normal in Spalten erlaubt Textumbruch innerhalb der Spalte

  • Schritt 3: JavaScript-Logik

    Das JavaScript-Skript macht folgendes:

    3.1 Zeilenhöhe berechnen
    	function createOptimalColumns(containerId) {
        const container = document.getElementById('container');
        const textElement = document.getElementById(containerId);
        const originalText = textElement.textContent.trim();
        const containerHeight = container.offsetHeight - 10; // Minus padding
        
        // Temporäres Element zum Messen
        const tempDiv = document.createElement('div');
        tempDiv.style.position = 'absolute';
        tempDiv.style.visibility = 'hidden';
        tempDiv.style.width = '150px';
        // Kopiere Schrifteigenschaften
        tempDiv.style.fontSize = getComputedStyle(textElement).fontSize;
        tempDiv.style.lineHeight = getComputedStyle(textElement).lineHeight;
        tempDiv.style.fontFamily = getComputedStyle(textElement).fontFamily;
        document.body.appendChild(tempDiv); 

    Warum ein unsichtbares Element? Wir brauchen es, um zu messen, wie hoch Text bei gegebener Breite wird, ohne das sichtbare DOM zu beeinflussen.

    3.2 Maximale Zeilenanzahl ermitteln
        tempDiv.textContent = 'Test';
        const lineHeight = tempDiv.offsetHeight;
        const maxLines = Math.floor(containerHeight / lineHeight);

    So finden wir heraus, wie viele Textzeilen in die Container-Höhe passen.

    3.3 Text auf Spalten aufteilen
        const words = originalText.split(' ');
        const columns = [];
        let currentColumn = [];
        
        for (let word of words) {
            // Teste aktuelle Spalte + neues Wort
            const testText = [...currentColumn, word].join(' ');
            tempDiv.textContent = testText;
            
            // Berechne benötigte Zeilen
            const neededLines = Math.ceil(tempDiv.offsetHeight / lineHeight);
            
            if (neededLines <= maxLines) {
                currentColumn.push(word);
            } else {
                // Neue Spalte starten
                if (currentColumn.length > 0) {
                    columns.push(currentColumn.join(' '));
                }
                currentColumn = [word];
            }
        }

    Der Algorithmus:

    1. Teile Text in Wörter
    2. Füge Wörter zur aktuellen Spalte hinzu
    3. Prüfe nach jedem Wort: Passt es noch in die Höhe?
    4. Wenn nicht: Starte neue Spalte

    3.4 DOM erstellen
        // DOM erstellen
        container.innerHTML = '';
        columns.forEach(columnText => {
            const columnDiv = document.createElement('div');
            columnDiv.className = 'text-columns';
            columnDiv.textContent = columnText;
            container.appendChild(columnDiv);
        });
        
        document.body.removeChild(tempDiv);
    }

    Schritt 4: Initialisierung
    document.addEventListener('DOMContentLoaded', function() {
        createOptimalColumns('textContent');
    });

    Das Skript läuft automatisch, sobald die Seite geladen ist.


    Zusammenfassung

    1. CSS allein reicht nicht für intelligente Textaufteilung basierend auf Höhe
    2. JavaScript kann messen, wie viel Platz Text benötigt
    3. Unsichtbare Test-Elemente ermöglichen Berechnungen ohne sichtbare Änderungen
    4. Algorithmische Textaufteilung optimiert die Spaltennutzung
    5. Kombination von CSS + JavaScript löst komplexe Layout-Probleme

    Mögliche Erweiterungen

    Du kannst die Lösung noch verbessern, indem du sie bei Fenstergrößenänderungen neu berechnest (responsive), die optimale Spaltenbreite automatisch findest, Animationen für sanfte Übergänge hinzufügst oder Touch-Gesten für bessere Mobile-Bedienung einbaust.

    Anwendungsfälle

    Diese Technik eignet sich besonders für mobile Interfaces mit begrenzter Höhe, horizontale Timelines, Text-Slider und Dashboard-Widgets, wo vertikaler Platz knapp ist.

    Fazit

    Horizontaler Text-Scroll mit optimaler Spaltenaufteilung erfordert JavaScript, aber das Ergebnis ist ein flexibles Layout, das die verfügbare Höhe optimal nutzt und minimale Scroll-Breite garantiert.

    Anschauen und Quelltext holen