web-dev-qa-db-ja.com

固定ページヘッダーがページ内アンカーと重なる

HTMLページにスクロールしないヘッダーがあり、上部が固定されていて、高さが定義されている場合

URLアンカー(#fragment部分)を使用してブラウザをページ内の特定の位置までスクロールさせる方法はありますが、それでもJavaScriptの助けを借りずに固定要素の高さを考慮する必要があります。

http://foo.com/#bar
間違っています(ただし、一般的な動作):正しい:
 + ----------------------------- ---- + + --------------------------------- + 
 | BAR //////////////////////ヘッダー| | //////////////////////// header | 
 + ------------------ --------------- + + --------------------------------- + 
 |これがテキストの残りの部分です。 | BAR | 
 | ... | | | 
 | ... | |これが本文の残りの部分です| 
 | ... | | ... | 
 + --------------------------------- + + ----- ---------------------------- + 
276
Tomalak

私は同じ問題を抱えていました。 topbarの高さをpadding-top値としてアンカー要素にクラスを追加することでそれを解決しました。

<h1><a class="anchor" name="barlink">Bar</a></h1>

それから単純なcss:

.anchor { padding-top: 90px; }
128
MutttenXd

新しいクラスを設定できない、または設定したくない場合は、CSSの ::before 擬似クラスに固定高の :target 擬似要素を追加します。

:target::before {
  content: "";
  display: block;
  height: 60px; /* fixed header height*/
  margin: -60px 0 0; /* negative fixed header height */
}

あるいは、jQueryを使って:targetを基準にしてページをスクロールします。

var offset = $(':target').offset();
var scrollto = offset.top - 60; // minus fixed header height
$('html, body').animate({scrollTop:scrollto}, 0);
204
Adrian Garner

私はこのアプローチを使います:

/* add class="jumptarget" to all targets. */

.jumptarget::before {
  content:"";
  display:block;
  height:50px; /* fixed header height*/
  margin:-50px 0 0; /* negative fixed header height */
}

各ターゲットの前に目に見えない要素を追加します。 IE 8以降で動作します。

これがより多くの解決策です: http://nicolasgallagher.com/jump-links-and-viewport-positioning/

114
Jeremias Erbs

公式ブートストラップ採用回答:

*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; // Set the Appropriate Height
  height: 75px; // Set the Appropriate Height
  visibility: hidden; 
}

クレジット

マージ

33
blnc

私がこの問題に対処するために見つけた最良の方法は、(65pxをあなたの固定要素の高さに置き換える):

div:target {
  padding-top: 65px; 
  margin-top: -65px;
}

target セレクタを使いたくない場合は、次のようにすることもできます。

.my-target {
    padding-top: 65px;
    margin-top: -65px;
}

注意:この例は、ターゲット要素の背景色が親と異なる場合は機能しません。例えば:

<div style="background-color:red;height:100px;"></div>
<div class="my-target" style="background-color:green;height:100px;"></div>

この場合、my-target要素の緑色は65pxの親の赤色要素を上書きします。この問題を処理するための純粋なCSSソリューションは見つかりませんでしたが、背景色が他にない場合は、このソリューションが最適です。

25
Roy Shoa

提案されたソリューションの一部は、フラグメントリンク(=ハッシュリンク)同じページ内(下にスクロールするメニューリンクなど)で機能しますが、現在は機能していません。 Chromeは、他のページからのフラグメントリンクを使用する場合

そのため、www.mydomain.com/page.html#fooを最初から呼び出すと、NOT現在のChromeのターゲットが指定されたCSSソリューションのいずれかでオフセットされますまたはJSソリューション。

また、問題の詳細を説明する jQueryバグレポート もあります。

ソリューション

これまでにChromeで実際に機能する唯一のオプションは、onDomReadyではなく遅延のあるJavaScriptです。

// set timeout onDomReady
$(function() {
    setTimeout(delayedFragmentTargetOffset, 500);
});

// add scroll offset to fragment target (if there is one)
function delayedFragmentTargetOffset(){
    var offset = $(':target').offset();
    if(offset){
        var scrollto = offset.top - 95; // minus fixed header height
        $('html, body').animate({scrollTop:scrollto}, 0);
    }
}

概要

JS遅延ソリューションがなければ、Firefox、IE、Safariではおそらく動作しますが、Chromeでは動作しません。

15
Jpsy

Chrome/Safari/Firefoxの場合、display: blockを追加し、負の余白を使ってオフセットを補正することができます。

a[name] {
    display: block;
    padding-top: 90px;
    margin-top: -90px;
}

