使用 Flexbox,让元素拉伸以填充行之间的间隙 [英] Using Flexbox, have elements stretch to fill gap between rows

查看:17
本文介绍了使用 Flexbox,让元素拉伸以填充行之间的间隙的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得这个问题有点傻,但我对 Flexbox 的知识有点用完了,所以我希望也许其他人可以进来帮助我.

我的总体目标是让中间行中的两个项目伸展以填充标题和项目之间的空间,我四处搜索,老实说无法弄清楚我应该做什么.我从 CSS Tricks Guide 分叉了代码,在最底部,我做了一些改动.我目前拥有的代码是(以全屏模式打开它以使其更清晰):

body,html {高度:100%;}.包装{显示:-webkit-box;显示:-moz-box;显示:-ms-flexbox;显示:-webkit-flex;显示:弹性;justify-content: flex-start;-webkit-flex-flow:行换行;flex-flow:行包装;高度:100%;字体粗细:粗体;文本对齐:居中;}.wrapper >* {填充:10px;弹性:1 1 100%;}.header {背景:番茄;高度:50px;弹性:1 1 100%;}.页脚{背景:浅绿色;高度:50px;}.主要的 {文本对齐:左;对齐自我:伸展;背景:深蓝;}.aside-1 {背景:黄金;}.aside-2 {背景:hotpink;}@media all 和(最小宽度:600px){.在旁边 {弹性:1 自动;}}@media all and (min-width: 800px) {.主要的 {弹性:3 0px;}.aside-1 {订单:1;}.主要的 {订单:2;}.aside-2 {订单:3;}.页脚{订单:4;}}身体 {填充:2em;}

<header class="header">Header</header><文章类=主要"><p>Pellentesque 居民 morbi tristique senectus et netus etmalesuada Fames ac turpis egestas.Vestibulum tortor quam、feugiat vitae、ultricies eget、tempor sat amet、ante.Donec eu libero 坐 amet quam egestas semper.Aenean ultricies mi vitae est.Mauris placerat eleifend leo.</p></文章><aside class="asideside-1">Aside 1</aside><footer class="footer">Footer</footer>

是否可以在 flexbox 中在不更改 HTML 的情况下实现此目标,或者我应该寻找另一种方法来实现此目标?

解决方案

虽然人们告诉您如何解决问题,但他们并没有告诉您为什么没有得到预期的结果.我认为部分原因是他们中的大多数人都错过了实际问题.我觉得这很有趣.

让我先解决一些问题:

Flex-direction::出于实际目的,它表示项目显示的方向.但是它不准确.

现在假设如果方向设置为行,则意味着每个项目必须具有容器的高度,并且它们应该彼此相邻放置.换句话说,容器必须被视为一行,而项目是列.

.c{显示:弹性;宽度:400px;高度:100px;}.c1{弹性增长:1;背景:金色;}.c2{弹性增长:1;背景:红色;}

<div class="c1"></div><div class="c2"></div>

我没有指定高度,项目填充了行的高度并像列一样相互堆叠.

<小时>

当您指定高度时,项目将采用您定义的高度,但不会改变行的高度:

.c{显示:弹性;宽度:400px;高度:100px;}.c1{弹性增长:1;高度:40px;背景:金色;}.c2{弹性增长:1;背景:红色;}

<div class="c1"></div><div class="c2"></div>

红色立方体仍然产生垂直空间,因为行的高度没有改变.

<小时>

弹性增长:分配给不同项目的可用空间量.

.c{显示:弹性;宽度:400px;}.c1{弹性增长:1;背景:金色;}.c2{弹性增长:1;背景:红色;}

 

<div class="c1">AAAAAAAAAAAAA</div><div class="c2"></div>

尽管具有相同的 flex-grow 值,但这两个项目的大小并不相同,这是因为自由空间分布在它们之间,但黄色矩形开始时更大.

<小时>

