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

My position: sticky element isn't sticky when using flexbox

提问人:bholtbholt 提问时间:6/9/2017 最后编辑:TylerHbholtbholt 更新时间:5/25/2023 访问量:164655

问:

我被困在这个上了一会儿,以为我会分享这个 + flexbox 陷阱:position: sticky

我的粘性 div 工作正常,直到我将视图切换到 flex box 容器,突然间 div 在包装在 flexbox 父级中时没有粘性。

.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 粘性

评论

0赞 TylerH 6/13/2017
此行为是否在所有支持或仅支持一个/某些浏览器的浏览器中持续存在?position: sticky
2赞 bholtbholt 6/13/2017
@TylerH我相信这都是浏览器。它在 Chrome 和 Safari 中都像这样运行。
0赞 TylerH 6/13/2017
谢谢。我也可以确认Firefox中也出现了问题和解决方案。

答:

505赞 bholtbholt 6/9/2017 #1

由于 flex box 元素默认为 ,因此所有元素的高度都相同,无法滚动。stretch

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

目前,所有主流浏览器都支持此功能,但 Safari 仍然落后于前缀,并且除 Firefox 之外的其他浏览器在表格方面存在一些问题。-webkit-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 显示解决方案

评论

56赞 aequalsb 9/29/2018
这仅在包含的 flex 元素内滚动时有效 - 当滚动整个窗口时,它不会粘住(至少在 Firefox 中) - 所以对于那些正在经历矛盾行为的人来说,你更有可能正在经历矛盾的期望(就像我一样)
0赞 Douglas Gaskell 3/20/2019
@aequalsb 你知道有一种方法可以让它在滚动整个页面时粘住吗?
0赞 aequalsb 3/20/2019
@Douglas这个问题具有误导性,因为它表明问题出在,但问题更多地与包含元素有关。看看这个小提琴:jsfiddle.net/9y87zL5c 第二个红框按预期工作,但第一个红框没有粘住——所以......这与 Flexbox 无关(因此期望相互矛盾)......也。。。我添加了一堆 jabberwocky 以更准确的方式查看结果。flexboxsticky
3赞 Shahriar 3/3/2021
我在 Firefox 87 中使用它没有问题。工作正常。
1赞 Goal Man 8/23/2022
@Ms. Siri,答案在 Edge 中使用 和 .我的 Flexbox 测试不使用 或 .正如答案所示,您绝对需要。top: 0top: 100pxoverflowheighttopalign-self
16赞 Simon_Weaver 9/7/2019 #2

您也可以尝试将子 div 添加到包含内容的 flex 项中,并分配给它。position: sticky; top: 0;

这对我适用于两列布局,其中第一列的内容需要具有粘性,而第二列的内容看起来是可滚动的。

评论

0赞 Ibrahim ben Salah 1/8/2020
完全同意,这是我能找到的最简单、最可靠的选择。这样,您还可以通过控制容器的高度来控制何时停止粘连。
88赞 TheoPlatica 10/9/2019 #3

就我而言,其中一个父容器已应用于它,这将破坏功能。您需要删除该规则。overflow-x: hidden;position: sticky

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

评论

1赞 Samuel Liew 1/23/2020
你也不能有 html 元素。overflow-x:hidden
1赞 Raphael Aleixo 1/28/2020
多谢。我总是在为位置粘性而苦苦挣扎,直到阅读您的回复,我才知道这种情况。:)
1赞 TheoPlatica 1/29/2020
@SamuelLiew,是的,您可以在 HTML 元素上拥有。overflow-x: hidden;
1赞 alds 3/19/2021
天哪,这奏效了!在我的情况下,隐藏的溢出来自粘性列上三层的父级。我使用了 Bulma 的“section”布局助手,它显然应用了 overflow:hidden。不过,从我的角度来看,overflow-x 和 overflow-y 都不应该被隐藏,而不仅仅是 overflow-x。
2赞 mateostabio 2/14/2022
我刚刚测试了它:你可以在body标签上有,但你不能在任何其他父元素上有。overflow-x: hidden;overflow: hidden;
0赞 Andrew 8/14/2020 #4

我做了一个临时的flexbox桌子,遇到了这个问题。为了解决这个问题,我只需将粘性标题行放在 flexbox 之外,就在它前面。

8赞 OXiGEN 10/14/2020 #5

就我的情况而言,(或)解决方案不起作用。我也需要保留,因为有些容器会水平滑动。align-self: flex-startjustify-self: flex-startoverflow-x: hidden

我的解决方案需要嵌套才能获得所需的行为:display: flexoverflow-y: auto

  • 标头可以动态调整高度,从而防止玩弄或position: absoluteposition: fixed
  • 内容垂直滚动,水平受限于视图宽度
  • 粘性元素可以垂直位于任何位置,粘在标题的底部
  • 其他元素可以水平滑动
    • 看起来 SO 片段工具无法在子元素上渲染以正确演示水平幻灯片,或者我的实际布局中可能有一些其他设置使其工作......width
    • 请注意,需要不执行任何其他操作的包装元素才能允许在父元素下正常工作overflow-x: autooverflow-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>

0赞 Ciabaros 3/25/2021 #6

根据我的经验,全球解决方案/规则:

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

取而代之的是(对于 flex 布局)将带有粘性元素的 table/div 放在 flex 子容器中(例如,使用 { flex: 1 1 auto },但没有 { display : flex } ),那么一切都应该按预期工作。

评论

2赞 Imu Sama 6/29/2021
你能举个例子吗?
34赞 MD SHAYON 7/6/2021 #7

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

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

评论

0赞 Siri 5/26/2022
但是当使用时,例如,不起作用。我该怎么做?align-self: flex-starttop: 100px;
8赞 Qiluo 7/13/2022 #8

确保 flex-wrapper 已分配高度,并将溢出值设置为 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赞 MiftikCZ 4/14/2023 #9

这对我有用,但我不知道这是否是你遇到的问题。 我的问题是,当视口太小时,flexbox 中的居中内容被隐藏了

/*this is the wrapper of centered content*/
.section {
    overflow-y: auto;
    max-height: none;
    height: 100%;
    min-height: 100vh; /*optional, can be changed to anything*/
}
<div class="section">
   <div class="content">
      Some long content that is centered....
   </div>
</div>