例を参照してください http://codepen.io/swed/pen/RrZBJo

8
MrSwed

あなたはjQueryでこれを行うことができます:

var offset = $('.target').offset();
var scrollto = offset.top - 50; // fixed_top_bar_height = 50px
$('html, body').animate({scrollTop:scrollto}, 0);
6
webvitaly

あなたはこれを試すことができます:

<style>
h1:target { padding-top: 50px; }
</style>

<a href="#bar">Go to bar</a>

<h1 id="bar">Bar</h1>

上部パディング値を実際のヘッダの高さに設定します。これはあなたのヘッダの上部にわずかな余分なギャップを導入するでしょう、しかしそれはユーザがアンカーにジャンプしてそして次に上にスクロールするときにだけ見えるでしょう。私は今自分のサイトのためにその解決策を作り上げたが、それはページの上部に小さな固定バーを示しているだけであり、あまりにも高いものは何もない。

5
ygoe

わたしにはできる:

HTMLリンクからアンカーへ:

<a href="#security">SECURITY</a>

HTMLアンカー:

<a name="security" class="anchor"></a>

CSS:

.anchor::before {
    content: "";
    display: block;
    margin-top: -50px;
    position: absolute;
}
5
avila

私はそれがCSSとHTMLで上で述べた "anchor:before"メソッドを使って簡単に動くようにしました。それはあなたのdivの間に大きなパディングを作らないので、私はそれが最もうまくいくと思います。

.anchor:before {
  content:"";
  display:block;
  height:60px; /* fixed header height*/
  margin:-60px 0 0; /* negative fixed header height */
}

ページの最初のdivにはうまくいかないようですが、最初のdivにパディングを追加することでそれに対処できます。

#anchor-one{padding-top: 60px;}

これが実用的なフィドルです。 http://jsfiddle.net/FRpHE/24/

4
Eric Wood

私は@ Jpsyの答えを使用していますが、パフォーマンス上の理由から、ハッシュがURLに存在する場合にのみタイマーを設定します。

$(function() {
      // Only set the timer if you have a hash
      if(window.location.hash) {
        setTimeout(delayedFragmentTargetOffset, 500);
      }
  });

function delayedFragmentTargetOffset(){
      var offset = $(':target').offset();
      if(offset){
          var scrollto = offset.top - 80; // minus fixed header height
          $('html, body').animate({scrollTop:scrollto}, 0);
          $(':target').highlight();
      }
  };
3
sandre89

私はbothMutttenXdBadabamのCSSソリューションを一緒に使用しなければならないことがわかりました。 1つ目はChromeでは機能せず、2つ目はFirefoxでは機能しませんでした。

a.anchor { 
  padding-top: 90px;
}

a.anchor:before { 
  display: block;
  content: "";
  height: 90px;
  margin-top: -90px;
}

<a class="anchor" name="shipping"></a><h2>Shipping (United States)</h2>
...
3
tshalif

私が一番きれいだと思う方法は次のとおりです。

  #bar::before {
    display: block;
    content: " ";
    margin-top: -150px;
    height: 150px;
    visibility: hidden;
    pointer-events: none;
  }
3

ブックマークされたアンカーはFAQページ内のセクションヘッダーであるため、ここや他の場所での回答の多くには多くの問題がありました。そうだった。だから私は私が投稿しようと思った。

私がやってしまったのは、いくつかの解決策を組み合わせたものでした。

  1. CSS:

    .bookmark {
        margin-top:-120px;
        padding-bottom:120px; 
        display:block;
    }
    

"120px"はあなたの固定ヘッダの高さです(多少のマージンもあります)。

  1. ブックマークリンクのHTML:

    <a href="#01">What is your FAQ question again?</a>
    
  2. ブックマークされたコンテンツのHTML:

    <span class="bookmark" id="01"></span>
    <h3>What is your FAQ question again?</h3>
    <p>Some FAQ text, followed by ...</p>
    <p>... some more FAQ text, etc ...</p>
    

この解決策の良いところは、span要素が隠されているだけでなく、本質的に折りたたまれていてコンテンツが埋められないことです。

このソリューションは、さまざまなリソースからなるSwagから来たものであるため、私はあまり信用できませんが、私の状況では私にとって最適な方法でした。

実際の結果を見ることができます こちら

3
SteveCinq

これは私の純粋主義者の心にはやや厄介な気がしますが、CSSのみの解決策として、:targetセレクターを使ってアクティブなアンカー要素にパディングを追加することができます。

