WEB Tips デザイン・コーディング

position:fixed 固定時にアンカーリンクがずれるのを解決する

2015-06-16

本記事にはプロモーションが含まれています。

position:fixed 固定時にアンカーリンクがずれるのを解決する

ソラミ♪

Webエンジニアをやりつつ、デザインにも携わる株式会社コムワークの中の人。WordPress、Adobeアプリ、カワウソ好き。 2015年から当ブログ運営|2008年からGmail使用中|WordPress制作10年以上|15社以上のレンタルサーバー利用経験|100件以上のドメイン取得運用|サイト・ドメイン移転多数 »  もっとくわしく

ヘッダーナビゲーションなどを固定するスタイルは良くみかけるデザインですよね。

ヘッダーをスクロールに追従させることで、ユーザーがわざわざページ上部に戻らなくてもすぐにナビゲーションにアクセスできるようになります。

スマホでの縦に長いページにはユーザービリティが向上する有用な手段です。また、ヘッダーナビゲーションにはメニューや検索フォームなど、重要な機能が含まれることが多いため、それらのアクセス性が向上します。

ヘッダーをページ上部に固定したり、下部にナビゲーションを固定するための方法にはposition:fixedを使って固定するのが一般的です。

position:fixedを使った時に手こずるのが、アンカーの位置がずれてしまう問題。

ページ内リンクにジャンプすると、リンク先が固定ヘッダーの下に隠れてしまいます。

See the Pen position:fixedでアンカーがずれる状態 by mixtaro (@mixtaro) on CodePen.

このアンカーがずれてしまうのを解決する方法で、従来からある方法とCSSでより簡単に解決できる方法を説明します。

ネガティブマージンとパディングを設定する

まずは従来から使われている固定したヘッダーの高さ分のネガティブマージンと、高さ相殺用のパディングを設定する方法です。

See the Pen position:fixedでアンカーがずれる margin/padding by mixtaro (@mixtaro) on CodePen.

/* 固定ヘッダー */
header{
  position:fixed;
  height:60px; /* 高さを指定しておく */
}

リンク先の要素に固定ヘッダーの高さ分のネガティブマージンとパディングを指定します。

h2[id^="header"]{
  margin-top:-60px;
  padding-top:60px;
}

scroll-margin-topプロパティを使用する

scroll-margin-topプロパティはCSS スクロールスナップというCSSの機能のうちの一つで、

CSS スクロールスナップ (CSS Scroll Snap) は CSS モジュールの一つで、スクロール操作の完了後にスクロールコンテナーのスクロールポートが終了するスクロール位置を強制する、スクロールスナップ位置を導入します。

MDN CSSスクロールスナップ

とMDNにあるようにスクロール時の挙動を制御してスクロール位置を特定の位置で止めたりできる機能です。

以前はブラウザによって未対応だったり、バグがあったりした見たいですが現在はちゃんと動いてくれるようになっています。

scroll-margin-topの対応状況

caniuse https://caniuse.com/mdn-css_properties_scroll-margin-top

See the Pen position:fixedでアンカーがずれる scroll-margin-top by mixtaro (@mixtaro) on CodePen.

使い方は先程と同様にアンカーのリンク先になる要素にscroll-margin-topプロパティを設定し、ヘッダーの高さ分の余白を指定することで解決できます。

h2[id^="header"]{
  scroll-margin-top:60px;
}

:targetセレクタ、カスタムプロパティを使った今時のやり方

:targetセレクタにスクロールマージンを指定すれば個別に対応する必要がなくなります。

:target {
  scroll-margin-top: 60px;
}

さらにカスタムプロパティを作成しておけば、メンテナンス性も向上します。

:root {
  --header-h: 60px;
}
:target {
  scroll-margin-top: var(--header-h);
}

header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--header-h);
  background-color: #624763;
  color: #fff;
}

カスタムプロパティも最強です。

See the Pen position:fixedでアンカーがずれる :target selector by mixtaro (@mixtaro) on CodePen.

scroll-padding-topを使ってアンカーの位置を調整する

scroll-margin-topと同じようにscroll-padding-topプロパティを使ってアンカー位置を調整することができます。

See the Pen position:fixedでアンカーがずれる scroll-padding-top by mixtaro (@mixtaro) on CodePen.

html {
  scroll-padding-top:var(--header-h);
}

scroll-padding-topの場合は適用対象が「スクロールコンテナー」となります。なのでリンク先要素に設定するのではなく、html要素にscroll-padding-topを指定します。

MDN:scroll-padding-top

jQueryでヘッダー高さを取得しアンカーの位置を調整する方法

最後にCSSで解決できることが多くなったので使う機会は少ないかと思いますが、一応jQueryを使った解決方法も記載します。

See the Pen position:fixedでアンカーがずれる jQuery by mixtaro (@mixtaro) on CodePen.

$(function() {
  $('a[href^="#"]').click(function() {
    var headerHeight = $('header').outerHeight();
    var href = $(this).attr('href');
    var target = $(href == '#' || href == '' ? 'html' : href);
    var position = target.offset().top - headerHeight;
    $('html, body').animate({scrollTop: position}, 500, 'swing');
    return false;
  });
});

このコードでは、ヘッダーの高さを取得してアンカーの位置を調整しています。

以上、position:fixedで要素を固定した時にアンカーが隠れてしまうのを解決する方法を紹介しました。ここ数年でCSSだけでできることが大幅に増えたような気がします。

  • この記事を書いた人
  • 最新記事

ソラミ♪

Webエンジニアをやりつつ、デザインにも携わる株式会社コムワークの中の人。WordPress、Adobeアプリ、カワウソ好き。 2015年から当ブログ運営|2008年からGmail使用中|WordPress制作10年以上|15社以上のレンタルサーバー利用経験|100件以上のドメイン取得運用|サイト・ドメイン移転多数 »  もっとくわしく

-WEB Tips, デザイン・コーディング
-,