我的立场:使用 flexbox 时粘性元素不粘

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

我被困在这个问题上了一点,我想我会分享这个

position: sticky
+ flexbox 陷阱:

我的粘性 div 工作正常,直到我将我的视图切换到一个 flex box 容器,当它被包裹在一个 flexbox parent 中时突然不粘了。

.flexbox-wrapper {
  display: flex;
  height: 600px;
}
.regular {
  background-color: blue;
}
.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  background-color: red;
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>

JSFiddle 显示问题

css flexbox css-position sticky
8个回答
444
投票

由于 flex box 元素默认为

stretch
,所有元素高度相同,无法滚动。

align-self: flex-start
添加到粘性元素将高度设置为自动,允许滚动,并修复它。

目前所有主流浏览器都支持,但Safari仍然在

-webkit-
前缀后面,除Firefox之外的其他浏览器在
position: sticky
表方面存在一些问题。

.flexbox-wrapper {
  display: flex;
  overflow: auto;
  height: 200px;          /* Not necessary -- for example only */
}
.regular {
  background-color: blue; /* Not necessary -- for example only */
  height: 600px;          /* Not necessary -- for example only */
}
.sticky {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
  align-self: flex-start; /* <-- this is the fix */
  background-color: red;  /* Not necessary -- for example only */
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>

JSFiddle 显示解决方案


74
投票

就我而言,其中一个父容器应用了

overflow-x: hidden;
,这将破坏
position: sticky
功能。您需要删除该规则。

任何父元素都不应应用上述 CSS 规则。此条件适用于(但不包括)“身体”元素的所有父母。


27
投票

如果您在父元素中使用 flex,请使用 align-self: flex-start 为您想要粘性的元素。

position: sticky;
align-self: flex-start;
top: 0;
overflow-y: auto;

15
投票

您还可以尝试将子 div 添加到包含内容的 flex 项目,并将

position: sticky; top: 0;
分配给它。

这对我来说适用于双列布局,其中第一列的内容需要粘性,第二列显示为可滚动。


8
投票

对于我的情况,

align-self: flex-start
(或
justify-self: flex-start
)解决方案不起作用。我还需要保留
overflow-x: hidden
,因为有些容器会水平滑动。

我的解决方案需要嵌套

display: flex
overflow-y: auto
以获得所需的行为:

  • header可以动态调整高度,防止玩
    position: absolute
    position: fixed
  • 内容垂直滚动,水平受限于视图宽度
  • sticky 元素可以垂直放置在任何地方,粘在标题的底部
  • 其他元素可以水平滑动
    • 看起来 SO 片段工具无法在子元素上呈现
      width
      以正确演示水平滑动,或者我的实际布局上可能有一些其他设置使其工作......
    • 请注意,需要一个不做任何其他事情的包装器元素,以允许
      overflow-x: auto
      在具有
      overflow-x: hidden
    • 的父级下的元素中正常工作

body {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
}

body>header {
  background-color: red;
  color: white;
  padding: 1em;
}

.content {
  overflow-x: hidden;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

article {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.horizontal_slide {
  display: flex;
  overflow-x: auto;
  background-color: lightblue;
  padding: .5em;
}

.horizontal_slide>* {
  width: 1000px;
}

.toolbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: lightgray;
  padding: .5em;
  display: flex;
}
<header>Fancy header with height adjusting to variable content</header>
<div class="content">
  <article class="card">
    <h1>One of several cards that flips visibility</h1>
    <div class="overflow_x_wrapper">
      <div class="horizontal_slide">
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
      </div>
      <div class="toolbar">Sticky toolbar part-way down the content</div>
      <p>Rest of vertically scrollable container with variable number of child containers and other elements</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </article>
  </div>


3
投票

确保 flex-wrapper 已经分配了高度,并将 overflow 值设置为 auto。 然后添加“align-self: flex-start;”到粘性元素。

.flexbox-wrapper {
  display: flex;
  height: 600px;  //<- nessary,and don't assign with %
  overflow:auto;  //<-fix
}
.regular {
  background-color: blue;
}
.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  background-color: red;
  align-self: flex-start; // <-fix
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>


0
投票

我做了一个临时的 flexbox 表并遇到了这个问题。为了解决这个问题,我简单地将粘性标题行放在 flexbox 的外面,就在它之前。


0
投票

我的经验的全局解决方案/规则:

不要将带有粘性元素的结构直接放入 { display : flex } 容器中。

相反(对于 flex 布局)将带有粘性元素的表格/div 放入 flex 子容器(例如使用 { flex: 1 1 auto },但是 without { display : flex } ),那么一切都应该像有意的。

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