怎么才能有position:fixed; flexbox 大小的元素的行为?

How can I have a position: fixed; behaviour for a flexbox sized element?

我有一个名为 .side-el 的 div,我希望它处于一个位置:已修复;行为,但是一旦我应用固定位置,宽度就会从正确的位置交替。正确的宽度将由 flexbox 设置。我怎样才能实现这个目标?

.container {
  -webkit-align-content: flex-start;
  align-content: flex-start;
  -webkit-align-items: flex-start;
  align-items: flex-start;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: row;
  flex-direction: row;
  -webkit-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-justify-content: flex-start;
  justify-content: flex-start;
  
  * {
    box-sizing: border-box;
    -webkit-flex-grow: 1;
    flex-grow: 1;
    -webkit-flex-shrink: 0;
    flex-shrink: 0;
  }
}


.main-el {
  box-sizing: border-box;
  padding:0 2em;
  width: 70%;
}

.side-el {
  box-sizing: border-box;
  width: 30%;
}
<div class="container" style="background-color: blue; height: 100px;">
  <div class="main-el">
    <div  style="background-color: red; height: 1000px;">content</div>
  </div>
  <div class="side-el" >
    <div style="background-color: red; height: 100px;">content</div>
  </div>
</div>

你不能。

CSS2.1 spec 所述:

Absolutely positioned boxes are taken out of the normal flow.

并且 Flexible Box Layout 规范确认:

An absolutely-positioned child of a flex container does not participate in flex layout. However, it does participate in the reordering step (see order), which has an effect in their painting order.

(强调我的)

@Daniel,我知道这已经很晚了但是......虽然接受的答案是正确的,但我觉得它没有多大帮助。 我有同样的问题(这就是我遇到这个 post 的原因),我认为我会采用的解决方案是将位置固定元素包装在 flex 元素中。 这是一个(非常难看)example

相关标记

  <aside class="Layout-aside" ng-class="{'isCollapsed': collapsed}" ng-controller="AsideCtrl">
    <div class="Layout-aside-inner">
      <button ng-click="collapsed = !collapsed">
        <span ng-show="collapsed">&gt;</span>
        <span ng-hide="collapsed">&lt;</span>
      </button>
      <ul class="Layout-aside-content">
        <li ng-repeat="i in items">{{i}}</li>
      </ul>
    </div>
  </aside>

相关CSS

.Layout-aside {
  order: 0;
  min-width: 140px;
  width: 140px;
  background-color: rgba(0, 255, 0, .4);
  transition: width .4s, min-width .4s; 
}
.Layout-aside.isCollapsed {
  min-width: 25px;
  width: 25px;
}

.Layout-aside-inner {
  position: fixed;
}

.Layout-aside.isCollapsed .Layout-aside-inner {
  width: 25px;
}

.Layout-aside.isCollapsed .Layout-aside-content {
  opacity: 0;
}

一个更简单的解决方案是在 main-el 容器上使用 overflow-y:scrollheight: 100vh。这将为 side-el 容器提供固定位置的外观,而无需求助于 position: fixed。

这是一种受 bootstrap 启发的方法:

.fixed-top {
  display: flex;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

这为您的 flex-box 空间提供了喘息的空间,让您可以做 flex-box 的事情。如果你的 flex-direction 是列,你可以使用 top, left, bottom 代替。

这是有效的,因为当你给一个元素一个固定的位置并且 leftright 为 0 或 topbottom 为 0 时,该元素是从左到右或从上到下拉伸以填充 space。这反过来又允许 flex-box 使用你期望的 space 数量而不固定位置。

您可以使用 css 替代方法实现它 position: sticky

效果很好,但唯一的问题是浏览器支持(2018 年 6 月): https://caniuse.com/#feat=css-sticky

希望快点好起来。

我遇到了同样的问题,实际上我只是找到了一种方法来拥有 flex-box,导航栏的宽度,并在固定位置将其居中。

nav {
    display: flex;
    height: 50px;
    width: 90%;
    left: 5%;
    position: fixed;
}

我希望能够在固定位置设置弹性框导航栏,但 居中。所以我做的是左边的 5%,因为它等于剩下的 10% 宽度的一半。试试吧,它可能对你有帮助! :)

position:sticky 但没有代码示例。 这是一个极简主义的例子:

* {
  box-sizing: border-box;
}

body {
 display: flex;
 margin: 0;
}

nav {
 width: 20%;
 height: 100vh;
 top: 0; /* this is required for "sticky" to work */
 position: sticky;
 background: lightblue;
 padding: 1rem;
}

main {
 height: 3000px; /* cause scroll */
 background: lightpink;
 flex-grow: 1;
 padding: 1rem;
}
<body>
 <nav>
  sidebar here
 </nav>

 <main>
  content here
 </main>
</body>

你是说你想要 position:fixed;-like 行为与 flexbox 一起玩。如已接受的答案中所述,将此 属性 应用于元素会将其从正常流程中删除,因此这实际上是不可能的。

如果您想要一个固定的侧边栏 .side-el 和一个可滚动的内容框 .main-el 作为弹性容器的项目,您可以这样做:

  1. 在 flex 容器中禁用滚动 parent;让我们假设它是 <body>,因为您没有提供 div.container 的 parent。另外,hard-set 它的高度为 viewport-height (100vh),因此 body 的任何部分都没有 框保持在视图之外(想象 body 的框通常延伸 超出屏幕以包含整个文档;你不想 那,如果你要禁用移动视口的能力 滚动)。
  2. 将弹性容器的 (.container) 高度设置为其 parent。
  3. 选择性地re-enable 滚动内容框(.main-el)。

在CSS中:

body{
  overflow: hidden;
  height: 100vh;
}
.container {
  display: flex;
  height: 100%;
}
.main-el {
  overflow-y: auto;
}