「位置:粘着性がある」CSSとHTMLが機能しない


177

スクロールした後、ナビゲーションバーを一番上に固定したいのですが、うまくいきません。理由がわかりません。あなたが助けてくれるなら、これが私のHTMLとCSSコードです:

.nav-selections {
  text-transform: uppercase;
  letter-spacing: 5px;
  font: 18px "lato",sans-serif;
  display: inline-block;
  text-decoration: none;
  color: white;
  padding: 18px;
  float: right;
  margin-left: 50px;
  transition: 1.5s;
}

.nav-selections:hover{
  transition: 1.5s;
  color: black;
}

ul {
  background-color: #B79b58;
  overflow: auto;
}

li {
  list-style-type: none;
}
<nav style="position: sticky; position: -webkit-sticky;">
  <ul align="left">
    <li><a href="#/contact" class="nav-selections" style="margin-right:35px;">Contact</a></li>
    <li><a href="#/about" class="nav-selections">About</a></li>
    <li><a href="#/products" class="nav-selections">Products</a></li>
    <li><a href="#" class="nav-selections">Home</a></li>
  </ul>
</nav>


10
position:stickyは貼り付ける場所を伝えるためにcoordonateを必要としています
G-Cyrillus

36
また、親要素にも注意する必要があります。position: stickyあなたが注意している場合を除き、それはフレキシボックスの内側にいた場合に動作を停止することができ、そこにいた場合も失敗するoverflow: hiddenか、overflow: autoそれと何の間でそれが内部(体内のルートまたは最も近い祖先オーバーフロー付き:スクロール)スクロール
user56reinstatemonica8を

2
@ user56reinstatemonica8 OMG thankkkkyouについて私に告げるためにずっとそうoverflow: hiddenoverflow: auto!このがらくたを機能させるために何日も頭を
悩ませ

回答:


206

固定配置は、相対配置と固定配置のハイブリッドです。要素は、指定されたしきい値を超えるまで相対配置として扱われ、その時点で、固定配置として扱われます。
...
あなたは、の少なくとも一つでしきい値を指定する必要がありtoprightbottom、またはleft期待通りに動作するように粘着性の位置決めのために。それ以外の場合は、相対配置と区別できません。[ ソース:MDN ]

したがって、例では、topプロパティを使用して、最後に固定する位置を定義する必要があります。

html, body {
  height: 200%;
}

nav {
  position: sticky;
  position: -webkit-sticky;
  top: 0; /* required */
}

.nav-selections {
  text-transform: uppercase;
  letter-spacing: 5px;
  font: 18px "lato", sans-serif;
  display: inline-block;
  text-decoration: none;
  color: white;
  padding: 18px;
  float: right;
  margin-left: 50px;
  transition: 1.5s;
}

.nav-selections:hover {
  transition: 1.5s;
  color: black;
}

ul {
  background-color: #B79b58;
  overflow: auto;
}

li {
  list-style-type: none;
}
<nav>
  <ul align="left">
    <li><a href="#/contact" class="nav-selections" style="margin-right:35px;">Contact</a></li>
    <li><a href="#/about" class="nav-selections">About</a></li>
    <li><a href="#/products" class="nav-selections">Products</a></li>
    <li><a href="#" class="nav-selections">Home</a></li>
  </ul>
</nav>


124
一般的に、この答えは、動作するように粘り強くするには十分ではありません。親もオーバーフロープロパティを持つべきではありません。
ViliusL 2018

コメントありがとうございます。OP以外の例では、私の答えでは不十分な場合があることに同意します。他の回答はこれを指摘しています:)
Marvin

トリックは、位置の固定が既知の高さのスクロール可能な親に属する子にのみ適用できることだと思います(フレックスボックス内の直接の子は、他のflex-itemから計算される既知の高さを持っています)
code4j

@ViliusLコメントありがとうございます!それは、私がポジションで抱えていた問題でした。粘着性があるので、この情報がどこにも見つからなかったので、あなたにとってはそうではなかったでしょう。
Piotr Szlagura

スティッキー位置には、オーバーフロープロパティを持つ親があってはなりません。また、スティッキーは一部のWebブラウザーでサポートされていません
Rohan Shenoy

331

祖先要素にオーバーフローが設定されているかどうかを確認しoverflow:hiddenます(例:); それを切り替えてみてください。期待よりもDOMツリーを上に移動しなければならない場合があります=)。

これはposition:sticky、子孫要素に影響を与える可能性があります。


36
私はあなたに複数回賛成したいと思います!これは私が認めたいと思うよりも頻繁に私を噛みました。
Alexander Varwijk

