【问题标题】:'position: sticky' not working when 'height' is defined定义“高度”时,“位置:粘性”不起作用
【发布时间】:2018-09-25 15:43:27
【问题描述】:

我正在构建一个登录页面,用户首先会看到一个主要区域,其下方有一个页脚。进一步向下滚动显示页脚是一个粘性页眉,我的目标是使用纯 CSS 来实现这一点。为了获得主要内容和页脚的全屏外观,我将height 属性设置为两个不同的值:92% 和8%(使用vh 也不起作用)。无论我在 CSS 中指定的height(不同的单位和所有单位),我的页脚div 都不会粘住。一旦我删除 height 属性,它就会按预期工作。

这是我的页面删除height属性之前的屏幕截图:

如您所见,它确实坚持:

删除height 属性值后,它确实粘住了:

相关代码下方:

html,
body {
  height: 100%;
  margin: 0;
}

#main {
  height: 92%;
}

#landing {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
}

#landingContent {
  width: 20vw;
}

#footerNav {
  height: 8%;
  display: flex;
  align-items: center;
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
}
<div id="main">
  <div id="landing">
    <div id="landingContent">
      <h1 class="logo">Logo</h1>
      <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
      <button>Button</button>
    </div>
  </div>
</div>
<div id="footerNav">
  <div id="footerNavContent">
    <h1 class="logo">Logo</h1>
  </div>
</div>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>

我已经读到使用overflow 属性可能会出现问题,尽管它不存在,我也没有听说过height 对其他人来说是个问题。当然,我可能错了。

我已经测试过:

  • Firefox 61(每晚)
  • Safari 53(技术预览)
  • 铬 65

编辑:大发展;从#main 中删除height 属性会使#footerNav 保持粘性。

【问题讨论】:

  • 在您的第一个(设置高度的加载页面)屏幕截图和第三个(没有高度的工作)屏幕截图中,footer 的高度没有太大差异。那么,您想设置footerheight 的具体目的是什么?另外,您是否尝试过仅为footer 删除height
  • @xuhaib 我很欣赏为统一设置的高度,并确保页面 100% 填充页脚和主要内容,如果这有意义的话。删除页脚的高度产生了一个有趣的结果:页脚会保持粘性一段时间,但是一旦我滚动到某个点,就会“不粘”。在 Firefox 中测试。
  • 有什么理由不能使用 javascript?
  • @Pixelomo 没有什么特别的原因,我想我宁愿保持干净。
  • 完全不同意,CSS3 的“粘性位置属性”是为他试图解决的问题而设计的。 Temani 一针见血。

标签: html css flexbox css-position sticky


【解决方案1】:

这里的问题在于height,而不是您想到的height。我们先从sticky position的定义开始:

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

这里的重要部分是最后一句话,它解释了当元素到达其包含块的边缘时,粘性位置将结束,在您的情况下,粘性元素的包含块是主体并且您将正文设置为height:100%,并且您的内容溢出

因此,当将 main 的高度设置为 92%,将页脚设置为 8% 时,您已经 在其包含块的相反边缘设置了页脚。这是一个插图,我在正文中添加了背景颜色,以便您可以清楚地看到:

html,
body {
  height: 100%;
  margin: 0;
}
html {
  background:white;
}
body {
  background:blue;
}

#main {
  height: 92%;
}
#landing {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
}
#landingContent {
  width: 20vw;
}
#footerNav {
  height: 8%;
  display: flex;
  align-items: center;
  position: sticky;
  top: 0px;
  background:red;
  color:#fff;
}
<div id="main">
    <div id="landing">
        <div id="landingContent">
            <h1 class="logo">Logo</h1>
            <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
            <button>Button</button>
        </div>
    </div>
</div>
<div id="footerNav">
    <div id="footerNavContent">
        <h1 class="logo">Logo</h1>
    </div>
</div>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>

如您所见,徽标已经位于主体底部,因此无法使其像粘性一样移动。你的内容也溢出来了。

现在,如果您稍微降低主要内容的高度,您会看到一个小的粘性行为,该行为将在页脚到达蓝色部分(body)的底部时结束。

html,
body {
  height: 100%;
  margin: 0;
}
html {
  background:white;
}
body {
  background:blue;
}

