Flexbox布局:同时缩小和增长

时间:2017-07-01 11:06:46

标签: html css css3 flexbox

我正在努力使用flexbox进行简单的布局。

布局:两个div。

  1. 宽度小于300px时 - 它们应叠放在一起并占据所有可用空间。
  2. 宽度超过300像素 - 它们应占宽度的50%。
  3. 如果一个div不包含任何内容 - 它不应该占用任何空间(基本上它应该被隐藏)并且剩余的div应该占用所有可用空间。
  4. 我在下面尝试过这种安排,但失败了。在这个例子中,第二个块是错误的,那么每个块应占据"一行"的50%。我尝试了其他一些变体 - 似乎都没有效果。

    
    
    .container {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-around;
    }
    
    .div1, .div2 {
      flex-grow: 1;
      flex-shrink: 1;
      flex-basis: 50%;
    }
    
    .div1 {
      background-color: red;
    }
    
    .div2 {
      background-color: green;
    }
    
    <div class="container" style="width: 250px;">
      <div class='div1'>
        "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."
      </div>
    
      <div class='div2'>
        "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."
      </div>
    </div>
    
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
        "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."
      </div>
    
      <div class='div2'>
        "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."
      </div>
    </div>
    
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
      </div>
    
      <div class='div2'>
        "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."
      </div>
    </div>
    &#13;
    &#13;
    &#13;

2 个答案:

答案 0 :(得分:3)

this answer由@LGSon提供了解决此问题的好方法。

正如答案所指出的,关键是要给每个项目flex-grow: 1

以下是其工作原理:

这些是问题的要求:

  1. 两个弹性项目
  2. 在小屏幕上,它们应该叠加成一列
  3. 在大屏幕上,它们应该连续排成50/50
  4. 如果一个项目没有内容,则它应该不占用空间,而另一个项目应占用所有空间
  5. flex: 1 1 50%

    这是问题中尝试的解决方案:

    .div1, .div2 {
       flex-grow: 1;
       flex-shrink: 1;
       flex-basis: 50%;
    }
    

    此代码不起作用,因为它不符合要求#4。 Flex项目将平均分享可用空间(flex-grow: 1), 后,它们的大小均为50%宽度(flex-basis: 50%)。

    由于当两个项目为50/50时没有剩余可用空间,flex-grow无效,且无论内容如何,​​项目总是50/50。

    请注意,在flex-basisflex-grow分配任何可用空间之前,首先呈现flex-shrink属性per spec guidelines

    &#13;
    &#13;
    .container {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-around;
    }
    
    .div1,
    .div2 {
      flex-grow: 1;
      flex-shrink: 1;
      flex-basis: 50%;
    }
    
    .div1 {
      background-color: red;
    }
    
    .div2 {
      background-color: green;
    }
    &#13;
    <div class="container" style="width: 250px;">
      <div class='div1'>
        "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."
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
        "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."
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    &#13;
    &#13;
    &#13;

    flex: 1

    使用flex: 1也不会有效。这相当于:

    • flex-grow: 1
    • flex-shrink: 1
    • flex-basis: 0

    由于弹性项目的初始大小为flex-basis: 0,因此所有容器空间均匀分布。同样,这违反了要求#4,因为两个项目都是50/50,无论内容如何。

    &#13;
    &#13;
    .container {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-around;
    }
    
    .div1,
    .div2 {
      flex: 1;
    }
    
    .div1 {
      background-color: red;
    }
    
    .div2 {
      background-color: green;
    }
    &#13;
    <div class="container" style="width: 250px;">
      <div class='div1'>
        "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."
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
        "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."
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    &#13;
    &#13;
    &#13;

    flex: auto

    这是唯一有效的解决方案。它分解为:

    • flex-grow: 1
    • flex-shrink: 1
    • flex-basis: auto

    这基本上说:

    • 每个弹性项目的初始大小是内容的大小。
    • 确定该尺寸后,flex-grow可以输入图片以分配剩余空间。

    由于没有内容的项目的初始大小为零,这允许第二项占据该行的所有空间。

    我引用的答案使用flex-grow: 1代替flex: auto。这具有相同的效果,因为flex-shrink: 1flex-basis: auto是默认值。

    &#13;
    &#13;
    .container {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-around;
    }
    
    .div1,
    .div2 {
      flex: auto;
    }
    
    .div1 {
      background-color: red;
    }
    
    .div2 {
      background-color: green;
    }
    &#13;
    <div class="container" style="width: 250px;">
      <div class='div1'>
        "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."
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
        "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."
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    <hr/>
    <div class="container" style="width: 1000px;">
      <div class='div1'>
      </div>
      <div class='div2'>
        "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."
      </div>
    </div>
    &#13;
    &#13;
    &#13;

    更多信息

