8. juni 2026

Størrelsen på elementer og scrolling

Der er mange JavaScript-egenskaber, der giver os mulighed for at læse information om elementets bredde, højde og andre geometriske træk.

Vi har ofte brug for dem, når vi flytter eller placerer elementer i JavaScript.

Eksempel-element

Lad os bruge elementet herunder som eksempel til at demonstrere egenskaberne:

<div id="example">
  ...Tekst...
</div>
<style>
  #example {
    width: 300px;
    height: 200px;
    border: 25px solid #E8C48F;
    padding: 20px;
    overflow: auto;
  }
</style>

Det har kant, padding og scroll-mulighed. Det har ingen margin, da de ikke er en del af elementet selv, og der er ingen specielle egenskaber for dem.

Elementet ser sådan ud:

Du kan åbne dokumentet i sandbox.

Mind the scrollbar

Billedet ovenfor viser det mest komplekse tilfælde, hvor elementet har en scrollbjælke. Nogle browsere (ikke alle) reserverer plads til den ved at tage den fra indholdet (angivet som “content width” ovenfor).

Så uden en scrollbjælke ville indholdsbredden være 300px, men hvis scrollbjælken er 16px bred (bredden kan variere mellem enheder og browsere), er der kun 300 - 16 = 284px tilbage, og vi bør tage det med i betragtning. Det er derfor, eksemplerne i dette kapitel antager, at der er en scrollbjælke. Uden den er nogle beregninger enklere.

Området padding-bottom kan fyldes med tekst

Normalt vil padding være tom som det ses på illustrationerne, men hvis der er meget tekst i elementet og det overløber, vil browseren vise den " overløbende" tekst på padding-bottom, det er normalt.

Geometri

Her er et billede, der viser alle geometriske egenskaber:

Værdierne af disse egenskaber er teknisk set bare talværdier, men værdierne er i pixels, så det er pixelmålinger.

Lad os starte med at udforske egenskaberne startende fra elementets yderside.

offsetParent, offsetLeft/Top

Disse egenskaber er sjældent nødvendige, men de er stadig de “yderste” geometriske egenskaber, så vi starter med dem.

offsetParent er den nærmeste forfader, som browseren bruger til at beregne koordinater under rendering.

Det er den nærmeste forfader, der er en af følgende:

  1. CSS-positioneret (position er enten absolute, relative, fixed eller sticky), eller
  2. <td>, <th>, eller <table>, eller
  3. <body>.

Egenskaberne offsetLeft og offsetTop giver x/y koordinater i forhold til offsetParent’s øverste venstre hjørne.

I eksemplet nedenfor har det indre <div> <main> som offsetParent og offsetLeft/offsetTop viser forskydningen fra dets øverste venstre hjørne (180):

<main style="position: relative" id="main">
  <article>
    <div id="example" style="position: absolute; left: 180px; top: 180px">...</div>
  </article>
</main>
<script>
  alert(example.offsetParent.id); // main
  alert(example.offsetLeft); // 180 (bemærk: et tal, ikke en streng "180px")
  alert(example.offsetTop); // 180
</script>

Der er lejligheder hvor offsetParent er null:

  1. For ikke viste elementer (display:none eller ikke i dokumentet).
  2. For <body> og <html>.
  3. For elementer med position:fixed.

offsetWidth/Height

Nu til selve elementet.

Disse to egenskaber er de simpleste. De giver elementets “ydre” bredde/højde. Eller med andre ord, dets fulde størrelse inklusive rammer.

For vores eksempel gælder det at:

  • offsetWidth = 390 – den ydre bredde, kan beregnes som indre CSS-bredde (300px) plus padding (2 * 20px) og rammer (2 * 25px).
  • offsetHeight = 290 – den ydre højde.
Geometriske egenskaber er nul/null for elementer, der ikke vises

Geometriske egenskaber beregnes kun for viste elementer.

Hvis et element (eller en af dets forfædre) har display:none eller ikke er i dokumentet, er alle geometriske egenskaber nul (eller null for offsetParent).

For eksempel er offsetParent null, og offsetWidth og offsetHeight er 0, når vi har oprettet et element, men ikke har indsat det i dokumentet endnu, eller hvis det (eller en af dets forfædre) har display:none.