#main {
  height: 82%;
}
#landing {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
}
#landingContent {
  width: 20vw;
}
#footerNav {
  height: 8%;
  display: flex;
  align-items: center;
  position: sticky;
  top: 0px;
  background:red;
  color:#fff;
}
<div id="main">
    <div id="landing">
        <div id="landingContent">
            <h1 class="logo">Logo</h1>
            <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
            <button>Button</button>
        </div>
    </div>
</div>
<div id="footerNav">
    <div id="footerNavContent">
        <h1 class="logo">Logo</h1>
    </div>
</div>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>

为了解决这个问题,您只需避免将height:100% 设置为正文。您可以改用min-height 或保持其高度自动。您也可以考虑使用vh 单元作为主要和页脚:

html,
body {
  /*height: 100%;
    no needed
  */ 
  margin: 0;
}
html {
  background:white;
}
body {
  background:blue;
}

#main {
  height: 92vh;
}
#landing {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
}
#landingContent {
  width: 20vw;
}
#footerNav {
  height: 8vh;
  display: flex;
  align-items: center;
  position: sticky;
  top: 0px;
  background:red;
  color:#fff;
}
<div id="main">
    <div id="landing">
        <div id="landingContent">
            <h1 class="logo">Logo</h1>
            <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
            <button>Button</button>
        </div>
    </div>
</div>
<div id="footerNav">
    <div id="footerNavContent">
        <h1 class="logo">Logo</h1>
    </div>
</div>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>

更多细节/示例的相关问题:

Why element with position:sticky doesn't stick to the bottom of parent?

What are `scrolling boxes`?

If you specify `bottom: 0` for position: sticky, why is it doing something different from the specs?

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,但我需要父容器上的 height: 100%;。在我的情况下,我有一个粘性导航,内容需要增长到完整长度,并且页脚应该始终在页面末尾可见(但没有位置属性)。

    我通过将overflow: auto; 设置为该父容器来修复它。现在父级仍然是 100% 高,但其中的粘性容器与高度限制无关。

    【讨论】:

      【解决方案3】:

      对使用 position:sticky 的支持似乎有点弱。您可以在此页面中查看:

      https://caniuse.com/#search=position%3A%20sticky

      如果你想要一个粘性页脚,你可以使用 position: absolute,这是每个浏览器都支持的。我拿了你的代码并创建了一个迷你版来说明我关于位置的观点:绝对。

      <!doctype html>
          <html>
              <head>
          <style>
              * {
                  margin: 0;
                  padding: 0;
              }
      
              .footerNav {
                  background-color: red;
                  position: absolute;
                  bottom: 0;
                  width: 100%;
                  height: 100px;
              }
          </style>
      </head>
      <body>
          <div id="main">
              <div id="landing">
                  <div id="landingContent">
                      <h1 class="logo">Logo</h1>
                      <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
                      <button>Button</button>
                  </div>
              </div>
          </div>
          <div class="footerNav">
              <div id="footerNavContent">
                  <h1 class="logo">Logo</h1>
              </div>
          </div>
      </body>
      

      请注意,我将 id="footerNav" 更改为 class="footerNav"。我个人喜欢应用样式的类。但是,如果您仍然愿意,可以使用 id。

      如果您希望登录页面出现,然后用户滚动一点以查看您的页脚,那么您可以使用 height: 100vh 并从页脚中删除绝对位置,因为它将被向下推主要内容 div。例如:

      <!doctype html>
          <html>
      <head>
          <style>
              * {
                  margin: 0;
                  padding: 0;
              }
      
              #main {
                  height: 100vh;
              }
      
              #footerNav {
                  background-color: red;
                  position: relative;
                  bottom: 0;
                  width: 100%;
                  height: 100px;
              }
          </style>
      </head>
      <body>
          <div id="main">
              <div id="landing">
                  <div id="landingContent">
                      <h1 class="logo">Logo</h1>
                      <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
                      <button>Button</button>
                  </div>
              </div>
          </div>
          <div id="footerNav">
              <div id="footerNavContent">
                  <h1 class="logo">Logo</h1>
              </div>
          </div>
      </body>
      

      希望我的回答能对你有所帮助。

      【讨论】:

      • 感谢您的回复,但我认为您并没有真正回答我的问题:“粘性”行为有效,但是当应用两个 div 的高度属性时,它会中断。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 1970-01-01
      相关资源
      最近更新 更多