わたしと納豆ごはん

納豆、Web、雑記など

ヘッダ固定時のページ内リンクのズレをCSSだけで解消する3つのテクニック

ブログやサイトで固定ヘッダーを設置すると、気になるモノとしてページ内リンクのズレがあります。

ページ内リンクで移動すると、リンク先が固定ヘッダーの下になってしまうというアレです。

この解決法としてはJavaScriptで調整するのが無難なのですが、スクリプト無効の環境向けにCSSだけでズレを解消したいという時もあります。

今回は、そんな時に役立つかもしれないCSSだけで行なうページ内リンクのズレ解消のテクニックです。

スポンサーリンク

paddingを使った基本的な方法

まず検索で調べると、次のものがよく出て来ます。これが基本的な方法です。

#ターゲット要素 {
    padding-top: 50px;
    margin-top: -50px;
}

リンク先の要素のpaddingを使ってヘッダーの高さ分ずらし、ずらした分をネガティブマージンで戻す方法です。要素がインラインならばmargin-topは効かないので要りません。

基本的にはこれでズレを解消できます。目次から見出しなどへのページ内リンクなどに使えます。

ただし、ページ内リンクのリンク先が a 要素などの場合、判定の範囲が広がってしまうので注意が必要です。例えば文章中に設定したら上の段にまでリンク判定の範囲が伸びてしまう。

またターゲットの上部にリンクなどがあったなら、paddingを指定した要素がその要素にかぶさります。

この場合、リンクが押せないなんて事態になることもあります。

どんな状態かはサンプルページにてワザと重なるように作っていますので、ご参考にしてください。

リンク:サンプルページ

疑似要素を使う方法

次の方法は疑似要素を使った方法です。この方法は先ほどのように要素やその周りに影響がでることがないので、使いやすい方法だと言えます。

#ターゲット要素::before {
    content: "";
    display: inline-block;
    height: 50px;
    margin-top: -50px;
    vertical-align: top;
}

疑似要素に高さをもたせ、それでズレを解消させています。

どんな要素にも使え、見出しのデザインでpaddingを使っているので変えたくない時にも使えます。

ただし、ちょうど文書の折り返部分になったりすると、疑似要素の後ろで折り返す場合があります。

ターゲット要素だけが下の段になるため、変な感じになります。

疑似要素の後ろで折り返した画

回避策としてはwhite-space:nowrapをターゲット要素に指定します。

ただし、この方法を使えば文書の折り返し自体が無くなるので、折り返すほど長い文章には向きません。

またこの方法はFirefoxなど、ブラウザやバージョンの違いによって機能しないこともあります。

この方法も、サンプルページにて挙動の確認ができます。

リンク:サンプルページ

:targetとanimationを使う方法

以前ならここで手詰まりだったのですが、CSS3になって疑似クラス target やアニメーションが導入それました。

これらを使うことで範囲を広げることなく、全てのブラウザでズレを解消することができます。

@-webkit-keyframes modify{
      0% { padding-top: 50px; margin-top: -50px; }
    100% { padding-top: 0; margin-top: 0; }
}
@keyframes  modify{
      0% { padding-top: 50px; margin-top: -50px; }
    100% { padding-top: 0; margin-top: 0; }
}

#ターゲット要素:target {
    -webkit-animation: modify 0.1s;
    animation: modify 0.1s;
}

:targetはターゲットとなるリンク先の要素にスタイル指定できる疑似クラスです。要はページ内リンクで移動した先の要素に、スタイルを指定できるのです。

スタイルが反映されるタイミングはリンクで移動したときです。このときにヘッダー分のズレをanimationで一旦増やし、素早く元に戻すという方法でヘッダ固定時のズレが解消しています。

もちろんリンク先がインライン要素ならばmargin-topは不要です。

@keyframesなど記述量は増えますが、CSSでズレを調整するならこの方法が1番汎用性が利くと思います。

サンプルページにも設置してますので、ご確認ください。

リンク:サンプルページ

締め

CSSにいろいろ機能が増えたため、やろうと思えばCSSでも出来るようです。

今回の記事が、サイト制作の何かの参考になれば幸いです。

あ、後このように要素を大きさを変えたりすると、クリックした時に出る囲み枠(アウトライン)が変に大きくなったりして気になる場合があります。

そんな時は、アウトラインをCSSで消すことができます。

#ターゲット要素 {
    outline: none;
}

また、スマホではリンクをタップするとハイライトとして色がでます。これを消すには次のCSSを指定します。

#ターゲット要素 {
  -webkit-tap-highlight-color: rgba( 0, 0, 0, 0);
}

もちろん値はtransparentでもオッケーです。

以上です。それでは。

スポンサーリンク