首先让我们使用 flex-wrap : wrap:

.c{显示:弹性;flex-wrap: 包裹;边框:1px纯黑色;宽度:400px;高度:100px;}.c1{宽度:200px;背景:金色;}.c2{宽度:200px;背景:红色;}.c3{宽度:100px;背景:橙色;}.c4{宽度:300px;背景:绿色;}

<div class="c1"></div><div class="c2"></div><div class="c3"></div><div class="c4"></div>

正如我们所看到的,当我们超出项目开始时的可用宽度量时,有效地创建了另一行.

<小时>

现在解决您的问题:

如果我们采用上面的例子并设置第一项的高度会怎样?让我们看看:

 .c{显示:弹性;flex-wrap: 包裹;边框:1px纯黑色;宽度:400px;高度:100px;}.c1{宽度:200px;高度:30px;背景:金色;}.c2{宽度:200px;背景:红色;}.c3{宽度:200px;背景:橙色;}.c4{宽度:200px;背景:绿色;}

<div class="c1"></div><div class="c2"></div><div class="c3"></div><div class="c4"></div>

喜欢你的片段.

再看一个例子:

 .c{显示:弹性;flex-wrap: 包裹;边框:1px纯黑色;宽度:600px;高度:100px;}.c1{宽度:400px;高度:35px;背景:金色;}.c2{宽度:200px;背景:红色;}.c3{宽度:200px;背景:橙色;}.c4{宽度:200px;背景:绿色;}.c5{宽度:200px;背景:紫色;}

 

<div class="c1"></div><div class="c2"></div><div class="c3"></div><div class="c4"></div><div class="c5"></div>

  1. 放置 400px X 35px 的黄色立方体并跨越 2 列,然后放置 200px 的红色立方体并跨越 1 列.

  2. 此时,除了第一个矩形的高度为 35px 之外,所有矩形的高度均为 0.

  3. 剩余的垂直空间在行之间划分以产生整个垂直空间.因此剩余的垂直空间为 100-35 = 65px.分为 2 行 = 32.5.第一行得到 35 + 32.5,第二行得到 32.5px 高度.

另一个让事情更清楚的例子:

 .c, .d{显示:弹性;flex-wrap: 包裹;边框:1px纯黑色;宽度:600px;高度:100px;}.c1{弹性收缩:0;宽度:400px;高度:0px;背景:金色;}.c2{宽度:200px;背景:红色;}.c3{宽度:200px;背景:橙色;}.c4{宽度:200px;背景:绿色;}.c5{宽度:200px;背景:紫色;}.d1{宽度:400px;高度:50px;背景:金色;}.d2{宽度:200px;背景:红色;}.d3{宽度:200px;背景:橙色;}.d4{宽度:200px;背景:绿色;}.d5{宽度:200px;背景:紫色;}

第一项的高度为 0px,剩余的垂直空间 (100px) 分为 2 行.两行都有 50px 的高度<div class="c"><div class="c1"></div><div class="c2"></div><div class="c3"></div><div class="c4"></div><div class="c5"></div>

第一个项目有 35px 的高度,剩余的垂直空间 (65px) 被分成 2 行.<div class="d"><div class="d1"></div><div class="d2"></div><div class="d3"></div><div class="d4"></div><div class="d5"></div>

要解决此问题,您可以使用 calc() 像其他人建议的那样计算其他行高.原因是没有更多的空闲垂直空间可供共享.

 .c{显示:弹性;flex-wrap: 包裹;边框:1px纯黑色;宽度:600px;高度:100px;}.c1{宽度:400px;高度:35px;背景:金色;}.c2{宽度:200px;背景:红色;}.c3{高度:计算(100% - 35px);宽度:600px;背景:绿色;}

 

<div class="c1"></div><div class="c2"></div><div class="c3"></div>

I feel a little silly asking this, but I've sort of exhausted my knowledge of Flexboxes, so I'm hoping maybe someone else can come in and help me out here.

