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

问题描述 投票:0回答:2

我试图使用

left: 0
阻止元素滚动过去
position: sticky
。在某些情况下,这工作得很好,但我注意到,如果元素宽度增加,它就会停止工作。例如,以下作品:

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

但是如果我将标题元素的宽度增加到

100%
,它就会停止工作。

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

为什么会出现这种情况?有没有办法使用

position: sticky
来防止标题元素在宽度为
100%
时滚动?在这种情况下我不想使用
position: fixed

html css css-position sticky horizontal-scrolling
2个回答
43
投票

我现在明白发生了什么。问题在于浏览器处理

<div>
的宽度和高度的方式不同。
auto
的默认值意味着
<div>
的宽度为
100%
,而高度由内容设置。如果内容比
100%
宽,则在水平滚动时,粘性元素会碰到容器
<div>
的末尾,并且由于它无法离开容器的边界,因此开始滚动。在垂直滚动的情况下,这种情况不会发生,因为默认情况下容器
<div>
与内容一样高。

为了防止这种情况发生,我们必须确保容器

<div>
与其内容一样宽。这可以在大多数浏览器(不是 Edge 或 Explorer)中通过在容器样式中包含
width: max-content
来完成。或者,正如 mfluehr 的答案中所建议的那样,放置
overflow: auto
会创建一个与内容一样宽的新块格式化上下文。另一种选择是使用
display: inline-block
inline-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;
}
<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>


9
投票

这是一个有趣的问题。我不知道为什么,但将

overflow: auto
放在
<div>
周围的容器上似乎可以解决问题。

可以在容器中添加

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);
}
<body>
  <div id="container">
    <div id="header">
      This is the header.
    </div>
    <div id="page">
      Page content goes here.
    </div>
  </div>
</body>

© www.soinside.com 2019 - 2024. All rights reserved.