Signatur
Beschreibung
Element.scrollWidth liefert die Breite des gesamten Inhalts eines Elements in CSS-Pixeln, also auch den Teil, der wegen overflow abgeschnitten oder nur durch horizontales Scrollen erreichbar ist. Der Wert enthält das Padding, aber weder Rahmen (border), Außenabstand (margin) noch eine vertikale Scrollleiste. Außerdem kann er die Breite von Pseudo-Elementen wie ::before und ::after einschließen.
Passt der Inhalt ohne horizontale Scrollleiste in das Element, entspricht scrollWidth dem Wert von clientWidth. Ist scrollWidth größer als clientWidth, läuft der Inhalt horizontal über. Mit diesem Vergleich prüft man typischerweise, ob Text abgeschnitten ist (etwa bei text-overflow: ellipsis), ob Scroll-Pfeile in einem Karussell nötig sind oder bis wohin ein Element maximal gescrollt werden kann (scrollWidth - clientWidth).
Die Eigenschaft ist schreibgeschützt und gibt immer einen gerundeten Ganzzahlwert zurück. Brauchst du Nachkommastellen, nimm getBoundingClientRect(). Beim Auslesen muss der Browser ein synchrones Layout berechnen (Reflow).
Rückgabewert
display: none) ist der Wert 0.Beispiele
Abgeschnittenen Text erkennen und Tooltip setzen
// Alle Tabellenzellen mit text-overflow: ellipsis prüfen
document.querySelectorAll('.truncate').forEach((el) => {
const istAbgeschnitten = el.scrollWidth > el.clientWidth;
if (istAbgeschnitten) {
// Vollständigen Text als Tooltip anzeigen
el.title = el.textContent.trim();
}
console.log(el.textContent.trim(), istAbgeschnitten);
});
Scroll-Buttons eines horizontalen Karussells ein- und ausblenden
const track = document.querySelector('.carousel-track');
const prevBtn = document.querySelector('.carousel-prev');
const nextBtn = document.querySelector('.carousel-next');
const updateButtons = () => {
const maxScroll = track.scrollWidth - track.clientWidth;
prevBtn.hidden = track.scrollLeft <= 0;
// Toleranz von 1px wegen Rundung bei gebrochenen Pixelwerten
nextBtn.hidden = track.scrollLeft >= maxScroll - 1;
};
nextBtn.addEventListener('click', () => {
track.scrollBy({ left: track.clientWidth, behavior: 'smooth' });
});
prevBtn.addEventListener('click', () => {
track.scrollBy({ left: -track.clientWidth, behavior: 'smooth' });
});
track.addEventListener('scroll', updateButtons, { passive: true });
new ResizeObserver(updateButtons).observe(track);
updateButtons();
Werte eines überlaufenden Containers vergleichen
const box = document.createElement('div');
Object.assign(box.style, {
width: '200px',
padding: '10px',
border: '5px solid',
overflow: 'auto',
whiteSpace: 'nowrap'
});
box.textContent = 'x'.repeat(200);
document.body.append(box);
console.log({
offsetWidth: box.offsetWidth, // inkl. Rahmen
clientWidth: box.clientWidth, // sichtbarer Bereich inkl. Padding
scrollWidth: box.scrollWidth // gesamter Inhalt inkl. Padding
});
box.remove();
// Wichtig · Fallstricke
- Rundung:
scrollWidthwird auf eine Ganzzahl gerundet. Bei gebrochenen Breiten (Zoom,transform, Prozentangaben) kann ein Vergleich wiescrollLeft === scrollWidth - clientWidthdaneben liegen. Rechne deshalb mit einer Toleranz von etwa 1px. - Performance: Beim Auslesen muss der Browser das Layout synchron berechnen. Wechselst du in Schleifen zwischen Lesen und DOM-Änderungen, entsteht „Layout Thrashing“. Lies die Werte deshalb gebündelt aus, am besten in
requestAnimationFrameoder in einemResizeObserver-Callback. - Nicht enthalten: Rahmen, Außenabstand und die vertikale Scrollleiste zählen nicht mit. Die Breite inklusive Rahmen liefert
offsetWidth. - Nicht gerenderte Elemente: Bei
display: noneoder Elementen, die nicht im Dokument hängen, ist der Wert0. Inline-Elemente ohne Layout-Box liefern ebenfalls0. - Dokumentbreite: Für die gesamte Seitenbreite nimmst du
document.documentElement.scrollWidth(im Quirks-Modusdocument.body.scrollWidth). - Kompatibilität: Wird von allen modernen Browsern unterstützt. Ältere Browser hatten kleine Abweichungen bei Pseudo-Elementen und bei Padding in Flex- und Grid-Containern.