弹性盒子 -- flex

弹性盒子

弹性盒子是一种用于按行或按列布局元素的一维布局方法。元素可以膨胀以填充额外的空间。也可以收缩以适应更小的空间。


为什么要用弹性盒子?

CSS 布局中我们常用的就是 float 和 position。这两个工具可以满足我们大部分的需求。但在一些情况用这两种方式就不太合适。比如

  • 在父内容里面垂直居中一个块内容。
  • 使容器的所有子项占用等量的可用宽度/高度,而不管有多少宽度/高度可用。
  • 使多列行列布局中的所有列采用相同的高度,即使它们包含的内容量不同。

这些任务利用 float 和 position 这两种方式很难解决。不过用弹性布局使得很多布局任务变得更加容易。


实践的例子

将下面的样式进行修改。

image-20221003201054925

修改后的样子。

image-20221003201154045

将对应的元素设置为 flexible。

section {
    display: flex;
}

就得到了我们想要的结果。这是因为 flex 项的默认值。

注意:假如你想设置行内元素为 flexible box,也可以置 display 属性的值为 inline-flex


flex 模型说明

当元素表现为 flex 框时,它们沿着两个轴来布局:

image-20221003201843862

  • 主轴(main axis):是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end。
  • 交叉轴(cross axis):是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
  • 设置了 display: flex 的父元素(在上面的例子中是
    )被称为 flex 容器(flex container)。
  • 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项(flex item)(本例中是
    元素。

列 or 行

弹性盒子提供了 flex-direction 这样一个属性。这个属性可以指定主轴的方向就(弹性盒子子类放置的地方)。默认值是 row 行。所以浏览器默认都是排成一排。

flex-direction: column;

这样那些元素设置为列分布,就像我们添加 css 之前的样子。可以理解为这个主轴是要把元素进行串起来。


换行

当布局的时候使用定宽和定高的时候,可能会出现问题。即处于容器中的弹性盒子子元素会溢出,破坏了布局。

img

解决办法就是:

// 在 section css 中添加。
flex-wrap: wrap;
// 在 article css 中添加。
flex: 200px;1

看看处理之后的效果:

img

这样就有了多行弹性盒子。任何溢出的元素将被移到下一行。


flex-flow 缩写

在这里 flex-directionflex-wrap 的缩写 flex-flow

flex-direction: row;
flex-wrap: wrap;
// 等价
flex-flow: row wrap;

flex 项的动态尺寸

article{
    flex: 1;
}

这是一个无单位的比例值。表示每一个 flex 项沿主轴的可用空间大小。设置为 1 这表示每个元素占用空间都是相等的。占用的空间是在设置 padding 和 margin 之后剩余的空间。

article:nth-of-type(3) {
    flex: 2;
}

这时候可以看见第一个和第二个元素各占了可用空间的 1/4 而第三个占用了可用空间的 1/2。也就是代表第三个占有两个单位。

还可以指定 flex 的最小。

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

弹性盒子的真正价值可以体现在它的灵活性/响应式,如果你调整浏览器窗口的大小,或者增加一个

元素,这时的布局仍旧是完好的。


flex:缩写于全写

flex 是一个可以指定最多三个不同值的缩写属性:

  • 第一个就是上面所讨论过的无单位比例。可以单独指定全写 flex-grow 属性的值。
  • 第二个无单位比例 flex-shrink 一般用于溢出容器的 flex 项。这指定了从每个 flex 项中取出多少溢出量,以阻止它们溢出它们的容器。这是一个相当高级的弹性盒子功能,我们不会在本文中进一步说明。
  • 第三个是上面讨论的最小值。可以单独指定全写 flex-basis 属性的值。

建议不要使用全写属性,除非你真的需要(比如要去覆盖之前写的)。使用全写会多写很多的代码。


水平和垂直水平

还可以使用弹性盒子的功能让 flex 项沿着主轴或交叉轴对齐。

一个新的例子,可以看到一个水平的菜单栏:

img

之后添加下面的 css 代码:

div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

下面是这段代码产生的效果:

image-20221003211404984

这段代码让所有的按钮很好的垂直水平居中了。这里运用了两个新的属性:

align-items 控制 flex 项在交叉轴上的位置。

  • 默认的值是 stretch,其会使所有 flex 项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。我们的第一个例子在默认情况下得到相等的高度的列的原因。
  • 在上面规则中我们使用的 center 值会使这些项保持其原有的高度,但是会在交叉轴居中。这就是那些按钮垂直居中的原因。
  • 你也可以设置诸如 flex-startflex-end 这样使 flex 项在交叉轴的开始或结束处对齐所有的值。

也可以用 align-self 属性覆盖 align-items 的行为。

button:first-child {
  align-self: flex-end;
}

justify-content 控制 flex 项在主轴上的位置。

  • 默认值是 flex-start,这会使所有 flex 项都位于主轴的开始处。
  • 你也可以用 flex-end 来让 flex 项到结尾处。
  • centerjustify-content 里也是可用的,可以让 flex 项在主轴居中。
  • 而我们上面用到的值 space-around 是很有用的——它会使所有 flex 项沿着主轴均匀地分布,在任意一端都会留有一点空间。
  • 还有一个值是 space-between,它和 space-around 非常相似,只是它不会在两端留下任何空间。

flex 项排序

弹性盒子也有可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。

代码也很简单:

button:first-child {
  order: 1;
}

这个排序的规则就是。所有的 flex 项的 order 默认值是0。之后排序的时候,order 值大的 flex 项比 order 值小的显示顺序中更靠后。

如果是负值会排到 order 值为 0 的元素前面。


flex 嵌套

弹性盒子也能创建一些颇为复杂的布局。设置一个元素为 flex 项目,那么他同样成为一个 flex 容器。它的孩子也表现为 flexible box。

img

这个例子的嵌套关系如下:

section - article
          article
          article - div - button
                    div   button
                    div   button
                          button
                          button

跨浏览器兼容性

大多数浏览器都支持 弹性盒子,诸如 Firefox, Chrome, Opera, Microsoft Edge 和 IE 11,较新版本的 Android/iOS 等等。但是你应该要意识到仍旧有被人使用的老浏览器不支持 弹性盒子(或者支持,但是只是支持非常非常老版本的 弹性盒子)。

虽然你只是在学习和实验,这不太要紧; 然而,如果您正在考虑在真实网站中使用弹性盒子,则需要进行测试,并确保在尽可能多的浏览器中您的用户体验仍然可以接受。

弹性盒子相较其他一些 CSS 特性可能更为棘手。例如,如果浏览器缺少 CSS 阴影,则该网站可能仍然可用。但是假如不支持 弹性盒子功能就会完全打破布局,使其不可用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值