2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【css2行だけ】ページ内リンクでターゲットの少し上に着地する「scroll-padding-top」

Last updated at Posted at 2024-03-07

ページ内リンクのリンク先は h2 などの見出しにしたい

h2 (見出し)にはアクセシビリティの観点的な都合で id を付与したい。
その id をページ内リンクのターゲットとして流用するのがスマートな感じがする。

ところが見出しを直接ページ内リンクのターゲットにすると、ページの上ギリギリになったり、固定のヘッダーが付いてくる場合はそれに隠されたりしちゃう。

「ページ内リンクのちょっと上に着地させたい」

「scroll-padding-top」という神プロパティ

@chocolamint 様に教えていただきました!)

htmlにこの2行を書くだけです。

  • scroll-snap-type: y proximity;
  • scroll-padding-top: 70px;

ついでにスムーススクロールつけるのも、これで完了。

css
html {
	scroll-snap-type: y proximity;
	scroll-padding-top: 70px;
 	scroll-behavior: smooth;
}

安心の主要ブラウザフルサポート済です。
※参考:MDN

(旧版)ターゲットの少し上に着地する方法

従来の方法は2種類ありました。

  1. cssを使った超シンプルな方法
  2. cssだと上手くいかない時にjsを使う方法

cssを使って、見出しの上に空間を作る

scsss
.c-heading {
    // (中略)
    paddint-top: 70px;
    margin-top: -70px;
}

これだけで見出しの上 70px のところに着地する。
ところが、見出しの style によってはこれを追加するのが難しいかもしれない。

jsを使って、ターゲットの少し上に着地させる

js
const headerHeight = 70;
const links = document.querySelectorAll('a[href^="#"]');

links.forEach(link => {
  link.addEventListener('click', function(event) {
    event.preventDefault();
    const href = this.getAttribute('href');
    const target = href === '#' ? document.documentElement : document.querySelector(href);
    const position = target.getBoundingClientRect().top + window.pageYOffset - headerHeight;
    window.scrollTo({
      top: position,
      behavior: 'smooth'); // smooth or instant
  });
});
2
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?