position: fixed;でページ内リンクの頭出しがずれる件の解決策を考えてみる
最近の流行りかは分かりませんが、ヘッダー、もしくはナビゲーションだけが スクロールの途中から固定するサイトをつくる機会が増えてきました。
そのデザインを見た時の毎回の悩みは、「ページ内リンクの頭出しがずれるのをどうしよう...」ということでした。
今日もまた同じことで悩んだので少し調べつつ、解決策を考えてみました。
この状況が発生するシチュエーション
- コンテンツより前に存在する要素(ヘッダー・ナビなど)をposition: fixed;で固定している
ネットに載っていた解決策
CSSで解決する方法
頭出しの対象となる要素(見出しなど)に以下のCSSを指定する
padding-top: 100px; /* 固定するもののheightと同じpx値 */
margin-top: -100px; /* 固定するもののheightと同じpx値 */
JavaScriptで解決する方法
- ページ表示時にズレた分のscrollTopを調整する
- smoothScrollなどページ内リンクを制御するjsのスクロール位置を調整する
コーディングを変えたくなかったため、Javascriptが有力とは思ったのですが パソコンだけでなく様々な環境で閲覧されることを想定するとscrollTopをJSで 調整するのはいささか怖い...と思い見送りました。
そこで対処方法はCSSでの対策一本に絞りました。
margin / paddingを使用した解決方法の問題点
結論から言いますと上記の方法で治りました。
ただ、margin / paddingは普通であればスタイリングにすでに 使用していることが多いと思います。
今回の案件でもかなりコーディングが進んでいたので影響が広範囲に及びました。
(padding-topのせいで背景がズレる、border-leftの長さがpadding分伸びる、marginの相殺が起きる...などなど)
そこで思い出したのがアンカータグ(aタグ)です。
昔、aタグはリンクURLを指定するだけの用途ではなく、飛び先を指定することにも
使用されていました。
<a name="xxx" id="xxx" />
margin / paddingのスタイルをこの対策のために変更しても影響範囲を狭くしたい、と思い 以下のようなコーディングに変更を行ってみました。
変更前
<h5 id="xxx">aaa</h5>
変更後(HTML)
<h5 class="m-txt-ttl5"><a id="xxx" />aaa</h5>
変更後(CSS/差分のみ)
.m-txt-ttl5 > a {
display: block; padding-top: 100px; margin-top: -100px;
}
問題は解決し、CSSはクリーンになりましたがHTMLが...ということで 今ひとつモヤモヤが残っています。
これまでに上げた理由からこのようなコーディングで一旦は凌ぎつつ、 様々なサイトの実装例を見て勉強してみようと思います。
JavaScriptを使用せずにCSSの範囲だけでこの問題を解決する方法を ご存知の方がいらっしゃいましたら、アドバイスいただけると幸いです。