在flex容器中垂直排列的flex项目的宽度控制

20

我想要实现的效果是,“HALF”标签的盒子只占据50%的宽度(也就是它们均匀地共享第一行)。

基本要求是它们必须保持在单个容器中。使用 flexbox 可以实现这个目标吗?

我已经尝试过调整 flex-growflex-shrinkflex-basis,但我担心我不理解如何使其工作,或者是否可以在单个容器要求的情况下实现该功能。

请参考此代码片段:http://jsfiddle.net/GyXxT/270/

div {
  border: 1px solid;
}

.container {
  width: 400px;
  display: flex;
  flex-direction: column;
}
.child {
  
  height: 200px;
}
.child.half {
  flex: 1 1 10em;
  color: green;
}

.child:not(.half) {

  flex-shrink: 2;
  flex-basis: 50%;
  color: purple; 
}
<div class="container">
  <div class="child half">
    HALF
  </div>
  
  <div class="child half">
    HALF
  </div>
  
   <div class="child">
    FULL
  </div>
   <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
   <div class="child">
    FULL
  </div>
</div>

4个回答

22

不要使用flex-direction: column,你可以尝试使用flex-wrap: wrap进行换行的弹性盒子,然后可以设置:

  1. 半宽度的div元素使用flex-basis: 50%

  2. 全宽度的div元素使用flex-basis: 100%

注意,在使用flex-basis时,需要添加box-sizing: border-box来调整宽度。

以下是演示:

div {
  border: 1px solid;
  box-sizing: border-box;
}
.container {
  width: 400px;
  display: flex;
  flex-wrap: wrap;
}
.child {
  height: 200px;
}
.child.half {
  flex-basis: 50%;
  color: green;
}
.child:not(.half) {
  flex-basis: 100%;
  color: purple;
}
<div class="container">
  <div class="child half">
    HALF
  </div>

  <div class="child half">
    HALF
  </div>

  <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
</div>


1
有一种更简单的方法,虽然只适用于Firefox和Chrome:在子元素上添加以下属性将限制它们的大小以适应其内容: width: -moz-max-contentwidth: max-content - ojathelonius

8
弹性尺寸属性——flex-growflex-shrinkflex-basisflex——仅在弹性容器的主轴上起作用。由于您的容器为flex-direction: column,所以主轴是垂直的,这些属性控制的是高度,而不是宽度。要在列方向容器中水平调整弹性项的大小,需要使用width属性。(这里有一个更详细的解释:flex-basis和width之间有什么区别?)要通过单个容器实现您的布局,请参见本问题的另一个答案。如果您想保持列方向,则需要将.half元素包装在它们自己的容器中。

.container {
  display: flex;
  flex-direction: column;
  width: 400px;
}
.container > div:first-child {
  display: flex;
}
.child.half {
  flex: 1 1 10em;
  color: green;
  width: 50%;
}
.child {
  height: 200px;
  width: 100%;
  border: 1px solid;
}
* {
  box-sizing: border-box;
}
<div class="container">
  <div><!-- nested flex container for half elements -->
    <div class="child half">HALF</div>
    <div class="child half">HALF</div>
  </div>
  <div class="child">FULL</div>
  <div class="child">FULL</div>
  <div class="child">FULL</div>
  <div class="child">FULL</div>
</div>


1
这个看起来比被接受的答案更合理。 - undefined

3

基本要求是它们必须保留在单个容器中。

这也可以通过简单地浮动这两个half元素而不使用flexbox来实现。

div {
  border: 1px solid;
  box-sizing: border-box;
}
.container {
  width: 400px;
}
.child {
  height: 200px;
}
.child.half {
  float: left;
  width: 50%;
  color: green;
}
.child:not(.half) {
  width: 100%;
  color: purple; 
}
<div class="container">
  <div class="child half">
    HALF
  </div> 
  <div class="child half">
    HALF
  </div>
  
   <div class="child">
    FULL
  </div>
   <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
   <div class="child">
    FULL
  </div>
</div>


虽然这是真的,而且我完全忽略了它,但弹性盒子方法更接近所需的效果。使用50%的宽度,当屏幕变小时,有些情况下50%太小了。弹性盒子方法只需在第二个项目不适合时将其放下,这就是我想要的效果。您的方法可以使用媒体查询响应式,但弹性盒已经足够了。谢谢,点赞。 - parliament
当然,谢谢...注意,通过给“half”元素设置最小宽度也可以实现相同的效果...并且结合媒体查询,这两种解决方案都需要,当包装时,您可以使它们全部占满宽度。 - Asons

1
如果目的是在CSS单位或百分比中硬编码大小,则@kukkuz的解决方案已经很好了。如果您想根据元素自身的内容调整其宽度,则align-tems:flex-start或类似方法可以完成任务。可以处理与Flex布局本身垂直的维度。请参见doc页面底部的测试器。(旧问题,但以前的答案不完整,有些误导人)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接