Webサイトの共通ヘッダーがスクロールに対して画面上部に固定されるような実装においては、ページ内リンクによってWebページ内の特定の箇所に移動する場合、そのままだと固定されたヘッダーがリンク先となる箇所に重なってしまうことが起こり得る。これを避けるため、ヘッダーの高さ分ずらして(オフセットさせて)スクロールさせることを、スムーズスクロールと同様にJavaScriptを用いて実装していた。
しかし、現在はCSSの記述のみで解決できる。例えば、ヘッダー部分の高さが80pxで、その分ページ内リンクをオフセットさせたいのであれば、以下のように指定するだけで実装できる。
scroll-padding-top
scroll-padding-top は手動ではなく、自動的にスクロールが行われたときに有効になる機能で、これらをheaderと同じ高さ分指定しておくことで、被ることがなくなる。
headerの高さをcss変数(カスタムプロパティ)で定義しておけば、headerの高さを変える場合でも、css変数の値を変えるだけでscroll-padding-topとheaderの高さの二箇所を同時に変更できる。
/*
css変数は詳細度の関係からhtmlではなく、:rootがいいらしい
*/
:root {
--header-height: 80px; /* headerの高さを変える時はここだけ変えれば良くなる */
scroll-padding-top: var(--header-height);
}
header {
height: var(--header-height);
}
scroll-margin-top
scroll-padding-topはhtmlなどのスクロールすることができる要素につけることで有効になり、scroll-margin-topはスクロールする要素の中にある子要素(htmlなどの子要素)につけることで有効になる。
<a href="#test1">test1</a>
<a href="#test2">test2</a>
<section id="test1"></section>
<section id="test2"></section>
上記のようにページ内リンクが複数あるときにリンクをクリックしてスクロールさせた時に、
- どの要素に飛んでもページ上部に隙間を空けたいときは、scroll-padding-top
- 特定の要素に飛んだ時のみ、ページ上部に隙間を開けたいときは、scroll-margin-top
といった感じで使い分ける。
:root {
scroll-padding-top: 100px; /* どの要素にスクロールしても100pxは空く */
}
/* :root(html)ではなく、section#test1に指定していることに注意! */
#test1 {
scroll-margin-top: 300px; /* この要素のみスクロールした時に300px空く */
}