Vi kan bruge dette til at tjekke, om et element er skjult, sådan her:

function isHidden(elem) {
  return !elem.offsetWidth && !elem.offsetHeight;
}

Bemærk at sådan en isHidden returnerer true for elementer, der er på skærmen, men har nul størrelser.

clientTop/Left

Inde i elementet har vi rammerne.

For at måle dem, er der egenskaberne clientTop og clientLeft.

I vores eksempel:

  • clientLeft = 25 – venstre rammes bredde
  • clientTop = 25 – øverste rammes bredde

…Men for at være præcis – disse egenskaber er ikke rammens bredde/højde, men snarere relative koordinater af den indre side fra den ydre side.

Hvad er forskellen?

Det bliver synligt, når dokumentet er højre-til-venstre (operativsystemet er på arabisk eller hebraisk). Scrollbjælken er så ikke til højre, men til venstre, og så inkluderer clientLeft også scrollbjælkens bredde.

I det tilfælde vil clientLeft være ikke 25, men med scrollbjælkens bredde 25 + 16 = 41.

Hér er eksemplet på hebraisk:

clientWidth/Height

Disse egenskaber giver størrelsen af området inde i elementets rammer.

De inkluderer indholdsbredden sammen med padding, men uden scrollbjælken:

I forhold til billedet ovenfor, lad os først se på clientHeight.

Der er ingen vandret scrollbjælke, så det er præcis summen af det, der er inde i rammerne: CSS-højde (200px) plus top og bund padding (2 * 20px), i alt 240px.

Nu clientWidth – her er indholdsbredden ikke 300px, men 284px, fordi 16px er optaget af scrollbjælken. Så summen er 284px plus venstre og højre padding, i alt 324px.

Hvis der ikke er nogen padding, så er clientWidth/Height præcis indholdsområdet, inde i rammerne og scrollbjælken (hvis nogen).

Så når der ikke er nogen padding, kan vi bruge clientWidth/clientHeight til at få størrelsen af indholdsområdet.

scrollWidth/Height

Disse egenskaber er som clientWidth/clientHeight, men de inkluderer også de “ud-scrollede” dele (som jo egentligt er skjulte):

I forhold til billedet ovenfor:

  • scrollHeight = 723 – er den fulde indre højde af indholdsområdet inklusive de ud-scrollede dele.
  • scrollWidth = 324 – er den fulde indre bredde, her har vi ingen vandret scroll, så den er lig med clientWidth.

Vi kan bruge disse egenskaber til at udvide elementet til dets fulde bredde/højde.

Sådan her:

// Udvid elementet til dets fulde højde
element.style.height = `${element.scrollHeight}px`;

Klik på knappen for at udvide elementet:

tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst tekst

scrollLeft/scrollTop

Egenskaberne scrollLeft/scrollTop er bredden/højden af den skjulte, ud-scrollede del af elementet.

På billedet nedenfor kan vi se scrollHeight og scrollTop for en blok med en lodret scroll.

Med andre ord er scrollTop “hvor meget der er scrollet op”.

scrollLeft/scrollTop kan ændres

De fleste geometriske egenskaber her kan kun læses, men scrollLeft/scrollTop kan ændres, og browseren vil så rulle elementet.

Hvis du klikker på elementet nedenfor, udføres koden elem.scrollTop += 10. Det får elementets indhold til at rulle 10px ned.

Klik
Mig
1
2
3
4
5
6
7
8
9

Ved at sætte scrollTop til 0 eller en stor værdi, som 1e9, får vi elementet til at rulle til toppen/bunden.

Tag ikke højde/bredde fra CSS

Vi har netop dækket geometriske egenskaber af DOM-elementer, der kan bruges til at få bredder, højder og beregne afstande.

Men som vi ved fra kapitlet Styles og classes, kan vi læse CSS-højde og bredde ved hjælp af getComputedStyle.

Hvorfor ikke så bruge getComputedStyle til at få bredden af et element, sådan her?

let elem = document.body;

alert( getComputedStyle(elem).width ); // vis CSS-bredde for elem

