【问题标题】:How does the "position: sticky;" property work?\"position: sticky;\" 属性是如何工作的?
【发布时间】:2023-02-01 20:07:39
【问题描述】:

一旦用户滚动页面,我想让导航栏粘在视口的顶部,但它不起作用,我不知道为什么。如果你能帮忙,这是我的 HTML 和 CSS 代码:

.container {
  min-height: 300vh;
}
.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;
}
<main class="container">
  <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>
</main>

【问题讨论】:

  • position:sticky 需要一个坐标来告诉粘贴在哪里
  • 您还必须小心父元素。 position: sticky can stop working if it's inside a flexbox unless you're careful 如果在它和它在里面滚动的任何东西之间有一个 overflow: hiddenoverflow: auto 也会失败(身体根或最近的祖先溢出:滚动)
  • @ user56reinstatemonica8 天哪,非常感谢kkkyou 告诉我overflow: hiddenoverflow: auto!几天来我一直在挠头试图让这个废话工作
  • 我写了一篇关于粘性定位的文章,如果你有兴趣,请查看这里:dioxmio.medium.com/sticky-done-the-right-way-880af0122a71
  • @user56reinstatemonica8 谢谢,对我来说它失败了,因为我在 flexbox 中使用了它。

标签: html css position css-position sticky


【解决方案1】:

检查祖先元素是否设置了溢出(例如overflow:hidden);尝试切换它。您可能需要检查比预期更高的 DOM 树 =)。

这可能会影响后代元素上的 position:sticky