My overall goal is to just have the two items in the middle row stretch to fill the space between the header and the items, and I have searched around and honestly can't figure out what it is that I should do. I forked the code from the CSS Tricks Guide, the one at the very bottom, and I've made some alterations. The code I currently have is (open it in full screen mode to make it more clear):

body,
html {
  height: 100%;
}
.wrapper {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  justify-content: flex-start;
  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;
  height: 100%;
  font-weight: bold;
  text-align: center;
}
.wrapper > * {
  padding: 10px;
  flex: 1 1 100%;
}
.header {
  background: tomato;
  height: 50px;
  flex: 1 1 100%;
}
.footer {
  background: lightgreen;
  height: 50px;
}
.main {
  text-align: left;
  align-self: stretch;
  background: deepskyblue;
}
.aside-1 {
  background: gold;
}
.aside-2 {
  background: hotpink;
}
@media all and (min-width: 600px) {
  .aside {
    flex: 1 auto;
  }
}
@media all and (min-width: 800px) {
  .main {
    flex: 3 0px;
  }
  .aside-1 {
    order: 1;
  }
  .main {
    order: 2;
  }
  .aside-2 {
    order: 3;
  }
  .footer {
    order: 4;
  }
}
body {
  padding: 2em;
}

<div class="wrapper">
  <header class="header">Header</header>
  <article class="main">
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
      Mauris placerat eleifend leo.</p>
  </article>
  <aside class="aside aside-1">Aside 1</aside>

  <footer class="footer">Footer</footer>
</div>

Is it possible in flexbox to achieve this without changing the HTML, or should I just look for another way to accomplish this goal?

解决方案

While people are telling you how to resolve the issue, they are not telling you why you don't have the result you expected. I think it's partly because most of them missed the actual question. Which I found really interesting.

Let me get some things out of the way first :

Flex-direction:: For practical purpose it means the direction in which the items are displayed. However it's not accurate.

For now let's say that if the direction is set to row, it means that each item must have the height of the container and they should be put next to each other. In other words the container has to be considered a row and the item are the columns.

.c{
  display: flex;
  width: 400px;
  height:100px;
}
.c1{
  flex-grow: 1;
  background:gold;

}
.c2{
  flex-grow: 1;
  background:red;
}

<div class="c">
    <div class="c1"></div>
    <div class="c2"></div>
</div>

I didn't specify an height, the items filled the height of the row and stacked against each others like columns.


When you specify an height the item will take the height you defined but that does not change the height of the row :

.c{
  display: flex;
  width: 400px;
  height: 100px;
}
.c1{
  flex-grow: 1;
  height: 40px;
  background:gold;

}
.c2{
  flex-grow: 1;
  background:red;
}

<div class="c">
    <div class="c1"></div>
    <div class="c2"></div>
</div>

The red cube still spawn the vertical space because the height of the row hasn't changed.


flex grow: the amount of free space distributed to the different items.

.c{
    display: flex;
    width: 400px;
  }

.c1{
  flex-grow: 1;
  background:gold;
  }

.c2{
  flex-grow: 1;
  background:red;
  }

    <div class="c">
        <div class="c1">AAAAAAAAAAAAA</div>
        <div class="c2"></div>
    </div>

Despite having the same flex-grow value, those two items aren't the same size, that is because the free space is distributed among them but the yellow rectangle was bigger to begin with.


First let's use flex-wrap : wrap:

.c{
  display: flex;
  flex-wrap: wrap;
  border: 1px solid black;
  width: 400px;
  height:100px;
}
.c1{
  width:200px;
  background:gold;

}
.c2{
  width:200px;
  background:red;
}

.c3{
  width:100px;
  background:orange;

}
.c4{
  width:300px;
  background:green;
}

<div class="c">
    <div class="c1"></div>
    <div class="c2"></div>
    <div class="c3"></div>
    <div class="c4"></div>