Hvorfor skulle vi så bruge geometriske egenskaber i stedet? Der er to grunde:

  1. Først afhænger CSS width/height af en anden egenskab: box-sizing, der definerer, “hvad” CSS-bredden og&#8209;højden omfatter. En ændring i box-sizing til CSS-formål kan ødelægge sådan et stykke JavaScript.

  2. Dernæst kan CSS width/height være auto, for eksempel for et inline element:

    <span id="elem">Hello!</span>
    
    <script>
      alert( getComputedStyle(elem).width ); // auto
    </script>

    Set fra et CSS-perspektiv er width:auto helt normalt, men i JavaScript har vi brug for en præcis størrelse i px, som vi kan bruge i beregninger. Så her er CSS-bredden ubrugelig.

Og så er der endnu en grund: scrollbjælken. Nogle gange bliver kode, der fungerer fint uden en scrollbjælke, fejlbehæftet med en scrollbjælke, fordi en scrollbjælke optager plads fra indholdet i nogle browsere. Så den reelle bredde, der er til rådighed for indholdet, er mindre end CSS-bredden. Og clientWidth/clientHeight tager højde for det.

…Men med getComputedStyle(elem).width er situationen anderledes. Nogle browsere (f.eks. Chrome) returnerer den reelle indre bredde, minus scrollbjælken, og nogle af dem (f.eks. Firefox) – CSS-bredden (ignorerer scrollbjælken). Sådan en tværbrowser-forskel er grunden til ikke at bruge getComputedStyle, men snarere stole på geometriske egenskaber.

Hvis din browser reserverer plads til en scrollbjælke (de fleste browsere til Windows gør), så kan du teste det nedenfor.

Elementet med tekst har CSS width:300px.

På et Desktop Windows-operativsystem reserverer Firefox, Chrome og Edge alle plads til scrollbjælken. Men Firefox viser 300px, mens Chrome og Edge viser mindre. Det skyldes, at Firefox returnerer CSS-bredden, mens andre browsere returnerer den “reelle” bredde.

Bemærk, at den beskrevne forskel kun gælder for at læse getComputedStyle(...).width fra JavaScript; visuelt er alt korrekt.

Opsummering

Elementer har følgende geometriske egenskaber:

  • offsetParent – er den nærmeste positionerede ancestor eller td, th, table, body.
  • offsetLeft/offsetTop – koordinater i forhold til den øverste venstre kant af offsetParent.
  • offsetWidth/offsetHeight – “ydre” bredde/højde af et element inklusive rammer.
  • clientLeft/clientTop – afstandene fra det øverste venstre ydre hjørne til det øverste venstre indre hjørne (indhold + padding). For venstre-til-højre operativsystemer er det altid bredden af venstre/øverste ramme. For højre-til-venstre operativsystemer er den lodrette scrollbjælke til venstre, så clientLeft inkluderer også dens bredde.
  • clientWidth/clientHeight – bredden/højden af indholdet inklusive padding, men uden scrollbjælken.
  • scrollWidth/scrollHeight – bredden/højden af indholdet, ligesom clientWidth/clientHeight, men inkluderer også den ud-scrollede, usynlige del af elementet.
  • scrollLeft/scrollTop – bredden/højden af den ud-scrollede øverste del af elementet, startende fra dets øverste venstre hjørne.

Alle egenskaber kan kun læses undtagen scrollLeft/scrollTop, som får browseren til at rulle elementet, hvis de ændres.

Opgaver

vigtighed: 5

Egenskaben elem.scrollTop viser den del af indholdet, der er scroll’et ud fra toppen. Hvordan får man størrelsen på den del af indholdet, der er scroll’et ud fra bunden (lad os kalde den scrollBottom)?

Skriv en kode der virker for et vilkårligt element.

P.S. Tjek din kode: hvis der ikke er nogen scroll eller elementet er fuldt scroll’et ud, så skal den returnere 0.

Løsningen er:

let scrollBottom = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

Eller med andre ord: (fuld højde) minus (ud-scrollet top del) minus (synlig del) = den ud-scrollede bund del.

vigtighed: 3

Skriv koden der returnerer bredden på en standard scrollbjælke.

For Windows varierer den normalt mellem 12px og 20px. Hvis browseren ikke reserverer plads til den (scrollbjælken er halvt gennemsigtig over teksten, hvilket også sker), kan den være 0px.