html, body {height:100%; min-height:100%; margin:0;}
body {min-height:200%;}
header {display:inline-block; position:fixed; font-size:1.5em; height:100px; top:0; left:0; right:0; line-height:100px; background:black; text-align:center;}
header a {color:#fff;}
section {padding:30px; margin:20px;}
section:first-of-type, section:target {padding-top:130px;}
<header><a href="#one">#One</a> <a href="#two">#two</a> <a href="#three">#three</a></header>
<section id="one"><h1>One</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="two"><h1>Two</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="three"><h1>Three</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
3
Moob

私はインバウンドリンク、ページ上のリンク、そしてページがヘッダの高さの変化に反応することができるようにそれがJSによって目標とされることができるもののために働く何かを必要としました

HTML

<ul>
  <li><a href="#ft_who">Who?</a></li>
  <li><a href="#ft_what">What?</a></li>
  <li><a href="#ft_when">When?</a></li>
</ul>
...
<h2 id="ft_who" class="fragment-target">Who?</h2> 
...
<a href="#">Can I be clicked?</a>
<h2 id="ft_what" class="fragment-target">What?</h2>
...
<h2 id="ft_when" class="fragment-target">When?</h2> 

CSS

.fragment-target {
    display: block;
    margin-top: -HEADER_HEIGHTpx;
    padding-top: HEADER_HEIGHTpx;
    z-index: -1;
}

z-index: -1はフラグメントターゲットの上の「パディングエリア」内のリンクがクリック可能であることを可能にします、彼の答えで@MuttenXdによってコメントされるように

IE 11、Edge 15以降、Chrome 38以降、FF 52以降、またはSafari 9.1以降にはまだ問題がありません。

2
Arth

JQueryを使った最小限の邪魔にならない方法:

リンク:

<a href="#my-anchor-1" class="anchor-link">Go To Anchor 1</a>

コンテンツ:

<h3 id="my-anchor-1">Here is Anchor 1</a>

スクリプト:

$(".anchor-link").click(function() {
    var headerHeight = 120;
    $('html, body').stop(true, true).animate({
        scrollTop: $(this.hash).offset().top - headerHeight
    }, 750);
    return false;
});

アンカーリンククラスをリンクに割り当てることで、他のリンクの動作(アコーディオンやタブコントロールなど)は影響を受けません。

この質問はjavascriptを必要としませんが、 もう1つのより一般的な質問 この質問のせいで終了してしまい、そこで回答できませんでした。

2

私は上に挙げた答えにうまくいっていなかったし、完璧に機能したこのソリューションを使ってしまいました...

アンカーを設定する場所に空白のスパンを作成します。

<span class="anchor" id="section1"></span>
<div class="section"></div>

そして、次のクラスを適用してください。

.anchor {
  display: block;
  height: 115px;       /* same height as header */
  margin-top: -115px;  /* same height as header */
  visibility: hidden;
}

セクションごとに色分けされた背景がある場合でも、この解決策は機能します。このリンクで解決策を見つけました

2
Matt Underwood

私はいくつかの改行でdivを作成し、それにidを与えました。そして、表示したいコードをその下に置きました。リンクをクリックすると、画像の上のスペースに移動し、ヘッダーが邪魔にならなくなります。

<a href="#image">Image</a>
<div id="image"><br><br></div>
<img src="Image.png">

もちろん、必要に応じて改行数を変更することができます。これは私には完璧に働きました、問題があるかどうかわからない、私はまだHTMLを学んでいます。

1
Anonymous
html {
  scroll-padding-top: 70px; /* height of sticky header */
}

から: https://css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my/

1

:beforeを使用して実装すると、疑似要素が実際に疑似要素の領域内with()のポインターイベントをカバーおよびブロックしていることがわかります。 pointer-events: none:beforeのようなものを使用しても、アンカーで直接使用しても効果はありません。

私たちがやったことは、アンカーの位置を絶対にし、その位置を固定領域のオフセット/高さに調整することでした。

ブロッキングポインターイベントのないオフセットアンカー

.section-marker {

    position: absolute;
    top: -300px;
}

これの価値は、300px以内に収まる可能性のある要素をブロックしていないことです。欠点は、Javascriptから要素の位置を取得するために、そのオフセットを考慮に入れる必要があるため、そこでのロジックを調整する必要があったことです。

1
skabob11

これで、ナビゲーションをクリックしたときに最終的に適切な場所に移動することができました。ナビゲーションクリック用のイベントハンドラを追加しました。それから、あなたはちょうどオフセットで上に動くために "scrollBy"を使うことができます。

var offset = 90;

 $('.navbar li a').click(function(event) {
    event.preventDefault();
    $($(this).attr('href'))[0].scrollIntoView();
    scrollBy(0, -offset);
 });
1
Mile Mijatovic

このスクリプトを使用

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top -140
    }, 1000);
});
1
Aadil Memon