2
これが正解です。ただし、問題を引き起こしている親要素を見つけるのは難しい場合があります。問題を特定した親のオーバーフロープロパティを特定するのに役立つjqueryスクリプトを作成しました(コンソールで実行するだけです)。スクリプトは数行なので、以下のスクリプトを含む回答を追加しました。
danday74、18年

5
私はあなたの「親要素」
che-azeh 2018

5
私も "s"を逃しました:(そしてそれが問題でした。多くの場所で、すべての親ではなく親だけをチェックする必要があると人々は書いています$(stickyElement).parents().css("overflow", "visible")。Webコンソールでの呼び出しが役立つかどうかを確認することで私の問題を見つけました。overflow:hidden問題を引き起こしたスタイルを持つ遠くの親。この回答をもっと注意深く読んでほしい
Mariusz Pawelski

2
のチェックが必要な場合はoverflow:hidden、ブラウザコンソールでこのスクリプトを実行して、特定の要素のすべての親/祖先をチェックできます: gist.github.com/brandonjp/478cf6e32d90ab9cb2cd8cbb0799c7a7
brandonjp

100

私は同じ問題を抱えており、私はここで答えを見つけました。

要素が期待どおりに固定されていない場合、最初に確認することは、コンテナに適用されているルールです。

具体的には、親に設定されているオーバーフロープロパティを探します。:、または要素の親には使用できませんoverflow: hiddenoverflow: scrolloverflow: autoposition: sticky


これも正しい答えですが、問題の原因となっている親を簡単に特定するのに役立つ私の答えも参照してください。
danday74

10
あなたは、最も近い親コンテナが、すべての親要素だけではなく、チェックする必要があります
Mariusz Pawelski 2018

はい、正確にそれを行うために私の答えを見て、すべての親を非常に迅速にチェックしてください
danday74

1
リンクは私にも役立ちました。「あなたがオーバーフローを使用して、まだ高さを親に設定されている場合、それはチェックの価値がある問題を抱えていない場合は... ...」私の問題はで解決した
xenetics

ライフセーバー、問題に対する非常に単純な説明ですが、この好奇心が強い人への回避
Rahul Singh

32

私が遭遇したいくつかのこと:

スティッキー要素がコンポーネント(角度など)の場合

  • 「スティッキー」要素自体が、名前付きの角度付きコンポーネントなどのカスタム要素セレクタを持つコンポーネントである<app-menu-bar>場合は、コンポーネントのcssに以下を追加する必要があります。

    :host { display: block; }   

    または

    app-menu-bar  { display: block; }   // (in the containing component's css)

    特にiOS上のSafari は、角度のあるアプリケーションのdisplay:blockルート要素app-rootでさえも必要とするようです。

  • コンポーネントを作成し、コンポーネント(シャドウDOM /カプセル化されたスタイル)内のCSSを定義している場合は、確認してposition: sticky「外側」セレクタに適用されている(例えば。app-menu-barデベロッパーツールで粘着性の位置を示すべきである)とないトップレベルdiv コンポーネント。Angularでは:host、コンポーネントのCSS のセレクターでこれを実現できます。

    :host
    {
        position: sticky;
        display: block;   // this is the same as shown above
        top: 0;
        background: red;    
    }
    

その他の

  • sticky要素に続く要素の背景が塗りつぶされている場合は、次の要素を追加して、要素が下にスライドしないようにする必要があります。

    .sticky-element { z-index: 100; }
    .parent-of-sticky-element { position: relative; }
    
  • スティッキ要素は、使用する場合は最初に(コンテンツの前に)、使用topする場合はその後に置く必要がありますbottom

  • overflow: hiddenwrapper要素を使用すると複雑になります。一般に、内部のsticky要素が削除されます。この質問でよりよく説明されています

  • モバイルブラウザーは、オンスクリーンキーボードが表示されているときに、固定/固定されたアイテムを無効にする場合があります。正確なルールはわかりません(誰もが知っていることです)が、キーボードが表示されているときは、ウィンドウへの「ウィンドウ」のようなものを見ているので、物事を画面の実際に見える上部。

  • 次のことを確認してください。

    position: sticky;

    ではなく

    display: sticky;

その他のユーザビリティの懸念

  • モバイルデバイスで画面の下部に物を貼り付ける必要がある場合は注意が必要です。たとえばiPhone Xでは、スワイプ領域(ホームページに戻るため)を示す細い線が表示され、この領域内の要素はクリックできません。したがって、何かを貼り付ける場合は、ユーザーがそれをアクティブ化できることをiPhone Xで必ずテストしてください。大きな「今すぐ購入」ボタンは、人々がクリックできないのではダメです!
  • Facebookに広告を掲載している場合、WebページはFacebookのモバイルアプリ内の「webview」コントロールに表示されます。特に、ビデオを表示する場合(コンテンツが画面の下半分のみで始まる場合)は、ページをスクロール可能なビューポート内に配置することにより、スティッキエレメントを完全にめちゃくちゃにすることがよくあります。電話のブラウザだけでなく、すべて動作が異なるFacebookのブラウザだけでなく、実際の広告のコンテキストでテストしてください。

@Sergey私はSafariでどちらが正しい動作display: blockposition: relativeするのか完全に明確ではありません- display: block必要なだけのように見えましたか?もちろん、両方を指定しても問題ないでしょう
Simon_Weaver

2
ちょうどdisplay: block十分だった
セルゲイ

27

これは、MarsAndBackとMiftah Mizwarからの回答の続きです。

彼らの答えは正しいです。ただし、問題の祖先を特定することは困難です。

これを非常に簡単にするには、ブラウザコンソールでこのjQueryスクリプトを実行するだけで、すべての祖先のオーバーフロープロパティの値がわかります。

$('.your-sticky-element').parents().filter(function() {
    console.log($(this));
    console.log($(this).css('overflow'));
    return $(this).css('overflow') === 'hidden';
});

祖先がoverflow: visibleCSS を変更しない場合、CSS は変更されます。

また、他の場所で述べたように、CSSでスティッキー要素にこれが含まれていることを確認してください。

.your-sticky-element {
    position: sticky;
    top: 0;
}

2
それはとても役に立ちました。の値を持つ親要素をすばやく特定できましたoverflow: invisible
デビッドブロワー2018

4
あなたのページにjQueryのを持っていない場合、あなたはそれを追加するために、コンソールでこの小さなスニペットを実行することができます: (async function() { let response = await fetch('https://code.jquery.com/jquery-3.3.1.min.js'); let script = await response.text(); eval(script); })();
magikMaker

8
また、JQueryが「目に見えない」オーバーフローの親を見つける必要がないこのスニペットを実行することもできます。開発者ツールで選択された最後の要素var p = $0.parentElement; while(p != null) { var ov = getComputedStyle(p).overflow; if(ov !== 'visible') console.warn(ov, p); else console.log(ov, p); p = p.parentElement; }どこですか。$0
Mariusz Pawelski、

position: fixedJavaScriptで適切なプロパティを処理することもできます。質問はJavaScriptの必要性を述べていません。
vintproykt

12

次のCSSを使用して機能させる必要がありました。

.parent {
    display: flex;
    justify-content: space-around;
    align-items: flex-start;
    overflow: visible;
}

.sticky {
    position: sticky;
    position: -webkit-sticky;
    top: 0;
}

上記がうまくいかない場合は...

すべての祖先を調べ、これらの要素のどれにもないことを確認しますoverflow: hidden。これを次のように変更する必要がありますoverflow: visible


1
ディスプレイ:flexが
実現-MaciejLisCK

6

これに遭遇してスティッキが機能しない場合-親を次のように設定してみてください:

display: unset

私のために働いた


これです。
mm-93

ああ!これは、親要素の高さが制限されている場合(たとえば、ボディ全体またはページコンテナーではなく、ナビゲーションバーコンテナーなど)の回避策のようです-スティッキーはその外側にスクロールしたくないようです親(これはまったくとんでもないことです!)今、誰もが親をに設定できるほど幸運である必要があります。これdisplay: unsetは常にすぐに実行できるとは限りません
ベンフィリップ

また、で動作するようだcontentsinitialと(?)inline
ベン・フィリップ・

5

私には明白ではなかった面白い瞬間:position: stickyDevToolsを使用して設定した場合、少なくともChrome 70 では適用されません。


これのソース、またはこれを回避する方法に関する他の情報はありますか?
AJMansfield 2018

5

貼り付けられるナビゲーションバーは、他のコンテンツを含むdivまたはセクションの中にあるべきではないようです。navbarが別のトップバーと共有しているdivからnavbarを取り出すまで、どのソリューションも機能しませんでした。以前は、共通のdivでトップバーとnavbarをラップしていました。


ありがとう、これは私が探していたものでした!私にとっては、オーバーフローを持つ親はいなかったし、身長の問題もありませんでした。受け入れられた回答でもこの情報を見るとよいでしょう。
saglamcem

私は実験を通して、スティッキーがその親要素の外にスクロールしないことを知りました。他の兄弟がいくつあるかはそれほど問題ではありませんが、その親はナビゲーションバーコンテナーにすることはできませんが、ページ/コンテンツコンテナーのレベルで何かでなければなりません:(これはばかげています
ベンフィリップ

しかし、Lo!可能であれば、制限する親をに設定するとdisplay: unset、この制限が解除されます。stackoverflow.com/a/60560997/2902367 も参照してくださいcontentsinitial(?)、およびinline
ベンフィリップ

4

私のコメントから:

position:sticky どこに固執するか電話するためにcoordonateが必要です

nav {
  position: sticky;
  top: 0;
}

.nav-selections {
  text-transform: uppercase;
  letter-spacing: 5px;
  font: 18px "lato", sans-serif;
  display: inline-block;
  text-decoration: none;
  color: white;
  padding: 18px;
  float: right;
  margin-left: 50px;
  transition: 1.5s;
}

.nav-selections:hover {
  transition: 1.5s;
  color: black;
}

ul {
  background-color: #B79b58;
  overflow: auto;
}

li {
  list-style-type: none;
}

body {
  height: 200vh;
}
<nav>
  <ul align="left">
    <li><a href="#/contact" class="nav-selections" style="margin-right:35px;">Contact</a></li>
    <li><a href="#/about" class="nav-selections">About</a></li>
    <li><a href="#/products" class="nav-selections">Products</a></li>
    <li><a href="#" class="nav-selections">Home</a></li>
  </ul>
</nav>

FFとChrome以外のブラウザで使用するポリフィルがあります。これは、ブラウザを介していつでも実装できる、または実装できない実験的なルールです。Chromeは数年前にそれを追加してからそれを落としました、それは戻ってきたようです...しかしどれくらいの期間ですか?

最も近いものは、position:relative + coordonatesです。これをスクロールして粘着性のあるポイントに到達すると、これをJavaScriptスクリプトに変換したい場合に更新されます。


4

これは既に回答されているように見えますが、特定のケースに遭遇し、ほとんどの回答がそのポイントを逃しているように感じます。

overflow:hidden答えは、例の90%をカバーしています。それは多かれ少なかれ「粘着性がある」シナリオです。

ただし、スティッキー動作はコンテナの高さ内で使用するのが最適です。ウェブサイトの右の列にある、ページとともにスクロールするニュースレターフォームを考えてみてください。スティッキ要素がコンテナの唯一の子である場合、コンテナはまったく同じサイズであり、スクロールする余地はありません。

コンテナは、要素がスクロールするときに期待する高さである必要があります。私の "右列"シナリオでは、左列の高さです。これを達成する最良の方法はdisplay:table-cell、カラムで使用することです。それができず、float:right私と同じように行き詰まっている場合は、Javascriptで計算するために、左の列の高さを推測する必要があります。


2
「スティッキー要素がコンテナの唯一の子である場合、コンテナはまったく同じサイズであり、スクロールする余地はありません。」ゴールド!!!ありがとうございました!
マークジャクソン

はい!これを理解するのにしばらくかかりました。最初はとんでもない制限だと思いましたが、少なくともそのための選択肢はあるはずです。私は多くのようなものを好むsticky-limit: parentsticky-limit: bodyまたはsticky-limit: nth-parent(3)とにかく...:あなたは、あなたがに制限親を設定することでこの制限を解除することができた場合はdisplay: unset、で述べたようにstackoverflow.com/a/60560997/2902367。また、で動作するようだcontentsinitialと(?)inline
ベン・フィリップ・

3

私はこれが古い記事であることを知っています。しかし、最近私がポジションをいじり始めた人がいる場合は、スティッキーが便利です。

私の場合、位置を使用していました:グリッドアイテムとしてスティッキー。それは機能していなかったし、問題はオーバーフロー-x:html要素に隠されていた。私はそのプロパティを削除するとすぐにうまくいきました。body要素にoverflow-x:hiddenがあると、うまくいくように見えましたが、まだ理由はわかりません。


1

ここで2つの答え:

  1. タグoverflowからプロパティを削除body

  2. に設定height: 100%してbody、問題を修正しますoverflow-y: auto

min-height: 100% 代わりに機能しない height: 100%


1

私はこの記事がどのようにsticky機能するかについて多くを言うと信じています

CSS Position Stickyが実際に機能する方法 CSSポジションスティッキーには、スティッキーアイテムとスティッキーコンテナーの 2つの主要部分があります

スティッキーアイテム  —位置で定義した要素:スティッキースタイル。要素は、ビューポートの位置が位置の定義と一致すると浮動しますtop: 0px。次に例を示します。

スティッキーコンテナー -スティッキーアイテムをラップするHTML要素です。これは、スティッキーアイテムが浮かぶことができる最大の領域です。

position:stickyの要素を定義すると、親要素が自動的にstickyコンテナとして定義されます。


1

スティッキー要素の実際の動作は次のとおりです。

  • まずそれはしばらくの間相対的です
  • その後しばらく修正されます
  • 最後に、それはビューから消えます

粘着的に配置された要素は、その包含ブロックがフロールート(または要素がスクロールするコンテナー)内の指定されたしきい値(トップをauto以外の値に設定するなど)を超えるまで相対的に配置されたと見なされ、その時点で「スタック」として扱われます。 「それを含むブロックの反対側の端に出会うまで。

要素はドキュメントの通常のフローに従って配置され、上、右、下の値に基づいて、テーブルに関連する要素を含む、最も近いスクロール先祖とそれを含むブロック(最も近いブロックレベルの先祖)に対してオフセットされます。そして、左。オフセットは、他の要素の位置には影響しません。

この値は常に新しいスタッキングコンテキストを作成します。先祖が実際に最も近いスクロール先祖でなくても、「スクロールメカニズム」(オーバーフローが非表示、スクロール、自動、また​​はオーバーレイの場合に作成)を持つ最も近い先祖にスティッキー要素が「くっつく」ことに注意してください。

この例は、理解に役立ちます。

code https://codepen.io/darylljann/pen/PpjwPM


0

danday74の修正が機能しない場合は、親要素に高さが設定されていることを確認してください。

私の場合、2人の子供がいて、1人は左に浮き、もう1人は右に浮かんでいます。右に浮いているものをベタベタにしたかったのですが、<div style="clear: both;"></div>高さを与えるために親の最後にaを追加する必要がありました。


誰かがこれに反対票を投じた理由は不明ですが、これはまさに私のケースでした。私float:leftは親要素に追加し(フロートなしで、高さは0でした)、position:sticky機能しました。
aexl

0

JSソリューションを使用しました。FirefoxとChromeで動作します。問題があれば教えてください。

html

<body>
  <header id="header">
    <h1>Extra-Long Page Heading That Wraps</h1>
    <nav id="nav">
      <ul>
        <li><a href="" title="">Home</a></li>
        <li><a href="" title="">Page 2</a></li>
        <li><a href="" title="">Page 3</a></li>
      </ul>
    </nav>
  </header>
  <main>
    <p><!-- ridiculously long content --></p>
  </main>
  <footer>
    <p>FOOTER CONTENT</p>
  </footer>
  <script src="navbar.js" type="text/javascript"></script>
</body>

CSS

nav a {
    background: #aaa;
    font-size: 1.2rem;
    text-decoration: none;
    padding: 10px;
}

nav a:hover {
    background: #bbb;
}

nav li {
    background: #aaa;
    padding: 10px 0;

}

nav ul  {
    background: #aaa;
    list-style-type: none;
    margin: 0;
    padding: 0;

}

@media (min-width: 768px) {

    nav ul {
        display: flex;
    }
}

js

function applyNavbarSticky() {
    let header = document.querySelector('body > header:first-child')
    let navbar = document.querySelector('nav')
    header.style.position = 'sticky'

    function setTop() {
        let headerHeight = header.clientHeight
        let navbarHeight = navbar.clientHeight
        let styleTop = navbarHeight - headerHeight

        header.style.top = `${styleTop}px`
    }

    setTop()

    window.onresize = function () {
        setTop()
    }
}

0

z-indexも非常に重要です。時々動作しますが、表示されません。念のため、非常に大きな値に設定してみてください。また、常に置くのではなくtop: 0、どこか(ツールバーの下)に隠れている場合は、もっと高いものを試してください。


0

これは私をつまずかせていたものです...私の粘着性のあるdivは別のdivの中にありました。下にスクロールします。

したがって、私の場合、sticky divの直後に、以下を追加する必要がありました。

    %div{style:"height:600px;"} 
      &nbsp;

(私のアプリケーションには2つのdivが並んでいます。左側に「背の高い」画像、右側に短いデータ入力フォームがあり、下にスクロールすると、データ入力フォームを画像の横にフロートさせたいのですが、フォームは常に画面上にあります。上記の「追加コンテンツ」を追加するまで機能しないため、スティッキーdivに「スライド」するものがあります


-1

子要素で機能させるためoverflowinitialを削除または設定する必要があるのは真ですposition: sticky。Angularアプリでマテリアルデザインを使用したところ、一部のマテリアルコンポーネントがoverflow値を変更していることがわかりました。私のシナリオの修正は

mat-sidenav-container, mat-sidenav-content {
  overflow: initial;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.