“位置:粘性;”如何?物业工作?

Posted

技术标签:

【中文标题】“位置:粘性;”如何?物业工作?【英文标题】:How does the "position: sticky;" property work? 【发布时间】:2017-09-28 03:48:15 【问题描述】:

一旦用户滚动页面,我想让导航栏粘在视口的顶部,但它不起作用,我不知道为什么。如果你能帮忙,这是我的 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 OMG 感谢kkkyou 告诉我有关overflow: hiddenoverflow: auto 的信息!几天来我一直在摸不着头脑,试图让这个废话发挥作用 我写了一篇关于粘性定位的文章,如果你有兴趣可以在这里查看:dioxmio.medium.com/sticky-done-the-right-way-880af0122a71 @user56reinstatemonica8 谢谢,对我来说它失败了,因为我在 flexbox 中使用了它。 【参考方案1】:

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

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

【讨论】:

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

【讨论】:

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

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

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

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

【讨论】:

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

如果您遇到此问题并且您的粘性不起作用 - 尝试将父级设置为:

display: unset

为我工作

【讨论】:

哦!对于父元素具有有限高度(例如导航栏容器或其他东西,而不是整个主体或页面容器)的情况,这似乎是一种解决方法 - 粘性似乎不喜欢滚动到它们的外部父母(这太荒谬了!)现在每个人都只需要很幸运能够将父母设置为display: unset,这可能并不总是立即可行 似乎也适用于contentsinitial(?) 和inline 它有效。但为什么它会起作用。? display: initial; 也可以。【参考方案5】:

我遇到的其他一些事情:

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

如果 'sticky' 元素本身是具有自定义元素选择器的组件,例如名为 &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(shadow 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 脚本,它就会告诉你每个祖先的溢出属性的值。

$('.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

【讨论】:

display: flex 造就了东西 align-items: flex-start; 在父 flex 容器中是我缺少的东西【参考方案8】:

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

由于弹性盒元素默认为拉伸,所有元素的高度相同,不能滚动。

因此,如果您在父级上使用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】:

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

【讨论】:

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

position: sticky 可能不起作用的另一个非常常见的情况是,如果它的父级具有 display: flexdisplay: grid

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

【讨论】:

【参考方案11】:

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

【讨论】:

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

来自我的评论:

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>

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

如果你想把它变成一个javascript脚本,最接近的是位置:相对+坐标在滚动到达粘滞点时更新

【讨论】:

【参考方案13】:

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

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

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

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

【讨论】:

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

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

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

【讨论】:

【参考方案15】:

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

2.如果任何父元素具有设定的高度,Position Sticky 可能无法正常工作。

【讨论】:

问题是“它是如何工作的”而不是“它是如何工作的”:) 请添加一些解决方案或将它们排除在外。您还可以在问题中添加 cmets,而不是添加不是答案的“答案”。【参考方案16】:

这里有两个答案:

    body标签中移除overflow属性

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

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

【讨论】:

【参考方案17】:

我知道为时已晚。但我找到了一个解决方案即使您在父元素中使用溢出或 display:flex 也可以使用粘性

步骤:

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

    为父元素添加以下样式:

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

    对于粘性元素,请务必添加高于页面中所有元素的 z-index。

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

【讨论】:

【参考方案18】:

从其他方向攻击这个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>

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

案例 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:粘节点&溢出(容易修复):

我通过添加带有溢出设置 auto#extra-wrapper - 或 - 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 相对于其最近的滚动祖先的偏移量。

我通过将#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 布局 - 甚至 cols by deafult(难以修复)

您创建 flex/grid 布局并将其中一个列设置为 sticky。默认情况下,cols 高度是 even = “最近的祖先”(包装器)的高度 == 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(现在列高度不均匀)。

工作:

#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>

【讨论】:

【参考方案19】:

我相信this article 说了很多关于sticky 的工作原理

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

Sticky Item — 是我们用位置定义的元素:粘性样式。当视口位置时元素会浮动 匹配职位定义,例如:top: 0px

Sticky Container — 是包装粘性项目的 HTML 元素。 这是粘性项目可以漂浮的最大区域。

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

【讨论】:

【参考方案20】:

粘性元素的真实行为是:

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

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

元素根据文档的正常流程定位,然后相对于其最近的滚动祖先和包含块(最近的块级祖先)偏移,包括与表格相关的元素,基于顶部、右侧的值、底部和左侧。偏移量不会影响任何其他元素的位置。

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

这个例子将帮助你理解:

codehttps://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】:

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

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

【讨论】:

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

我使用了 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 = `$styleToppx`
    

    setTop()

    window.onresize = function () 
        setTop()
    

【讨论】:

【参考方案25】:

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

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

    %divstyle:"height:600px;" 
      &nbsp;

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

【讨论】:

【参考方案26】:

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

【讨论】:

【参考方案27】:

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

【讨论】:

【参考方案28】:

注意空的网格区域!

在我的情况下,我有这样的事情:

.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';

【讨论】:

【参考方案29】:

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

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

【讨论】:

【参考方案30】:

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

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

我已经在article 上写过关于这方面的内容以及更多内容。只是提供一个参考,所以我不会重复自己太多。

【讨论】:

以上是关于“位置:粘性;”如何?物业工作?的主要内容,如果未能解决你的问题,请参考以下文章

位置粘性与方向 rtl 不起作用

位置粘性没有正确粘贴[重复]

当背景色存在时,为啥“位置:粘性”边框不可见?

为啥“位置:粘性”不适用于 Core UI Bootstrap CSS

当 css 位置粘性停止粘贴时

位置:粘性 - 结合 javascript 高度调整时滚动弹跳