P.S. Koden skal virke for et vilkårligt HTML dokument og må ikke afhæng af dets indhold.

For at få bredden på en scrollbjælke kan vi oprette et element med scroll, men uden rammer og padding.

Forskellen mellem dets fulde bredde offsetWidth og den indre indholdsarealbredde clientWidth vil være præcis scrollbjælken:

// Opret et div element med scroll
let div = document.createElement('div');

div.style.overflowY = 'scroll';
div.style.width = '50px';
div.style.height = '50px';

// Vi skal indsætte elementet i dokumentet, ellers vil dimensionerne være 0
document.body.append(div);
let scrollWidth = div.offsetWidth - div.clientWidth;

div.remove();

alert(scrollWidth);
vigtighed: 5

Her er hvordan kilde dokumentet ser ud:

Hvad er koordinaterne for midten af feltet?

Beregn det og brug det til at placere bolden i midten af det grønne felt:

  • Elementet skal flyttes af JavaScript, ikke CSS.
  • Koden skal virke med enhver boldstørrelse (10, 20, 30 pixels) og enhver feltstørrelse. Den må ikke være bundet til de givne værdier.

P.S. Selvfølgelig kunne centrering gøres med CSS, men her vil vi specifikt have JavaScript. Senere møder vi andre og mere komplekse situationer, hvor JavaScript skal bruges. Betragt dette som en “opvarmning”.

Åbn en sandbox til opgaven.

The ball has position:absolute. It means that its left/top coordinates are measured from the nearest positioned element, that is #field (because it has position:relative).

The coordinates start from the inner left-upper corner of the field:

The inner field width/height is clientWidth/clientHeight. So the field center has coordinates (clientWidth/2, clientHeight/2).

…But if we set ball.style.left/top to such values, then not the ball as a whole, but the left-upper edge of the ball would be in the center:

ball.style.left = Math.round(field.clientWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2) + 'px';

Here’s how it looks:

To align the ball center with the center of the field, we should move the ball to the half of its width to the left and to the half of its height to the top:

ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px';

Now the ball is finally centered.

Attention: the pitfall!

The code won’t work reliably while <img> has no width/height:

<img src="ball.png" id="ball">

When the browser does not know the width/height of an image (from tag attributes or CSS), then it assumes them to equal 0 until the image finishes loading.

So the value of ball.offsetWidth will be 0 until the image loads. That leads to wrong coordinates in the code above.

After the first load, the browser usually caches the image, and on reloads it will have the size immediately. But on the first load the value of ball.offsetWidth is 0.

We should fix that by adding width/height to <img>:

<img src="ball.png" width="40" height="40" id="ball">

…Or provide the size in CSS:

#ball {
  width: 40px;
  height: 40px;
}

Åbn løsningen i en sandbox.

vigtighed: 5

Hvad er forskellen mellem getComputedStyle(elem).width og elem.clientWidth?

Angiv mindst 3 forskelle. Jo flere jo bedre.

Forskelle:

  1. clientWidth er et tal, mens getComputedStyle(elem).width returnerer en streng med px til sidst.
  2. getComputedStyle kan returnere ikke-numerisk bredde som "auto" for et inline-element.
  3. clientWidth er det indre område for elementet plus padding, mens CSS-bredden (med standard box-sizing) er det indre område uden padding.
  4. Hvis der er en scrollbjælke, og browseren reserverer plads til den, trækker nogle browsere den plads fra CSS-bredden (da den ikke længere er tilgængelig for indhold), og andre gør ikke. Egenskaben clientWidth er altid den samme: scrollbjælkens størrelse trækkes fra, hvis den er reserveret.
Tutorial-oversigt

Kommentarer

læs dette før du kommenterer…
  • Hvis du har forslag til forbedringer - så opret venligst et GitHub-issue eller en pull request i stedet for at kommentere.
  • Hvis du ikke forstår noget i artiklen - så uddyb venligst.
  • For at indsætte få ord kode, brug <code>-taggen, for flere linjer - omslut dem i <pre>-tag, for mere end 10 linjer - brug en sandbox (plnkr, jsbin, codepen…)