答案 1 :(得分:2)

我简化了你的CSS。

  1. container设置为display: flex(并移除flex-wrap: wrap;,否则它们不会并排放在更宽的屏幕上)

  2. 设置flex-grow: 1,根据每个项目内容留出相等的空格

  3. 添加一个媒体查询,当我按照请求的宽度触发时,我使用600px(2倍300px),将flex-direction更改为column,这将使它们成为垂直堆栈。< / p>

  4. Stack snippet

    .container {
      display: flex;
    }
    
    .div1, .div2 {
      flex-grow: 1;
    }
    .div1 {
      background-color: red;
    }
    .div2 {
      background-color: green;
    }
    
    @media (max-width: 600px) {
      .container {
        flex-direction: column;
      }
    }
    <div class="container">
      <div class='div1'>
        "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."
      </div>
    
      <div class='div2'>
        "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."
      </div>
    </div>
    
    <hr/>
    <div class="container">
      <div class='div1'>
      </div>
    
      <div class='div2'>
        "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."
      </div>
    </div>

    更新

    如果2个弹性项目(div1 / div2)中的任何一个都有较少量的内容,并且您仍希望它们的宽度相等,请将flex-grow: 1更改为flex-basis: 100%

    这样做,他们现在总是占用宽度的100%,但由于它们无法换行,flex-shrink属性将起作用,默认为1,并且相同flex-grow,但会平等地缩小项目。

    由于这也会使为空 div采用相同的宽度,我们需要解决这个问题,我们可以轻松地使用此规则,:empty { {1}}的大小将为div

    0%

    Stack snippet

    .div1:empty, .div2:empty {
      flex-basis: 0%;
    }
    
    .container {
      display: flex;
    }
    
    .div1, .div2 {
      flex-basis: 100%;
    }
    .div1:empty, .div2:empty {
      flex-basis: 0%;
    }
    
    .div1 {
      background-color: red;
    }
    .div2 {
      background-color: green;
    }
    
    @media (max-width: 400px) {
      .container {
        flex-direction: column;
      }
    }

    根据评论更新

    可以将<div class="container"> <div class='div1'> "Lorem ipsum dolor sit amet." </div> <div class='div2'> "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." </div> </div> <hr/> <div class="container"> <div class='div1'></div> <div class='div2'> "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." </div> </div>flex-wrapmin-widthflex-grow结合使用,而不是使用媒体查询。

    这样的工作就是这样,flex-basis是他们的起始值,flex-basis: 50%让他们在断线后占用所有可用空间,而flex-grow: 1确保他们在父母的时候断线宽度小于min-width值的2倍。

    对于 min-width,我们现在需要div

    Fiddle demo

    Stack snippet

    display: none
    .container {
      display: flex;
      flex-wrap: wrap;
    }
    
    .div1, .div2 {
      flex-grow: 1;
      flex-basis: 50%;
      min-width: 150px;  
    }
    .div1:empty, .div2:empty {
      display: none;
    }
    
    .div1 {
      background-color: red;
    }
    .div2 {
      background-color: green;
    }