【讨论】:

  • 这是正确的答案。但是,可能很难找到导致问题的父元素。我写了一个 jquery 脚本来帮助识别父母的溢出属性,它发现了问题(只需在您的控制台中运行它)。因为脚本只有几行,所以我添加了一个包含以下脚本的答案。
  • 我错过了你的“s”“父元素”
  • 我也错过了“s”:( 这就是问题所在。在很多地方,人们写道你应该只检查父母而不是所有父母。我通过检查在 Web 控制台中调用 $(stickyElement).parents().css("overflow", "visible") 是否有帮助发现了我的问题,它确实如此。然后我找到了导致问题的overflow:hidden风格的远方父母。我希望我能更仔细地阅读这个答案。
  • 如果您需要检查 overflow:hidden,您可以在浏览器控制台中运行此脚本来检查给定元素的所有父母/祖先:gist.github.com/brandonjp/478cf6e32d90ab9cb2cd8cbb0799c7a7
  • @BenjaminIntal 不是我的情况,我有这个 overflow-x: 隐藏在身体标签,这就是它阻止它正常工作的原因。
【解决方案2】:

粘性定位是相对定位和固定定位的混合体。该元素被视为相对定位,直到它超过指定的阈值,此时它被视为固定定位。
...
您必须至少指定一个阈值toprightbottomleft使粘性定位按预期运行。否则的话,相对定位就分不清了。 [source: 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>

【讨论】:

  • 一般来说,这个答案不足以粘性工作,parent 也不应该有 overflow 属性。
  • 感谢您的评论。我同意你的看法,对于 OP 以外的其他示例,我的回答可能还不够。其他答案指出了这一点:)
  • 我认为诀窍是位置粘性只能应用于属于已知高度的可滚动父级的子级,(flexbox 中的直接子级具有从其他弹性项目计算的已知高度)
  • @ViliusL 感谢您的评论!这就是我在 position: sticky 方面遇到的问题,如果不是你,我不会知道,因为我在任何地方都找不到这些信息。
  • 粘性位置不应有具有溢出属性的父级,并且某些网络浏览器不支持粘性
【解决方案3】:

我有同样的问题,我找到了答案here

如果您的元素没有按预期粘附,首先要检查的是应用于容器的规则。

具体来说,查找在元素的任何父元素上设置的任何溢出属性。你不能使用overflow: hiddenoverflow: scrolloverflow: autoposition: sticky 元素的父元素上。

【讨论】:

  • 这也是正确的答案,但也请参阅我的答案,这有助于轻松识别导致问题的父母。
  • 您不仅应该检查最近的父容器,还应该检查所有父元素.
  • 是的,请查看我的答案以准确地做到这一点并快速检查所有父母
  • 该链接也帮助了我。我的问题是通过“......如果你没有使用溢出并且仍然有问题,值得检查是否在父级上设置了高度......”
  • API 中的 position: sticky 示例实际上是 overflow: auto 容器中的一个元素。 position: sticky 的全部意义不就是住在滚动容器中吗?这个答案让我很困惑。
【解决方案4】:

如果你遇到这个并且你的粘滞不工作 - 尝试将父级设置为:

display: unset

为我工作

【讨论】:

  • 哦!对于父元素的高度有限(例如,导航栏容器或其他东西,而不是整个主体或页面容器),这似乎是一种变通方法 - 便签似乎不喜欢滚动到它们的外部parents(这太荒谬了!)现在每个人都需要幸运才能将 parent 设置为display: unset,这可能并不总是立即可行
  • 似乎也适用于contentsinitial(?) 和inline
  • 有用。但为什么它有效。?
  • display: initial; 也有效。
  • 假设这“有效”,因为 overflow 属性不适用于内联元素(出于某种原因,当设置为 display: initial(或 unset)时,div 元素就是这样)
【解决方案5】:

我遇到的更多事情:

当你的粘性元素是一个组件时(角度等)

  • 如果“粘性”元素本身是一个带有自定义元素选择器的组件,例如名为&lt;app-menu-bar&gt; 的角度组件,您需要将以下内容添加到组件的 css 中:

      :host { display: block; }     // or use flexbox
    

或者

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

Safari on iOS in particular seems to require `display:block` even on the root element `app-root` of an angular application or it won't stick.
  • 如果您正在创建组件并在组件内部定义 css(影子 DOM/封装样式),请确保将 position: sticky 应用于“外部”选择器(例如,devtools 中的 app-menu-bar 应显示粘性位置)而不是顶级div之内组件。使用 Angular,这可以通过组件的 css 中的 :host 选择器来实现。

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

其他

  • 如果粘性元素后面的元素具有纯色背景,则必须添加以下内容以阻止它在下方滑动:

      .sticky-element { z-index: 100; }
      .parent-of-sticky-element { position: relative; }
    
  • 你的粘性元素必须是在你的内容之前如果使用 top在它之后如果使用bottom

  • 在包装器元素上使用 overflow: hidden 时会出现一些问题——通常它会杀死内部的粘性元素。 Better explained in this question

  • 当屏幕键盘可见时,移动浏览器可能会禁用粘性/固定位置的项目。我不确定确切的规则(有人知道吗)但是当键盘可见时,你正在看一个进入窗口的“窗口”,你将无法轻易地将东西粘在实际可见的屏幕顶部。

  • 确保你有:

    position: sticky;

    并不是

    display: sticky;

杂项可用性问题

  • 如果您的设计要求将内容粘贴到移动设备的屏幕底部,请务必谨慎。例如,在 iPhone X 上,它们会显示一条窄线来指示滑动区域(返回主页)——并且该区域内的元素不可点击。因此,如果你坚持某些东西,一定要在 iPhone X 上测试用户是否可以激活它。如果人们无法点击,那么大的“立即购买”按钮就没有用!
  • 如果您在 Facebook 上投放广告,网页将显示在 Facebook 移动应用程序的“webview”控件中。尤其是在显示视频时(您的内容仅从屏幕的下半部分开始)- 他们通常会通过将您的页面放在一个可滚动的视口中来完全弄乱粘性元素,这实际上允许您的粘性元素从页面顶部消失。请务必在实际广告的上下文中进行测试,而不仅仅是在手机浏览器甚至 Facebook 的浏览器中进行测试,因为它们的行为可能各不相同。

【讨论】:

  • @Sergey 我不太清楚display: blockposition: relative 中的哪一个触发了 Safari 中的正确行为 - 似乎只需要 display: block 吗?当然,同时指定两者可能并没有什么坏处
  • 只要display: block就够了
  • 我可能比我自己的任何其他答案都更多地提到了这个答案。这次是溢出:隐藏。
【解决方案6】:

这是 MarsAndBack 和 Miftah Mizwar 回答的延续。

他们的回答是正确的。但是,很难确定问题的祖先。

为了使这非常简单,只需在您的浏览器控制台中运行这个 jQuery 脚本,它就会告诉您每个祖先的 overflow 属性的值。

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

如果祖先没有overflow: visible,请更改其 CSS,以便它有!

此外,如其他地方所述,请确保您的粘性元素在 CSS 中具有以下内容:

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

【讨论】:

  • 这很有帮助。我能够快速识别值为 overflow: invisible 的父元素。
  • 如果你的页面上没有jQuery,你可以在控制台运行这个小sn-p来添加它:(async function() { let response = await fetch('https://code.jquery.com/jquery-3.3.1.min.js'); let script = await response.text(); eval(script); })();
  • 您还可以运行此不需要 JQuery 的 sn-p 来查找非“可见”溢出父级: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 是在开发人员工具中选择的 last element
  • 也可以使用 JavaScript 处理 position: fixed 和适当的属性。问题没有说明需要 JavaScript。
【解决方案7】:

我必须使用以下 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

【讨论】:

  • 显示:flex 成就一切
  • align-items: flex-start; 在父 flex 容器中是我丢失的东西
【解决方案8】:

Sticky 如果您的父母使用显示 flex,则位置将不起作用。当我在一个解决方案中阅读这篇文章时

由于 flex box 元素默认为拉伸,所有元素的高度相同,无法滚动。

因此,如果您在父级上使用display: flex;,那么您必须将其添加到粘性元素align-self: flex-start;,并将高度设置为自动height: auto;

这就是粘性元素类的样子

.stick-ontop {
  position: -webkit-sticky !important; // for safari
  position: sticky !important;
  top: 0;
  align-self: flex-start;
  height: auto;
}

【讨论】:

    【解决方案9】:

    position: sticky 可能无法正常工作的另一个非常常见的情况是它的父级有 display: flexdisplay: grid

    在这种情况下发生的情况是粘性位置起作用,但您看不到它,因为元素已完全拉伸。尝试使用 align-self: baseline 降低它的高度,你会看到效果。

    【讨论】:

      【解决方案10】:

      从其他方向攻击这个Q。

      想象这是一个游戏Find the nearest scrolling ancestor

      <!-- sticky not working -->
      <h1 style="position: sticky; top:0;">Hello World</h1>

      问题:

      • 1/3:粘性节点? &lt;h1&gt;
      • 2/3:祖先? &lt;body&gt;
      • 3/3:&lt;body&gt;滚动? FALSE => “无效”。

      修复:“Sticky 正在工作”(&lt;body&gt; 滚动?TRUE)。

      body{
        min-height: 300vh;
      }
      <!-- sticky working -->
      <h1 style="position: sticky; top: 0;">Hello World</h1>

      考虑到这一点 - 这里有一些“不工作”粘性的“hello world”“著名”场景 :) 大多数情况与这些情况中的一个或多个有关。

      案例 1:缺少“顶部”(易于修复):

      不工作:

      /* not working example */
      aside{
        position: sticky;
        background: lightgray;
      }
      
      main{
        height: 200vh;
      }
      <aside>
        <h2>sticky Aside</h2>
      </aside>
      
      <main>
        <h1>Article</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
        </p>
      </main>

      修复(添加顶部):

      aside{
        position: sticky;
        top: 0;
      }
      
      main{
        height: 200vh;
      }
      <aside>
        <h2>sticky Aside</h2>
      </aside>
      
      <main>
        <h1>Article</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
        </p>
      </main>

      案例 2:粘性节点和溢出(易于修复):

      我通过添加 #extra-wrapper 和溢出设置 auto -或- hidden -或- visible - 但是没有任何剪辑的内容。

      “问题”现在是最近的滚动祖先(#extra-wrapper)“没有”任何滚动(没有滚动条拖动选项==“没有滚动祖先”)。

      不工作:

      /* not working example */
      #overflow-wrapper{
        overflow: scroll;
      }
      
      aside{
        position: sticky;
        background: lightgray;
        top: 0px;
      }
      
      main{
        height: 200vh;
      }
      <div id="overflow-wrapper">
        <aside>
          <h2>sticky Aside</h2>
        </aside>
      
        <main>
          <h1>Article</h1>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
          </p>
        </main>
      </div>

      修复 - 剪辑内容(现在他们是“最近的滚动祖先”)。

      在职的:

      /* not working example */
      #overflow-wrapper{
        overflow: scroll;
        max-height: 60vh; /* clip the content */
      }
      
      aside{
        position: sticky;
        background: lightgray;
        top: 0px;
      }
      
      main{
        height: 200vh;
      }
      <div id="overflow-wrapper">
        <aside>
          <h2>sticky Aside</h2>
        </aside>
      
        <main>
          <h1>Article</h1>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
          </p>
        </main>
      </div>

      案例 3:与“错误/不滚动”节点相关的 Sticky(难以修复)

      同样,Sticky 偏移量相对于其最近的滚动祖先。

      我通过将 #extra-wrapper 添加到 sticky 元素来“销毁”便签。为什么它不起作用?现在#extra-wrapper的高度==高度aside内容(box model)==“没有滚动的祖先”==“无效”。

      不工作:

      /* not working example */
      aside{
        position: sticky;
        top: 0;
        background: lightgray;
      }
      
      main{
        height: 200vh;
      }
      <div id="extra-wrapper">
        <aside>
          <h2>sticky Aside</h2>
        </aside>
      </div>
      
      <main>
        <h1>Article</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
        </p>
      </main>

      这是真正“发生”的事情(我将高度添加到#extra-wrapper):

      #extra-wrapper{
        background: lightgray;
        height: 40vh;
      }
      aside{
        position: sticky;
        top: 0;
      }
      
      main{
        height: 200vh;
      }
      <div id="extra-wrapper">
        <aside>
          <h2>sticky Aside</h2>
        </aside>
      </div>
      
      <main>
        <h1>Article</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
        </p>
      </main>

      使固定: 更改粘性节点:

      #extra-wrapper{
        position: sticky;
        top: 0;
      }
      aside{
      
      }
      
      #layout{
        displ
      }
      main{
      height: 200vh;
      }
      <div id="extra-wrapper">
        <aside>
          <h2>sticky Aside</h2>
        </aside>
      </div>
      
      <main>
        <h1>Article</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
        </p>
      </main>

      案例 4:显示:flexbox/Grid 布局 - 默认情况下是偶数列(很难修复)

      您创建弹性/网格布局并将其中一个列设置为sticky。默认情况下,cols 高度为甚至= “最近的祖先”(包装器)的高度 == Cols 高度 = 无滚动效果。

      不工作:

      #extra-wrapper{
        position: sticky;
        top: 0;
        border: 1px solid red;
      }
      aside{
      
      }
      
      #layout{
        display: flex;
      }
      main{
      height: 200vh;
      }
      <div id="layout">
        <div id="extra-wrapper">
          <aside>
            <h2>sticky Aside</h2>
          </aside>
        </div>
      
        <main>
          <h1>Article</h1>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
          </p>
        </main>
      </div>

      FIX:例如,将粘滞的 max-height 设置为 90vh(现在 cols 高度甚至不是).

      在职的:

      #extra-wrapper{
        position: sticky;
        top: 0;
        border: 1px solid red;
        max-height: 90vh;
      }
      aside{
      
      }
      
      #layout{
        display: flex;
      }
      main{
      height: 200vh;
      }
      <div id="layout">
        <div id="extra-wrapper">
          <aside>
            <h2>sticky Aside</h2>
          </aside>
        </div>
      
        <main>
          <h1>Article</h1>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!
          </p>
        </main>
      </div>

      【讨论】:

      • 被低估的答案。非常详细的解释。解决了案例 4 的问题。非常感谢!
      【解决方案11】:

      看起来要粘贴的导航栏不应该在任何 div 或包含其他内容的部分内。在我将导航栏从导航栏与另一个顶部栏共享的 div 中取出之前,没有任何解决方案对我有用。我以前将顶部栏和导航栏包裹在一个公共的 div 中。

      【讨论】:

      • 谢谢,这就是我要找的!对我来说,没有父母有溢出,也没有任何身高问题。也很高兴在接受的答案中看到此信息。
      • 我刚刚通过实验发现粘性不会滚动到其父元素之外。它有多少其他兄弟姐妹并不重要,但它的父级显然不能成为导航栏容器,而必须是页面/内容容器级别的东西:(这太荒谬了
      • 但是罗!如果可以的话,如果你把limiting parent设置为display: unset,这个限制就解除了!参见stackoverflow.com/a/60560997/2902367 似乎也适用于contentsinitial(?) 和inline
      • 这是一篇有用的文章,更详细地解释了这种行为 - medium.com/@elad/…
      【解决方案12】:

      我知道这似乎已经得到回答,但我遇到了一个具体案例,我觉得大多数答案都没有抓住要点。

      overflow:hidden 的回答涵盖了 90% 的情况。这或多或少是“粘性导航”场景。

      但是粘性行为最好在容器的高度内使用。想想您网站右栏中的时事通讯表格,它会随着页面向下滚动。 如果您的粘性元素是容器的唯一子元素,则容器的大小完全相同,并且没有滚动空间。

      您的容器需要是您希望元素在其中滚动的高度。在我的“右栏”场景中,哪个是左栏的高度。 实现此目的的最佳方法是在列上使用display:table-cell。如果你不能,并且像我一样被困在 float:right 中,你将不得不猜测左列高度,然后用 Javascript 计算它。

      【讨论】:

      • “如果您的粘性元素是容器的唯一子元素,则容器大小完全相同,没有滚动空间。”金子!!!谢谢!
      • 是的!我花了一段时间才弄清楚这个。一开始我觉得这是一个荒谬的限制,但我想至少应该有选项为了那个原因。我更喜欢 sticky-limit: parentsticky-limit: bodysticky-limit: nth-parent(3)... 无论如何:如果可以,您可以通过将限制父级设置为 display: unset 来解除此限制,如 stackoverflow.com/a/60560997/2902367 中所述。似乎也适用于contentsinitial(?) 和inline
      【解决方案13】:

      1.如果元素的任何父元素上的溢出设置为隐藏、滚动或自动,位置粘性很可能不起作用。

      2.如果任何父元素设置了高度,Position sticky 可能无法正常工作。

      【讨论】:

      • 问题是“它是如何工作的”而不是“它是如何不工作的”:)请添加一些解决方案或将它们排除在外。您还可以将 cmets 添加到问题中,而不是添加不是答案的“答案”。
      • 我发现在这种情况下,“它是如何不起作用的”问题更合理,因为“它是如何起作用的”非常简单,在大多数情况下你需要找出问题所在,因此这个问题
      【解决方案14】:

      对我来说并不明显的有趣时刻:至少在 Chrome 70 中 position: sticky 不适用,如果你使用 DevTools 设置它。

      【讨论】:

      • 您是否有这方面的资源或有关如何解决此问题的任何其他信息?
      • 也很好奇这是否可以以某种方式备份
      【解决方案15】:

      我知道这是一个旧帖子。但是如果有像我这样的人最近才开始弄乱 position: sticky 这可能会有用。

      在我的例子中,我使用 position: sticky 作为网格项。它不工作,问题是 overflow-x: hidden on the html element。一旦我删除该属性,它就可以正常工作。将 overflow-x: 隐藏在 body 元素上似乎可行,但还不知道为什么。

      【讨论】:

        【解决方案16】:

        从我的评论:

        position:sticky需要一个坐标来告诉在哪里坚持

        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>

        有 polyfill 可用于 FF 和 Chrome 以外的其他浏览器。这是一个实验性的规则,可以通过浏览器随时执行或不执行。 Chrome 几年前添加了它,然后又删除了它,它似乎又回来了……但是多长时间了?

        最接近的是 position:relative + coordinates updated while scrolling once reached the sticky point,如果你想把它变成一个 javascript 脚本

        【讨论】:

          【解决方案17】:

          我知道为时已晚。但我找到了解决办法即使您在父元素中使用 overflow 或 display:flex,sticky 也会起作用.

          脚步:

          1. 为要设置粘性的元素创建一个父元素(确保创建的元素是相对于 body 或全宽和全高父元素)。

          2. 将以下样式添加到父元素:

            { 位置:绝对; 高度:100vmax; }

          3. 对于粘性元素,确保添加高于页面中所有元素的 z-index。

            就是这样!现在它必须工作了。问候

          【讨论】:

            【解决方案18】:

            这里有两个答案:

            1. body 标签中删除 overflow 属性

            2. height: 100% 设置为 body 以解决 overflow-y: auto 的问题

              min-height: 100% 不工作而不是 height: 100%

            【讨论】:

              【解决方案19】:

              我相信 this article 说了很多关于 sticky 是如何工作的

              CSS Position Sticky 是如何工作的! CSS位置粘性有两个主要部分,粘性物品和粘性容器.

              粘性物品— 是我们用position: sticky styles 定义的元素。当视口位置时元素会浮动 匹配位置定义,例如:top: 0px

              粘性容器— 是包装粘性项目的 HTML 元素。这是粘性物品可以漂浮的最大区域。

              当你用 position: sticky 定义一个元素时,你会自动 将父元素定义为粘性容器!

              【讨论】:

                【解决方案20】:

                粘性元素的真实行为是:

                • 首先是相对的
                • 然后修复一段时间
                • 最后,它从视图中消失了

                粘性定位的元素被视为相对定位,直到其包含块在其流根(或其滚动的容器)内超过指定阈值(例如将 top 设置为 auto 以外的值),此时它被视为“卡住” " 直到遇到其包含块的对边。

                元素根据文档的正常流定位,然后相对于其最近的滚动祖先和包含块(nearest block-level ancestor)进行偏移,包括表格相关的元素,基于top、right、bottom、离开。偏移量不会影响任何其他元素的位置。

                此值始终会创建一个新的堆叠上下文。请注意,粘性元素“粘附”到其最近的具有“滚动机制”的祖先(当溢出被隐藏、滚动、自动或覆盖时创建),即使该祖先不是最近的实际滚动祖先。

                这个例子将帮助你理解:

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

                【讨论】:

                  【解决方案21】:

                  使用此博客 (https://www.designcise.com/web/tutorial/how-to-fix-issues-with-css-position-sticky-not-working) 中的策略,我为那些无法控制页面中所有组件的人想出了一个选项

                  我正在使用 Angular 并在 ngOnInit 方法中运行此代码以将父母的可见属性更改为可见

                  /**
                   * position: sticky
                   * only works if all parent components are visibile
                   */
                  let parent = document.querySelector('.sticky').parentElement;
                  while (parent) {
                    const hasOverflow = getComputedStyle(parent).overflow;
                    if (hasOverflow !== 'visible') {
                      parent.style.overflow = 'visible';
                      // console.log(hasOverflow, parent);
                    }
                    parent = parent.parentElement;
                  }
                  

                  【讨论】:

                    【解决方案22】:

                    z-index也很重要。有时它会起作用,但您只是看不到它。尝试将其设置为某个非常高的数字以确保万无一失。也不要总是把 top: 0 放在更高的地方,以防它隐藏在某个地方(在工具栏下)。

                    【讨论】:

                      【解决方案23】:

                      当心空网格区域!

                      就我而言,我有这样的事情:

                      .cart-areas {
                          grid-template-columns: 2fr 0.2fr 1.5fr;
                          grid-template-areas:
                            'order . summary'
                            'order . .'
                            'order . .';
                      }
                      

                      当用户完成结帐表单时,我希望 summary 网格项目具有粘性。由于那些empty grid items(标有.),它不起作用。

                      解决方案是像这样删除那些空项目:

                      .cart-areas {
                          grid-template-columns: 2fr 0.2fr 1.5fr;
                          grid-template-areas:
                            'order . summary'
                            'order . summary'
                            'order . summary';
                      }
                      

                      【讨论】:

                        【解决方案24】:

                        如果 danday74 的修复不起作用,请检查父元素是否具有高度。

                        就我而言,我有两个孩子,一个向左漂浮,一个向右漂浮。 我想让右边的浮动对象变得粘稠,但必须在父对象的末尾添加一个&lt;div style="clear: both;"&gt;&lt;/div&gt;,以给它高度。

                        【讨论】:

                        • 不确定为什么这会被某人否决,但这正是我的情况:我将 float:left 添加到父元素(没有浮动,它的高度为 0)并且 position:sticky 有效。
                        【解决方案25】:

                        我使用了 JS 解决方案。它适用于 Firefox 和 Chrome。有任何问题,请告诉我。

                        网页格式

                        <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()
                            }
                        }
                        

                        【讨论】:

                          【解决方案26】:

                          这就是让我绊倒的原因...我的粘性 div 在另一个 div 中,因此父 div 在粘性 div 之后需要一些额外的内容,以使父 div“足够高”以使粘性 div 能够“滑过”其他内容你向下滚动。

                          所以就我而言,在粘性 div 之后,我必须添加:

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

                          (我的应用程序有两个并排的 div,左边是一个“高”图像,右边是一个简短的数据输入表单,我希望数据输入表单在您向下滚动时浮动在图像旁边,所以表格总是在屏幕上。直到我添加上面的“额外内容”,它才会起作用,所以粘性 div 有东西可以“滑过”

                          【讨论】:

                            【解决方案27】:

                            我有同样的问题。对我来说,问题是 display: 'none' 在大屏幕上(媒体查询)和 display: 'initial' 在智能手机上。如果我删除了显示 css 属性并在桌面上添加了不透明度和指针事件,则一切正常。

                            【讨论】:

                              【解决方案28】:

                              尽管阅读了整个页面并尝试了除厨房水槽之外的所有内容,但这在我的移动设备上根本不起作用。根本没有粘性动作——这是我唯一需要它工作的地方。我已经排除了任何会阻止此屏幕宽度运行的特殊指定或覆盖。清除我的移动格式代码作为测试,没有看到任何变化。在我的笔记本电脑上的 Chrome 浏览器上完美运行,但在我的新 S10 上的 chrome 浏览器上完全不运行。

                              【讨论】:

                                【解决方案29】:

                                确实需要删除 overflow 或将其设置为 initial 才能使 position: sticky 作用于子元素。我在我的 Angular 应用程序中使用了 Material Design,然后发现一些材料组件更改了 overflow 值。我的方案的修复是

                                mat-sidenav-container, mat-sidenav-content {
                                  overflow: initial;
                                }
                                

                                【讨论】:

                                  【解决方案30】:

                                  在处理 position sticky 时,最常见的错误之一是:

                                  1. 浏览器不支持
                                  2. 不包括任何上右下左属性。请记住,如果您没有提供足够的信息,浏览器将不知道如何正确处理它。如果没有它,它将只是 statically 定位。

                                    我已经在这个article 上写过关于这个和更多内部信息的文章。只是提供一个参考,所以我不会重复太多。

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2022-11-16
                                    • 2023-01-20
                                    • 2014-05-25
                                    • 1970-01-01
                                    • 2011-12-19
                                    • 1970-01-01
                                    • 2012-03-28
                                    相关资源
                                    最近更新 更多