我的位置:使用flexbox时,粘性元素不粘性


105

我对此稍作停留,以为我会分享这个position: sticky+ flexbox陷阱:

在将视图切换到Flex Box容器之前,我的粘性div工作正常,并且当将div包裹在flexbox父级中时,div突然变得不粘性。

.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显示问题


这种行为是否会在所有支持position: sticky或仅一个/某些浏览器上持续存在?
TylerH

1
@TylerH我相信所有的浏览器。它在Chrome和Safari中都像这样工作。
BHOLT

谢谢。我可以确认问题和解决方案也出现在Firefox中。
TylerH

Answers:


204

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

将添加align-self: flex-start到粘性元素上的高度设置为auto,可以滚动并固定它。

当前,所有主要的浏览器都支持此功能,但是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显示解决方案


26
这仅在包含flex元素内滚动时才有效-滚动整个窗口时它不会粘住(至少在Firefox中如此)-因此,对于那些遇到自相矛盾行为的人,您更有可能遇到自相矛盾的期望(例如i was)
aequalsb

@aequalsb您知道滚动整个页面时使其粘住的方法吗?
道格拉斯·加斯凯尔

@Douglas这个问题具有误导性,因为它表明问题出在哪里,flexbox但问题更多与包含sticky元素有关。看看这个小提琴:jsfiddle.net/9y87zL5c,其中第二个红色框按预期工作,但第一个红色框未粘住-所以...这与flexbox无关(因此矛盾的期望)...也...我添加了一堆jabberwocky以更准确的方式查看结果。
aequalsb

27

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

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


您也不能overflow-x:hidden在html元素上使用。
塞缪尔·柳

非常感谢。我一直在努力坚持自己的立场,直到阅读您的答复,我才知道这种情况。:)
拉斐尔·阿莱索

@SamuelLiew,是的,您可以使用overflow-x: hidden;HTML元素。
TheoPlatica

@RaphaelAleixo我很高兴可以为您提供帮助:)
TheoPlatica

这就是阻止我正常工作的原因。非常感谢!
MoOx

7

您还可以尝试将一个子div添加到带有内部内容的flex项目中并分配position: sticky; top: 0;给该项目。

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


完全同意,这是我能找到的最简单,最可靠的选择。这样,您还可以通过控制容器的高度来控制何时停止粘贴。
易卜拉欣·本·萨拉赫

0

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


0

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

我的解决方案需要嵌套display: flexoverflow-y: auto实现所需的行为:

  • 标头可以动态调整高度,从而防止使用position: absoluteposition: fixed
  • 内容垂直滚动,水平限制为视图宽度
  • 粘性元素可以垂直放置在标头底部
  • 其他元素可以水平滑动
    • 看来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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.