CSS Scroll Snap spec が登場すると、scroll-margin-topプロパティで簡単に可能になります。現在ChromeとOperaで動作しています(2019年4月)。 Safari 11以降もこれをサポートするはずですが、私はSafari 11でそれを実行することができませんでした。

Codepenの例

body {
  padding: 0;
  margin: 0;
}

h1,
p {
  max-width: 40rem;
  margin-left: auto;
  margin-right: auto;
}
h1 {
  scroll-margin-top: 6rem; /* One line solution. :-) */
}
.header {
  position: sticky;
  top: 0;
  background-color: red;
  text-align: center;
  padding: 1rem;
}
.header .scroll {
  display: block;
  color: white;
  margin-bottom: 0.5rem;
}
.header .browsers {
  color: black;
  font-size: 0.8em;
}
<header class="header">
  <a class="scroll" href="#heading">Scroll to heading</a>
  <span class="browsers" >Chrome 69+, Opera 56+ and Safari 11+ only</span>
</header>
<p>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<h1 id="heading">What is Lorem Ipsum?</h1>
<p>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<p>
  

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent pulvinar eleifend dolor, in cursus augue interdum quis. Morbi volutpat pulvinar nisl et condimentum. Quisque elit lacus, egestas non ante sit amet, hendrerit commodo dui. Nunc ac sagittis dolor. Proin iaculis ante non est pharetra, et ullamcorper nisl accumsan. Aenean quis leo vel sapien eleifend aliquam. Pellentesque finibus dui ex, blandit tristique risus vestibulum vitae. Nam a quam ac turpis porta eleifend. Sed at hendrerit risus, ac efficitur ante. Aenean pretium justo feugiat condimentum consectetur. Etiam mattis urna id porta hendrerit.
</p>
<p>
Mauris venenatis quam sed egestas auctor. Fusce lacus eros, condimentum nec quam vel, malesuada gravida libero. Praesent vel sollicitudin justo. Donec mattis nisl id mauris scelerisque, quis placerat lectus scelerisque. Ut id justo a magna mattis luctus. Suspendisse massa est, pretium vel suscipit sit amet, iaculis at mi. Aenean vulputate ipsum non consectetur sodales. Proin aliquet erat nec mi eleifend, eu dapibus enim ultrices. Sed fringilla tortor ac rhoncus consectetur. Aliquam aliquam orci ultrices tortor bibendum facilisis.
</p>
<p>
Donec ultrices diam quam, non tincidunt purus scelerisque aliquam. Nam pretium interdum lacinia. Donec sit amet diam odio. Donec eleifend nibh ut arcu dictum, in vulputate magna malesuada. Nam id dignissim tortor. Suspendisse commodo, nunc sit amet blandit laoreet, turpis nibh rhoncus mi, et finibus nisi diam sed erat. Vivamus diam arcu, placerat in ultrices eu, porta ut tellus. Aliquam vel nisi nisi.
</p>
<p>
Integer ornare finibus sem, eget vulputate lacus ultrices ac. Vivamus aliquam arcu sit amet urna facilisis consectetur. Sed molestie dolor et tortor elementum, nec bibendum tortor cursus. Nulla ipsum nulla, luctus nec fringilla id, sagittis et sem. Etiam at dolor in libero pharetra consequat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse quis turpis non diam mattis varius. Praesent at gravida mi. Etiam suscipit blandit dolor, nec convallis lectus mattis vitae. Mauris placerat erat ipsum, vitae interdum mauris consequat quis. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<p>
Nunc efficitur scelerisque elit. Integer ac massa ipsum. Cras volutpat nulla purus, quis molestie dolor iaculis eget. Maecenas ut ex nulla. Pellentesque sem augue, ornare ut arcu eu, porttitor consectetur orci. Aenean iaculis blandit quam, in efficitur justo sodales auctor. Vivamus dignissim pellentesque risus eget consequat. Pellentesque sit amet nisi in urna convallis egestas vitae nec mauris. 
</p>
1
dakur

これは、IEで機能する完全なjqueryソリューションです。

ナビゲーションバーの要素が次のようになっているとします。

<ul>
    <li><a class="navigation" href="/#contact-us">Contact us</a></li>
    <li><a class="navigation" href="/#about-us">About us</a></li>
</ul>

あなたはスクロールを相殺するために次のjqueryスニペットを使うことができます:

