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

时间:2017-04-30 13:43:42

标签: html css

我想在滚动到导航栏时将导航栏固定在顶部,但它不起作用,我不知道为什么。如果你能提供帮助,这是我的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>
&#13;
&#13;
&#13;

26 个答案:

答案 0 :(得分:161)

检查祖先元素是否有溢出集(例如overflow:hidden);尝试切换它。你可能不得不高出你期望的DOM树=)。

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

答案 1 :(得分:99)

  

粘性定位是相对定位和固定定位的混合。该元素被视为相对位置,直到它超过指定的阈值,此时它被视为固定位置   ...
  您必须至少指定toprightbottomleft中的一个阈值才能使粘性定位符合预期。否则,它将与相对定位无法区分。    [source: MDN]

因此,在您的示例中,您必须使用top属性定义最终应该保留的位置。

&#13;
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:68)

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

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

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

答案 3 :(得分:18)

如果您遇到此问题而粘滞不起作用-尝试将父项设置为:

display: unset

为我工作

答案 4 :(得分:16)

我遇到的事情很少:

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

  • 如果'sticky'元素本身是具有自定义元素选择器的组件,例如名为<app-menu-bar>的角度组件,则需要将以下内容添加到组件的css中:

    :host { display: block; }   
    

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

    iOS上的Safari似乎甚至需要display:block甚至在角度应用程序的根元素app-root上,否则它将不会坚持。

  • 如果要创建组件并在组件内定义css(shadow DOM /封装样式),请确保将position: sticky应用于“外部”选择器(例如{{1}在devtools中应该显示粘性位置)而不是组件中的顶级app-menu-bar 。使用Angular,可以使用组件的css中的div选择器来实现。

    :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时会出现复杂情况 - 通常它会杀死里面的粘性元素。 Better explained in this question

  • 当屏幕键盘可见时,移动浏览器可能会禁用粘贴/固定定位项目。我不确定确切的规则(有没有人知道)但是当键盘可见时你正在看窗口中的某种“窗口”,你将无法轻易地将事情坚持到实际可见的屏幕顶部。

  • 确保您拥有:

    overflow: hidden

    而不是

    position: sticky;

答案 5 :(得分:11)

这是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;
}

答案 6 :(得分:7)

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

<块引用>

由于 flex box 元素默认拉伸,所有元素高度相同,不能滚动。

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

这是粘性元素类的样子

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

答案 7 :(得分:3)

来自我的评论:

&#13;
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

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

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

答案 8 :(得分:3)

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

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

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

答案 9 :(得分:2)

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

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

答案 10 :(得分:2)

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

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

/**
 * 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;
}

答案 11 :(得分:2)

粘性元素的实际行为是:

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

粘性定位的元素被视为相对定位,直到其包含的块在其流根(或滚动其中的容器)内超过指定的阈值(例如将top设置为auto以外的值),然后对其进行处理直到遇到其包含块的相反边缘为止。

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

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

此示例将帮助您理解:

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

答案 12 :(得分:2)

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

答案 13 :(得分:2)

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

答案 14 :(得分:1)

我知道这是旧帖子。但是,如果最近有像我这样的人开始摆弄位置:粘性,这可能会有用。

在我的情况下,我使用的是位置:粘性作为网格项目。它不起作用,问题是一个溢出-x:隐藏在html元素上。一旦我删除了该属性,它就可以正常工作。在body元素上隐藏overflow-x:似乎行得通,尚不知道为什么。

答案 15 :(得分:1)

if [ -z "$JAVA_HOME" ]; then JAVA="java" else JAVA="$JAVA_HOME\java" fi JAVA = "../Java/jdk12/bin/java" echo $JAVA 也非常重要。有时它会起作用,但您只会看不到它。请确保将其设置为很高的数值。另外,不要总是放在z-index上,但要尝试将其隐藏在某个地方(在工具栏下),请尝试更高的东西。

答案 16 :(得分:1)

我知道为时已晚。但是我发现了一个解决方案,即使您在父元素中使用溢出或display:flex粘滞功能也可以

步骤:

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

  2. 在父元素中添加以下样式:

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

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

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

答案 17 :(得分:1)

此处有两个答案:

  1. overflow标记中删除body属性

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

  3. 的问题
  

min-height: 100%无效,而不是height: 100%

答案 18 :(得分:0)

我相信this article可以使export default (value) => const duration = moment.duration(value); const milliseconds = duration.milliseconds(); const seconds = duration.seconds(); const minutes = duration.minutes(); const hours = duration.hours(); const day = duration.days(); const sDay = `${day}d `; const sHours = (hours < 10) ? `0${hours}h ` : `${hours}h `; const sMinutes = (minutes < 10) ? `0${minutes}' ` : `${minutes}' `; const sSeconds = (seconds < 10) ? `0${seconds}" ` : `${seconds}" `; const sMilliseconds = `${milliseconds}ms`; ... } 的工作原理变得非常神秘

  

CSS位置粘性如何真正起作用!   CSS位置粘性有两个主要部分,粘性项目和粘性容器

     

粘性项目-是我们使用以下位置定义的元素:粘性样式。视口位置时元素将浮动   匹配位置定义,例如:sticky

     

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

     

当您定义具有以下位置的元素:粘性时,您会自动   将父元素定义为粘性容器!

答案 19 :(得分:0)

我知道这似乎已经得到了回答,但是我遇到了一个具体案例,我觉得大多数答案都没有说清楚。

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

但最好在容器的高度内使用粘性行为。考虑一下您网站右侧列中随页面向下滚动的新闻通讯形式。 如果您的粘滞元素是容器的唯一子元素,则该容器的大小完全相同,并且没有滚动空间。

您的容器必须是您希望元素在其中滚动的高度。在我的“右列”方案中,哪一个是左列的高度。 实现此目的的最佳方法是在列上使用display:table-cell。如果不能,并且像我以前那样受float:right的困扰,那么您将不得不猜测用Javascript计算它的左列高度。

答案 20 :(得分: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.getElementById('header');
    let navbar = document.getElementById('nav');
    var headerHeight = header.getBoundingClientRect().height;
    var navbarHeight = navbar.getBoundingClientRect().height;
    var styleTop = navbarHeight - headerHeight;
    header.style.position = 'sticky';
    header.style.top = styleTop + 'px';

    window.onresize = function() {
        headerHeight = header.getBoundingClientRect().height;
        navbarHeight = navbar.getBoundingClientRect().height;
        styleTop = navbarHeight - headerHeight;
        header.style.top = styleTop + 'px';
    }
}

window.onload = applyNavbarSticky();

答案 21 :(得分:0)

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

就我而言,我有两个孩子,一个漂浮在左边,另一个漂浮在右边。 我希望右边的浮动对象变得粘滞,但必须在父级末尾添加一个<div style="clear: both;"></div>,以使其高度。

答案 22 :(得分:0)

确实需要删除overflow或将其设置为initial才能使position: sticky在子元素上起作用。我在Angular应用程序中使用了Material Design,发现 some Material组件更改了overflow值。我的情况的解决方法是

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

答案 23 :(得分:0)

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

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

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

(我的应用程序有两个并排的div,左侧有一个“高”图像,右侧有一个简短的数据输入表单,我希望数据输入表单在您旁边浮动在图像旁边向下滚动,因此表单始终显示在屏幕上。直到我添加了上面的“额外内容”,该表单才起作用,因此粘性div可以“滑过”

答案 24 :(得分:0)

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

答案 25 :(得分:-2)

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

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

我已经在此 article 上写过有关此内容和更多内幕的文章。只是提供一个参考,所以我不会重复太多。