当元素宽度增加时,位置粘性不适用于水平滚动

jdn*_*dnz 3 html css

我试图left: 0使用position: sticky. 这在某些情况下工作正常,但我注意到如果元素宽度增加它会停止工作。例如,以下工作:

#header {
  position: sticky;
  left: 0;
  width: 50%;
  background-color: #888;
}
#page {
  height: 80vh;
  width: 120vw;
  background-color: #000;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <div id="header">
    Where is my mind?
  </div>
  <div id="page">
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

但是如果我增加标题元素的宽度,100%它就会停止工作。

#header {
  position: sticky;
  left: 0;
  width: 100%;
  background-color: #888;
}
#page {
  height: 80vh;
  width: 120vw;
  background-color: #000;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <div id="header">
    Where is my mind?
  </div>
  <div id="page">
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况?有什么方法可以position: sticky用来防止标题元素在宽度为 时滚动100%?我不想position: fixed在这种情况下使用。

jdn*_*dnz 15

我现在明白发生了什么。问题在于浏览器处理 a 的宽度和高度的方式不同<div>。的默认值auto意味着宽度<div>是,100%而高度是由内容设置的。如果内容比 宽100%,则在水平滚动时粘性元素会碰到容器的末端,<div>并且由于它无法离开容器的范围,因此开始滚动。这不会发生在垂直滚动的相同情况下,因为<div>默认情况下容器与内容一样高。

为了防止这种情况发生,我们必须确保容器<div>与其内容一样宽。这可以在大多数浏览器(不是 Edge 或 Explorer)中通过包含width: max-content在容器样式中来完成。或者,如 mfluehr 的回答中所建议的, putoverflow: auto会创建一个与内容一样宽的新块格式化上下文。另一种选择是使用display: inline-blockinline-flex等使容器<div>的宽度基于内容。

例如,使用其中的两种技术,您可以创建页眉、侧边栏和页脚,这些页眉、侧边栏和页脚都贴在可以垂直和水平滚动的页面上:

body {
  padding: 0;
  margin: 0;
}
#app {
  overflow: auto;
  height: 100vh;
}
#header {
  background: blue;
  width: 100%;
  height: 40px;
  position: sticky;
  top: 0;
  left: 0;
  z-index: 10;
  color: white;
}
#sidebar {
  position: sticky;
  background: green;
  width: 200px;
  height: calc(100vh - 40px);
  top: 40px;
  left: 0;
  color: white;
  flex-grow: 0;
  flex-shrink: 0;
}
#container {
  display: inline-flex;
}
#content {
  background: #555;
  height: 200vh;
  width: 200vw;
  background: linear-gradient(135deg, #cc2, #a37);
  flex-grow: 0;
  flex-shrink: 0;
}
#footer {
  background: #000;
  height: 100px;
  z-index: 100;
  left: 0;
  position: sticky;
  color: white;
}
Run Code Online (Sandbox Code Playgroud)
<div id="app">
  <div id="header" ref="header">
    Header content
  </div>
  <div id="container">
    <div id="sidebar" ref="sidebar">
      Sidebar content
    </div>
    <div id="content" ref="content">
      Page content
    </div> 
  </div>
  <div id="footer" ref="footer">
    Footer content
  </div>  
</div>
Run Code Online (Sandbox Code Playgroud)

  • 伙计,这是一个很好的答案。它确实有助于说明浏览器如何以不同的方式计算宽度和高度。我不明白为什么我的宽度没有扩大但高度却扩大了。这绝对让我们正确地看待它。谢谢你! (3认同)

mfl*_*ehr 5

这是一个有趣的问题。我不知道为什么,但是overflow: auto<div>s周围放上容器似乎可以解决这个问题。

您可以添加height: 100vh到容器中,让里面的内容溢出滚动条。

body {
  margin: 0;
}

#container {
  overflow: auto;
  height: 100vh;
}

#header {
  position: sticky;
  left: 0;
  width: 100%;
  background-color: #888;
}
#page {
  height: 200vh;
  width: 120vw;
  background: linear-gradient(135deg, #cc2, #a37);
}
Run Code Online (Sandbox Code Playgroud)
<body>
  <div id="container">
    <div id="header">
      This is the header.
    </div>
    <div id="page">
      Page content goes here.
    </div>
  </div>
</body>
Run Code Online (Sandbox Code Playgroud)