“位置:粘性;” 不工作的 CSS 和 HTML

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43707076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:37:03  来源:igfitidea点击:

"Position: sticky;" not Working CSS and HTML

htmlcsscss-position

提问by Harleyoc1

I want to make the Navigation Bar stick to the top once I scroll to it, but it's not working and I have no clue why. If you can please help, here is my HTML and CSS code:

一旦我滚动到导航栏,我想让它粘在顶部,但它不起作用,我不知道为什么。如果你能帮忙,这是我的 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>

回答by MarsAndBack

Check if an ancestor element has overflow set (e.g. overflow:hidden); try toggling it. You may have to go up the DOM tree higher than you expect =).

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

This may affect your position:stickyon a descendant element.

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

回答by Marvin

Sticky positioning is a hybrid of relative and fixed positioning. The element is treated as relative positioned until it crosses a specified threshold, at which point it is treated as fixed positioned.
...
You must specify a threshold with at least one of top, right, bottom, or leftfor sticky positioning to behave as expected. Otherwise, it will be indistinguishable from relative positioning. [source: MDN]

粘性定位是相对定位和固定定位的混合体。元素被视为相对定位,直到它超过指定的阈值,此时它被视为固定定位。
...
您必须指定的至少一个阈值toprightbottom,或left为粘稠定位像预期的那样。否则,它将与相对定位无法区分。[来源:MDN]

So in your example, you have to define the position where it should stick in the end by using the topproperty.

因此,在您的示例中,您必须使用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>

回答by Miftah Mizwar

I have same problem, and i found the answer here.

我有同样的问题,我在这里找到了答案。

If your element isn't sticking as expected the first thing to check are the rules applied to the container.

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

Specifically, look for any overflow property set on the parent. You can't use: overflow: hidden, overflow: scrollor overflow: autoon the parent of a position: stickyelement.

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

回答by Simon_Weaver

Few more things I've come across:

我遇到的更多事情:

When your sticky element is a component (angular etc)

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

  • If the 'sticky' element itself is a component with a custom element-selector, such as an angular component named <app-menu-bar>you will need to add the following to the component's css:

    :host { display: block; }   
    

    or

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

    Safari on iOS in particular seems to require display:blockeven on the root element app-rootof an angular application or it won't stick.

  • If you are creating a component and defining the css inside the component (shadow DOM / encapsulated styles), make sure the position: stickyis being applied to the 'outer' selector (eg. app-menu-barin devtools should show the sticky position) and not a top level divwithinthe component. With Angular, this can be achieved with the :hostselector in the css for your component.

    :host
    {
        position: sticky;
        display: block;   // this is the same as shown above
        top: 0;
        background: red;    
    }
    
  • 如果 'sticky' 元素本身是一个带有自定义元素选择器的组件,例如名为 angular 的组件<app-menu-bar>,则需要将以下内容添加到组件的 css 中:

    :host { display: block; }   
    

    或者

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

    尤其是 iOS 上的 Safari 似乎display:block甚至需要app-rootangular 应用程序的根元素,否则它不会粘住。

  • 如果要创建一个组件,定义组件内部的CSS(影子DOM /封装样式),确保position: sticky被应用到“外”选择(例如,app-menu-bar在devtools应显示粘的位置),而不是一个顶级div组件。使用 Angular,这可以通过:host组件 css 中的选择器来实现。

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

Other

其他

  • If the element following your sticky element has a solid background, you must add the following to stop it from sliding underneath:

    .sticky-element { z-index: 100; }
    .parent-of-sticky-element { position: relative; }
    
  • Your sticky element must be first (before your content) if using topand after it if using bottom.

  • There are complications when using overflow: hiddenon your wrapper element – in general it will kill the sticky element inside. Better explained in this question

  • Mobile browsers may disable sticky/fixed positioned items when the onscreen keyboard is visible. I'm not sure of the exact rules (does anybody ever know) but when the keyboard is visible you're looking at a sort of 'window' into the window and you won't easily be able to get things to stick to the actual visible top of the screen.

  • Make sure you have:

    position: sticky;

    and not

    display: sticky;

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

    .sticky-element { z-index: 100; }
    .parent-of-sticky-element { position: relative; }
    
  • 如果使用top,则您的粘性元素必须是第一个(在您的内容之前),如果使用bottom.

  • overflow: hidden在你的包装元素上使用时会出现一些复杂情况——通常它会杀死里面的粘性元素。在这个问题中更好地解释

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

  • 确保你有:

    position: sticky;

    并不是

    display: sticky;