$(function() {
    $("a.navigation").click(function(event) {
        event.preventDefault();
        offSetScroll($(this));
    });
    offSetScrollFromLocation(window.location.href.toLowerCase());
});

function offSetScroll(anchor) {
    var href = anchor.attr("href");
    offSetScrollFromLocation(href);
}

function offSetScrollFromLocation(href) {
    //Change this according to the height of the navigation bar
    var fromTop = 250;
    if(href.indexOf("#")<=0)
        return;
    var hash=href.substring(href.indexOf("#"));
    var targetOffset = $(hash).offset().top-fromTop;
    $('html, body').animate({scrollTop: targetOffset}, 400, function(e) {

    });
}
1
Thunder
<div style="position:relative; top:-45px;">
    <a name="fragment"> </a>
</div>

このコードはうまくいくはずです。あなたのヘッダーバーの高さのために45pxを交換しなさい。

編集:jQueryを使用することがオプションであれば、私はまたオフセット値を設定してjQuery.localScrollを使用することに成功しています。 offsetオプションは、jQuery.localScrollの基礎となるjQuery.scrollToの一部です。デモはこちらから入手できます。 http://demos.flesler.com/jquery/scrollTo/ (2番目のウィンドウ、 'offset'の下)

1
fourk

それが動作するように "paddingtop"を持つクラスを追加します。

<h1><a class="paddingtop">Bar</a></h1>

そしてCSSのためにあなたが持っている:

.paddingtop { 
   padding-top: 90px; 
}
0
MAESTRO_DE
// handle hashes when page loads
// <http://stackoverflow.com/a/29853395>
function adjustAnchor() {
  const $anchor = $(':target');
  const fixedElementHeight = $('.navbar-fixed-top').outerHeight();
  if ($anchor.length > 0)
    window.scrollTo(0, $anchor.offset().top - fixedElementHeight);
}
$(window).on('hashchange load', adjustAnchor);
$('body').on('click', "a[href^='#']", function (ev) {
  if (window.location.hash === $(this).attr('href')) {
    ev.preventDefault();
    adjustAnchor();
  }
});
0
niftylettuce

非常に単純なCSSのみの答えはこれをあなたのスタイルシートの一番上に置くことです:

a{padding-top: 90px;}
a:link{padding-top: unset;}

最初のスタイルはすべてのアンカータグを規制し、2番目のスタイルはハイパーリンクでタグをアンカーします。

注:これは現在FirefoxとEdgeでは機能しますが、Chromeでは機能しません。

0
D. Stewart

私はこの方法を使用します。なぜなら、何らかの理由で、提案された他の解決策のどれも実際に私のために働かなかったからです。私は試したことを約束します。

section {
   position: relative;
   border-top: 52px solid transparent; /* navbar height +2 */
   margin: -30px 0 0;
   -webkit-background-clip: padding-box;
   -moz-background-clip: padding;
   background-clip: padding-box;
}

section:before {
   content: "";
   position: absolute;
   top: -2px;
   left: 0;
   right: 0;
   border-top: 2px solid transparent;
}

必要に応じて、セクションをクラスに置き換えます。

source: ジャンプリンクとビューポートポジショニング

  • Firefox 45とChrome 52でテスト済み。
  • ブートストラップバージョン:3.3.7

私を信じていない人のために私は親切にその中の解決策とjsfiddleを用意しました: SOLUTION

0
scavenger

CSSのトリックは回避策になります。すべてのシナリオで機能する適切なソリューションは、jQueryを使用して実装できます。

https://codepen.io/pikeshmn/pen/mMxEdZ を参照してください。

アプローチ:document.getElementById( 'header')。offsetHeightを使用して、固定ナビゲーションの高さを取得します。そしてスクロールをこの値にオフセットします。

var jump=function(e){  

e.preventDefault();                        //prevent "hard" jump
  var target = $(this).attr("href");       //get the target

      //perform animated scrolling
      $('html,body').animate(
        {
          scrollTop: $(target).offset().top - document.getElementById('header').offsetHeight - 5  //get top-position of target-element and set it as scroll target
        },1000,function()                  //scrolldelay: 1 seconds
        {
          location.hash = target;          //attach the hash (#jumptarget) to the pageurl
        });
      }

  $(document).ready(function()
  {
    $('a[href*="#"]').bind("click", jump); //get all hrefs
    return false;
  });

P:

  • ヘッダーとターゲットの間に5ピクセルの違いがあります。
  • スクロール効果は硬くはなく、むしろ滑らかです。スムーズスクロール
0
Pikesh Prasoon