ページ内リンクのリンク先は 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種類ありました。
- cssを使った超シンプルな方法
- 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
});
});