怎么才能有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">></span>
<span ng-hide="collapsed"><</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:scroll
和 height: 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
代替。
这是有效的,因为当你给一个元素一个固定的位置并且 left
和 right
为 0 或 top
和 bottom
为 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
作为弹性容器的项目,您可以这样做:
- 在 flex 容器中禁用滚动 parent;让我们假设它是
<body>
,因为您没有提供 div.container 的 parent。另外,hard-set
它的高度为 viewport-height (100vh),因此 body 的任何部分都没有
框保持在视图之外(想象 body 的框通常延伸
超出屏幕以包含整个文档;你不想
那,如果你要禁用移动视口的能力
滚动)。
- 将弹性容器的 (
.container
) 高度设置为其 parent。
- 选择性地re-enable 滚动内容框(
.main-el
)。
在CSS中:
body{
overflow: hidden;
height: 100vh;
}
.container {
display: flex;
height: 100%;
}
.main-el {
overflow-y: auto;
}
我有一个名为 .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">></span>
<span ng-hide="collapsed"><</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:scroll
和 height: 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
代替。
这是有效的,因为当你给一个元素一个固定的位置并且 left
和 right
为 0 或 top
和 bottom
为 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
作为弹性容器的项目,您可以这样做:
- 在 flex 容器中禁用滚动 parent;让我们假设它是
<body>
,因为您没有提供 div.container 的 parent。另外,hard-set 它的高度为 viewport-height (100vh),因此 body 的任何部分都没有 框保持在视图之外(想象 body 的框通常延伸 超出屏幕以包含整个文档;你不想 那,如果你要禁用移动视口的能力 滚动)。 - 将弹性容器的 (
.container
) 高度设置为其 parent。 - 选择性地re-enable 滚动内容框(
.main-el
)。
在CSS中:
body{
overflow: hidden;
height: 100vh;
}
.container {
display: flex;
height: 100%;
}
.main-el {
overflow-y: auto;
}