</div>

As we can see when we go beyond the amount of width available the items start under, effectively creating another row.


Now to address your question:

What if we took the example above and set the height of the first item ? Let's see:

    .c{
      display: flex;
      flex-wrap: wrap;
      border: 1px solid black;
      width: 400px;
      height:100px;
    }
    .c1{
      width:200px;
      height: 30px;
      background:gold;

    }
    .c2{
      width:200px;
      background:red;
    }

    .c3{
      width:200px;
      background:orange;

    }
    .c4{
      width:200px;
      background:green;
    }

<div class="c">
  <div class="c1"></div>
  <div class="c2"></div>
  <div class="c3"></div>
  <div class="c4"></div>
</div>

Like in your snippet.

Let's see another example:

        .c{
          display: flex;
          flex-wrap: wrap;
          border: 1px solid black;
          width: 600px;
          height:100px;
        }
        .c1{
          width:400px;
          height: 35px;
          background:gold;

        }
        .c2{
          width:200px;
          background:red;
        }

        .c3{
          width:200px;
          background:orange;

        }
        .c4{
          width:200px;
          background:green;
        }
        .c5{
          width:200px;
          background:purple;
        }

    <div class="c">
      <div class="c1"></div>
      <div class="c2"></div>
      <div class="c3"></div>
      <div class="c4"></div>
      <div class="c5"></div>
    </div>

  1. yellow cube of 400px X 35px is put and spans 2 columns, then red cube of 200px is put and spans 1 column.

  2. At this point all the rectangles have 0 height except the first one which has 35px.

  3. The remaining vertical space is divided between the rows as to spawn the whole vertical space. Thus the remaining vertical space is 100-35 = 65px. divided in 2 rows = 32.5. The first row gets 35 + 32.5 and the second row gets 32.5px height.

Another example to make things clearer:

    .c, .d{
              display: flex;
              flex-wrap: wrap;
              border: 1px solid black;
              width: 600px;
              height:100px;
            }

            .c1{
              flex-shrink: 0;
              width:400px;
              height: 0px;
              background:gold;

            }
            .c2{
              width:200px;
              background:red;
            }

            .c3{
              width:200px;
              background:orange;

            }
            .c4{
              width:200px;
              background:green;
            }
            .c5{
              width:200px;
              background:purple;
            }


            .d1{
              width:400px;
              height: 50px;
              background:gold;

            }
            .d2{
              width:200px;
              background:red;
            }

            .d3{
              width:200px;
              background:orange;

            }
            .d4{
              width:200px;
              background:green;
            }
            .d5{
              width:200px;
              background:purple;
            }

First item has 0px height, the vertical space remaining (100px) is divided between the 2 rows. Both row have 50px height
        <div class="c">
          <div class="c1"></div>
          <div class="c2"></div>
          <div class="c3"></div>
          <div class="c4"></div>
          <div class="c5"></div>
        </div>

First item has 35px height, the vertical space remaining (65px) is divided between the 2 rows.
        <div class="d">
          <div class="d1"></div>
          <div class="d2"></div>
          <div class="d3"></div>
          <div class="d4"></div>
          <div class="d5"></div>
        </div>

To resolve this you can use calc() to calculate the other rows height like others suggested. The reason is that there is no more free vertical space to be shared.

            .c{
              display: flex;
              flex-wrap: wrap;
              border: 1px solid black;
              width: 600px;
              height:100px;
            }
            .c1{
              width:400px;
              height: 35px;
              background:gold;

            }
            .c2{
              width:200px;
              background:red;
            }

            .c3{
              height:calc(100% - 35px);
              width:600px;
              background:green;

            }
            
            

        <div class="c">
          <div class="c1"></div>
          <div class="c2"></div>
          <div class="c3"></div>
        </div>

这篇关于使用 Flexbox,让元素拉伸以填充行之间的间隙的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