情報量が多く縦に長いWebページではページ内をスクロール移動させるアンカーリンクを設置することはよくあります。
その際、Webページ内のヘッダー要素を固定していると、アンカーリンクをクリックしてスクロール移動した位置と固定ヘッダー要素が被ってしまう、という事象に陥ることがあります。

アンカーリンクで移動した位置に固定ヘッダーが被ってしまう動作サンプル

この固定ヘッダーを被らないようにするには、スクロールさせる位置の要素の上部に固定ヘッダーの高さ分の余白を付けておくなど、画面構成において余白の対策が必要になったりするのですが、そのような煩わしい調整をせずにCSSのbefore疑似要素を使って簡単に解消する方法があったのでご紹介してみます。

CSSのbefore疑似要素を使ってページ内アンカーリンクでスクロールした位置と固定ヘッダー要素が被らないようにする方法

「CSSのbefore疑似要素を使ってページ内アンカーリンクでスクロールした位置と固定ヘッダー要素が被らないようにする方法」サンプルを別枠で表示

冒頭で紹介している動作サンプルでは、アンカーリンクでスクロールした位置に固定ヘッダーが被ってしまっていました。

上記のサンプルではHTMLなどの基本構造は同じですが、アンカーリンクでスクロールしても固定ヘッダーが該当位置の要素に被らずに停止位置を調整しています。

このアンカーリンクのスクロール位置の制御について、まずはHTMLから。

◆HTML
<nav>
<ul>
<li><a href="#section1">> SECTION 1</a></li>
<li><a href="#section2">> SECTION 2</a></li>
<li><a href="#section3">> SECTION 3</a></li>
<li><a href="#section4">> SECTION 4</a></li>
</ul>
</nav>

アンカーリンクのメニュー部分はページ内のIDに飛ばすように、リンク先を「#」をつけたID名にします。

これに対して、このサンプルでは、飛ばす先の要素は「section」で囲って構成しています。
※もちろん「section」以外のタグでも可。

◆HTML
<section id="section1">
<h2>SECTION 1</h2>
<p>・・・・・</p>
<p>・・・・・</p>
   ・
   ・
   ・
</section><!-- /#section1 -->

<section id="section2">
<h2>SECTION 2</h2>
<p>・・・・・</p>
<p>・・・・・</p>
   ・
   ・
   ・
</section><!-- /#section2 -->
   ・
   ・
   ・

スクロール動作のスクリプト動作については、この記事では割愛させていただきますが、リンク先が「#」のついたID名となっている要素をクリックしたら該当箇所にスクロール移動させる構成になります。

このままで単純にCSSでレイアウト調整をするだけだとスクロールした位置にヘッダー要素が被ってしまいます。

そこで、スクロール移動させる対象となる「section」にbefore疑似要素をつけて停止位置を制御するようにします。

実際の「section」につけるbefore疑似要素の内容は以下のように指定します。

◆CSS
section:before {
	content: " ";
	margin-top: -120px;
	height: 120px;
	display: block;
	visibility: hidden;
}

before疑似要素でヘッダー要素の高さ(+多少の余白)分の空のブロック要素を追加して「margin-top」の位置をネガティブマージンでヘッダー要素の高さ分を上に移動させます。
※サンプルではヘッダー要素の高さが「100px」になっています。

アンカーリンクでスクロール移動した際は、このbefore疑似要素をつけた位置でスクロールが停止することになります。

このようにbefore疑似要素で位置を調整するだけでアンカーリンクで移動させる要素に対して、固定ヘッダーがあっても停止位置と被ることなく指定させることが可能になります。

※今回のサンプルは「CSS-Tricks」さんの記事を参考にさせていただいております。
【参考記事】Hash Tag Links That Don't Headbutt The Browser Window | CSS-Tricks

以上がCSSのbefore疑似要素を使ってページ内スクロールでリンクした位置と固定したヘッダー要素が被らないようにする方法でした。

意外とこのアンカースクロールの位置調整は画面の余白などレイアウトで調整しようとすると面倒だったりするので、このようにbefore疑似要素を使って制御ができると、とても便利になるかと思います。

ページ内スクロールでリンクした位置と固定したヘッダー要素が被らないようにする際にぜひ。。。

サンプルファイルをダウンロードしたい方はこちらから