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: nowrapbleibt der Text in einer Zeile (verschwendet Höhe) - CSS
columnsfunktioniert 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 Spaltendisplay: inline-block bei Spalten ermöglicht horizontale Anordnungwhite-space: normal in Spalten erlaubt Textumbruch innerhalb der SpalteSchritt 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:
- Teile Text in Wörter
- Füge Wörter zur aktuellen Spalte hinzu
- Prüfe nach jedem Wort: Passt es noch in die Höhe?
- 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
- CSS allein reicht nicht für intelligente Textaufteilung basierend auf Höhe
- JavaScript kann messen, wie viel Platz Text benötigt
- Unsichtbare Test-Elemente ermöglichen Berechnungen ohne sichtbare Änderungen
- Algorithmische Textaufteilung optimiert die Spaltennutzung
- 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