﻿---
title: Fix Markdown Footnote Jump Overlap with CSS scroll-margin-top
date: 2025-11-17
tags:
  - Web
  - Blog
  - CSS
  - UIUX
excerpt: Fix the common problem where fixed top navbars hide jump targets using scroll-margin-top rule
updated: 2026-05-08 22:10:51
---

Markdown footnotes and header anchors let readers jump to specific positions within a page. But when a blog has a fixed top navigation bar, the target content often ends up hidden underneath it after the jump.

> Footnotes allow you to add notes and references without cluttering the body of the document. When you create a footnote, a superscript number with a link appears where you added the footnote reference. Readers can click the link to jump to the footnote content at the bottom of the page.
>
> <cite>[Markdown Footnotes | Markdown Guide](https://www.markdownguide.org/extended-syntax/#footnotes)</cite>

## The HTML Structure in This Blog

To understand why the selectors in the solution look the way they do, it helps to first look at the actual HTML this blog generates.

### Header Anchors

When you write a heading in Markdown:

```md
## My Heading
```

Hexo renders it as:

```html
<h2 id="my-heading">
  <a class="header-anchor" href="#my-heading">#</a>
  My Heading
</h2>
```

Notice that the **`id` is on the `<h2>` itself**, not on the inner `<a>`. The `<a class="header-anchor">` is only the clickable `#` symbol.

### Footnotes

The footnote reference in the body becomes:

```html
<sup class="footnote-ref">
  <a href="#fn1" id="fnref1">[1]</a>
</sup>
```

The actual footnote at the bottom of the page is rendered as a list item:

```html
<li class="footnote-item" id="fn1">
  <p>This is the first footnote.</p>
  <a class="footnote-backref" href="#fnref1">↩</a>
</li>
```

These are the exact elements the CSS selectors in the next section target.

## The Solution

Set `scroll-margin-top` on every element that might become a jump target, leaving enough space for the fixed navbar:

```css
sup.footnote-ref > a,
li.footnote-item,
h2,
h3,
h4,
h5,
h6 {
  scroll-margin-top: 5rem;
}
```

`{css} scroll-margin-top` controls how much space to leave at the top when scrolling to an element. It only takes full effect when there is **enough scrollable space**. If the page content is short and the scroll distance is insufficient to reach the requested offset, the element may not appear exactly where expected.

## Smooth Scrolling

You might be tempted to add smooth scrolling globally:

```css
html {
  scroll-behavior: smooth;
}
```

This works, but be aware that it applies to **all** scrolls, including those triggered by user navigation (back/forward buttons, URL fragments). If you want smooth scrolling only for anchor jumps triggered by clicks within the page, apply it more selectively or use `{js} element.scrollIntoView({ behavior: 'smooth' })` in JavaScript.
