CSSでposition: sticky;
と設定し、ページジャンプを試みた際のものをまとめました。
どんな状況か
- 本文中にいくつか見出しがあり、閲覧中の見出しを常にページ上部で留めておきたい。
- 目次を設け、ページ内ジャンプで任意の見出しへ移動したい
実際に記述する
コードも短いので先に全て記載します。
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<nav>
<ul>
<li><a href="#">TOP</a></li>
<li><a href="#first">First</a></li>
<li><a href="#second">Second</a></li>
</ul>
</nav>
<h1>ページタイトル</h1>
<h2 id="first">First</h2>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<!-- 以下略 -->
<h2 id="second">Second</h2>
<p>素晴らしい本文(sticky要素2)</p>
<p>素晴らしい本文(sticky要素2)</p>
<!-- 以下略 -->
</body>
nav {
position: fixed;
right: 0;
z-index: 100;
background-color: #fff;
}
h2 {
position: sticky;
top: 0;
background-color: #fff;
border-style: solid;
border-width: 0 0 .1rem 0;
}
表示結果は上の画像。
挙動確認
順番に検証して確認する。
TOP から First OR Second へジャンプ
- 結果:飛べる
First から Second へジャンプ
- 結果:飛べる
First OR Second から TOP へジャンプ
- 結果:飛べない
Second から TOP OR First へジャンプ
- 結果:飛べない
検証結果
position: sticky;
プロパティが付与された要素へ、同じブロック内からジャンプできない。
上手くいかない理由
同じブロック内(今回はmain
)でその要素より下にスクロールしている場合、同じsticky
要素が覆っている状況なためである。
実際にChromeのデベロッパーモードで要素を消して確認する。
-
Second
を消す前
-
Second
を消した後
隠れている部分にid
のプロパティを持つ要素が付いてきている。
勿論、この状態でFirstにジャンプしてもジャンプされているように見えないのは納得できると思う。
どう解決するか
<section>
タグを使う
<section>
は HTML の要素で、文書の自立した一般的なセクション(区間)を表します。そのセクションを表現するより意味的に具体的な要素がない場合に使用します。少数の例外を除いて、セクションには見出しを置いてください。
引用: https://developer.mozilla.org/ja/docs/Web/HTML/Element/section
と記されているので実際に使う。
<!-- 前略 -->
<h1>ページタイトル</h1>
+ <section>
<h2 id="first">First</h2>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
+ </section>
<!-- 後略 -->
Second
も同様に記述する。
結果
-
Second
からFirst
にジャンプした結果
このようにジャンプした。
違う
div
要素を直前に設けて id
を付与する
div
(またはspan
)タグを直前に配置してid
を付与すれば擬似的にジャンプできるのでは、という仮説です。
<!-- 前略 -->
<h1>ページタイトル</h1>
<section>
<div id="first"></div> <!-- この行を追加 -->
<h2>First</h2>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
<p>素晴らしい本文(sticky要素1)</p>
</section>
<!-- 後略 -->
結果
-
Second
からFirst
にジャンプした結果
成功
成功したものの、シンプルに実装したとは言えない結果となった。
結論
div
タグまたはspan
タグを直前に配置してid
を付与すれば擬似的に成功する。
可能ならHTMLを殆ど変更せずに実現したいところ。また分かり次第追記する。
参考