Sticky Nav verbergt ankerlinks: een nette oplossing met slechts een paar inline CSS-regels

Wanneer je in een document (blog/ wiki/gids) op een voetnootlink of een TOC (table of contents) klikt, springt de browser naar #some-id en brengt het element met die id precies op de bovenkant van het viewport.\n\nMaar als er bovenaan een position: sticky (of fixed) navigatiebalk staat, wordt het element wel naar de bovenkant gescrold, terwijl de daadwerkelijke inhoud zich achter de nav verbergt.

Dit is een veelvoorkomend front‑end probleem, maar voor back‑end of full‑stack ontwikkelaars kan het vragen: "Waarom is de link wel aangeklikt, maar zie ik de inhoud niet?"\n\nHier beschrijf ik mijn meest gebruikte aanpak: enkele inline CSS‑regels toevoegen aan de pagina – de eenvoudigste en snelste oplossing.


Waarom gebeurt dit?



De standaardwerking van de browser is als volgt:

  • Als de URL verandert naar .../page#target
  • Zoekt de browser het element met id="target\n* Scrollt het element naar de bovenkant van de scrollcontainer (meestal de viewport top).

Een sticky nav wordt echter boven de viewport gerenderd, waardoor het element onder de nav verborgen raakt.

Voorbeeld van een verborgen target door een sticky nav


De eenvoudigste oplossing: scroll-margin-top (ruimte boven het element)

Door scroll-margin-top toe te voegen aan het element dat je via een anker laat scrollen, probeert de browser het element niet helemaal naar de bovenkant te plaatsen, maar iets lager.

Inline CSS voor minimale toepassing (aanbevolen)

Voeg in de <head> of het template van de pagina het volgende toe:

<style>
  :root { --sticky-nav-h: 64px; } /* pas aan op de werkelijke hoogte van de nav */
  [id] { scroll-margin-top: calc(var(--sticky-nav-h) + 12px); }
</style>
  • --sticky-nav-h: hoogte van de sticky nav
  • + 12px: een kleine marge om te voorkomen dat het element nog steeds net onder de nav valt (je kunt dit aanpassen).

Door [id] globaal toe te passen, worden alle anker‑doelen op de pagina automatisch gecorrigeerd. Als dit te breed is, kun je de selectie beperken, zie hieronder.

De selectie beperken voor meer veiligheid

Bijvoorbeeld alleen in het artikelgebied:

<style>
  :root { --sticky-nav-h: 64px; }
  .article [id] { scroll-margin-top: calc(var(--sticky-nav-h) + 12px); }
</style>

Of alleen voor h2/h3 als de TOC daarheen springt:

<style>
  :root { --sticky-nav-h: 64px; }
  .article h2[id], .article h3[id] {
    scroll-margin-top: calc(var(--sticky-nav-h) + 12px);
  }
</style>

Extra optie: scroll-padding-top (basis padding voor de container)



scroll-padding-top geeft de scrollcontainer een veilige bovenkant voor scroll‑snap of fragment‑navigatie. In de praktijk is scroll-margin-top intuïtiever, maar een combinatie kan de stabiliteit vergroten.

<style>
  :root { --sticky-nav-h: 64px; }
  html { scroll-padding-top: calc(var(--sticky-nav-h) + 12px); }
</style>
  • Handig voor een snelle, pagina‑breed correctie.
  • Voor fijnmazige controle blijft scroll-margin-top de voorkeur.

Legacy‑truc voor compatibiliteit: een nep‑offset met ::before

Een oude, maar nog steeds werkende methode is om vóór het doel een onzichtbaar blok te plaatsen, waardoor het element onder de nav wordt verschoven.

<style>
  :root { --sticky-nav-h: 64px; }

  .anchor-target::before {
    content: "";
    display: block;
    height: calc(var(--sticky-nav-h) + 12px);
    margin-top: calc(-1 * (var(--sticky-nav-h) + 12px));
    visibility: hidden;
    pointer-events: none;
  }
</style>

Voorbeeldgebruik:

<h2 id="install" class="anchor-target">Installatie</h2>
  • Voordeel: werkt vrijwel altijd, omdat het een echte offset creëert.
  • Nadeel: vereist een extra klasse en meer aandacht voor de structuur.

Gebruik scroll-margin-top eerst; als dat niet werkt, overweeg dan de ::before‑truc.


JavaScript‑oplossingen zijn ook mogelijk, maar inline CSS is vaak beter

Je kunt ook scrollIntoView() gebruiken en vervolgens window.scrollBy(0, -navHeight) aanpassen. Toch is CSS meestal de voorkeur.

  • Voor statische of document‑rijke pagina’s (veel voetnoten/TOC)
  • Wanneer je zonder framework‑routing een snelle, pagina‑specifieke oplossing wilt
  • Als de onderhouders geen front‑end specialisten zijn

Een paar inline <style>‑regels zijn zonder afhankelijkheden, makkelijk te debuggen en kunnen eenvoudig worden teruggedraaid.


Praktische checklist

  • Bepaal de exacte hoogte van de sticky nav
  • Bij responsieve nav kun je --sticky-nav-h per breakpoint aanpassen.
  • Beperk de scope niet te breed
  • [id] is handig, maar kan te veel beïnvloeden; overweeg .article [id].
  • Voeg een kleine marge (+8–16 px) toe voor een betere perceptie
  • Alleen de exacte nav‑hoogte kan soms te strak voelen.

Conclusie: mijn favoriete aanpak

Voeg simpelweg het volgende inline toe aan de pagina die het probleem heeft:

<style>
  :root { --sticky-nav-h: 64px; }
  .article [id] { scroll-margin-top: calc(var(--sticky-nav-h) + 12px); }
</style>

Dit lost meestal TOC, voetnoten en diepe links in één keer op. Hopelijk helpt dit ontwikkelaars die het probleem van verborgen links achter een sticky nav willen verhelpen.


Gerelateerde artikelen
- Waarom het specificeren van width en height in een afbeeldingstag belangrijk is
- Zelfs backend engineers moeten deze dingen weten - Top 5 frontend JS-methoden en modules