Misc usability concerns

其他可用性问题

  • Be cautious if your design calls for for sticking things to the bottom of the screen on mobile devices. On iPhone X for instance they display a narrow line to indicate the swipe region (to get back to the homepage) - and elements inside this region aren't clickable. So if you stick something there be sure to test on iPhone X that users can activate it. A big 'Buy Now' button is no good if people can't click it!
  • If you're advertising on Facebook the webpage is displayed in a 'webview' control within Facebook's mobile apps. Especially when displaying video (where your content begins in the bottom half of the screen only) - they often completely mess up sticky elements by putting your page within a scrollable viewport that actually allows your sticky elements to disappear off the top of the page. Be sure to test in the context of an actual ad and not just in the phone's browser or even Facebook's browser which can all behave differently.
  • 如果您的设计要求将东西贴在移动设备屏幕的底部,请务必小心。例如,在 iPhone X 上,它们显示一条细线来指示滑动区域(以返回主页)-并且该区域内的元素不可点击。因此,如果您坚持使用某些东西,请务必在 iPhone X 上测试用户是否可以激活它。如果人们无法点击,那么大的“立即购买”按钮是没有用的!
  • 如果您在 Facebook 上投放广告,该网页将显示在 Facebook 移动应用程序内的“webview”控件中。尤其是在显示视频时(您的内容仅从屏幕的下半部分开始) - 它们通常会将您的页面放在可滚动的视口中,从而完全弄乱粘性元素,这实际上允许粘性元素从页面顶部消失。请务必在实际广告的上下文中进行测试,而不仅仅是在手机浏览器甚至 Facebook 浏览器中进行测试,这些浏览器的行为都可能有所不同。

回答by danday74

This is a continuation of the answers from MarsAndBack and Miftah Mizwar.

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

Their answers are correct. However, it is difficult to identify the problem ancestor(s).

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

To make this very simple, simply run this jQuery script in your browser console and it will tell you the value of the overflow property on every ancestor.

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

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

Where an ancestor does not have overflow: visiblechange its CSS so that it does!

祖先没有overflow: visible更改其 CSS 以使其更改!

Also, as stated elsewhere, make sure your sticky element has this in the CSS:

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

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

回答by Unicco

I had to use the following CSS to get it working:

我必须使用以下 CSS 才能使其正常工作:

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

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

If above dosen't work then...

如果以上不起作用,那么...

Go through all ancestors and make sure none of these elements have overflow: hidden. You have to change this to overflow: visible

遍历所有祖先并确保这些元素都没有overflow: hidden. 你必须把它改成overflow: visible

回答by G-Cyrillus

from my comment:

从我的评论:

position:stickyneeds a coordonate to tel where to stick

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>

There is polyfill to use for other browsers than FF and Chrome . This is an experimental rules that can be implemented or not at any time through browsers. Chrome add it a couple of years ago and then dropped it, it seems back ... but for how long ?

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

The closest would be position:relative + coordonates updated while scrolling once reached the sticky point, if you want to turn this into a javascript script

最接近的是 position:relative + coordonates 在滚动到达粘滞点时更新,如果你想把它变成一个 javascript 脚本

回答by i.k

Funny moment that wasn't obvious for me: at least in Chrome 70 position: stickyis not applied if you've set it using DevTools.

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

回答by solaris333

It seems like that the navbar to be stickied shouldn't be inside any div or section with other content. None of the solution were working for me until I took the navbar out of the div which the navbar shared with another topbar .I previously had topbar and navbar wrapped with a common div.

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

回答by Marco Peralta

I know this is an old post. But if there's someone like me that just recently started messing around with position: sticky this can be useful.

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

In my case i was using position: sticky as a grid-item. It was not working and the problem was an overflow-x: hidden on the htmlelement. As soon as i removed that property it worked fine. Having overflow-x: hidden on the bodyelement seemed to work tho, no idea why yet.

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