Flex弹性盒子布局(display: flex)

简介

我们经常听说一种布局:Flexbox或者是弹性布局,它的全称叫做弹性盒子布局(Flexible Box Layout),那么它到底该如何实现呢?从我们熟悉的 display 属性开始,给元素添加 display: flex,该元素变成了一个弹性容器(flex container),它的直接子元素变成了弹性子元素(flex item),那么最简单的弹性盒子布局就完成了,它具有以下的效果:

1、弹性容器像块元素一样填满可用宽度(注意,这里只是弹性容器,即添加了display: flex的元素),高度由自身内容决定,但是弹性子元素不一定填满其弹性容器的宽度。
2、弹性子元素默认是在同一行按照从左到右的顺序并排排列。
3、弹性子元素高度相等,该高度由它们的内容决定。

当然,我们可以手动的设置它们的宽高,但是在Flexbox布局中,弹性是其最突出的属性,所有一般我们不建议这样做。在大致了解了它最显著的作用之后,下面我们来进行细致深入的学习。

基础概念

Flexbox布局中,有两根重要的轴线——主轴&副轴,其属性几乎都是围绕着这两根轴线来描述的。默认情况下,主轴是水平的,它的起点为最左侧,终点为最右侧,对应的,有一根与之垂直相交的副轴,它的起点是最上侧,终点是最下侧。当然,这些方向可以改变,我们稍后介绍。


image.png

相关属性

1、flex-direction 作用:决定主轴的方向(弹性子元素的排列方向)

row(默认值):水平,起始在左端
row-reverse:水平,起始在右端
column:竖直,起始在上沿
column-reverse:竖直,起始在下沿
image.png
2、flex-wrap 作用:决定直接子元素是否换行以及如何换行

nowrap(默认):不换行
wrap:换行,第一行在上方
wrap-reverse:换行,第一行在下方
image.png
3、flex-flow
作用:前面两个属性的简写,默认值为 row nowrap
4、justify-content 作用:决定弹性子元素在主轴上的对齐方式

flex-start(默认值):左对齐
flex-end:右对齐
center:居中
space-between:两端对齐,弹性子元素之间的间隔相等
space-around:弹性子元素两侧的间隔相等,相邻之间的间隔会叠加

image.png
5、align-content 作用:决定多行/列弹性子元素在交叉轴上的的对齐方式 (前提是要开启flex-wrap)

stretch(默认值):每行元素将会被拉伸,直至撑满整个交叉轴,每行/列之间的间隔相等
flex-start:与交叉轴起点对齐
flex-end:与交叉轴终点对齐
center:在交叉轴上居中对齐
space-between:与交叉轴两端对齐,弹性子元素之间的间距相等
space-around:弹性子元素两侧的间隔相等,相邻之间的间隔会叠加

image.png
6、flex-items 作用:决定单行/列弹性子元素在交叉轴上的对齐方式

stretch(默认值):如果没有设置高度/高度设置为auto,那么将撑满整个盒子
flex-start、flex-end、center属性值的效果同上
baseline:项目的第一行文字的基线对齐(效果如下,紫色是盒子)

image.png
7、flex-basis 作用:指定子元素未受flex-grow或flex-shrink影响时的初始大小
取值:<length>或<percent>,初始值是auto(此时会检查元素是否设置了width属性。如果有,则使用 width 的值作为 flex-basis 的值;如果没有,则用元素内容自身的大小。如果 flex-basis 的值不是 auto,width 属性会被忽略)

8、flex-grow 作用:每个弹性子元素的 flex-basis 值计算出来后,它们(加上子元素之间的外边距)加起来会占据一定的宽度。加起来的宽度不一定正好填满弹性容器的宽度,可能会有留白。多出来的留白(或剩余宽度)会按照 flex-grow(增长因子)的值分配给每个弹性子元素。
取值:非负,初始值是0(此时元素的宽度不会超过flex-basis的宽度,不参与分配)
示例:flex-grow 的值越大,元素的“权重”越高,也就会占据更大的剩余宽度。一个 flex-grow: 2 的子元素增长的宽度为 flex-grow: 1 的子元素的两倍,如下图
image.png
9、lex-shrink 作用: flex-shrink 属性与 flex-grow 遵循相似的原则。计算出弹性子元素的初始主尺寸后,它们的累加值可能会超出弹性容器的可用宽度。如果不用 flex-shrink,就会导致溢出,每个子元素的 flex-shrink 值代表了它是否应该收缩以及相应的收缩比例以防止溢出。(在开启了flex-wrap之后会忽略此属性)
取值:非负,初始值为1(为 0 时,不会缩小)

效果:

如果元素A的flex-shrink为0,而其他的元素都为0,那么A不会缩小
如果元素A的flex-shrink为2,元素B的flex-shrink为1,那么A的缩小的部分的长度是B的缩小部分的长度的2倍

image.png

示例:如下图:


image.png
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>flex-shrink缩放</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }

    body {
      padding: 1em;
    }

    #content {
      display: flex;
      width: 500px;
    }

    #content div {
      flex-basis: 120px;
      border: 3px solid rgba(0, 0, 0, 0.2);
    }

    .box {
      flex-shrink: 2;
    }

    .box1 {
      flex-shrink: 1;
    }

    .result {
      margin-top: 20px;
    }

    p {
      line-height: 1.5em;
    }
  </style>
</head>

<body>
  <p>容器宽度为 500px, 弹性子元素的flex-basic 是120px</p>
  <p>A, B, C 设置 flex-shrink:2, D 和 E 设置 flex-shrink:1</p>
  <p>根据js打印输出可知,A、B、C缩小的长度是D、E缩小长度的2倍</p>
  <div id="content">
    <div class="box" id="A" style="background-color:red;">A</div>
    <div class="box" style="background-color:lightblue;">B</div>
    <div class="box" style="background-color:yellow;">C</div>
    <div class="box1" id="D" style="background-color:brown;">D</div>
    <div class="box1" style="background-color:lightgreen;">E</div>
  </div>

  <div class="result"></div>
  <script>
    const A = document.getElementById("A");
    const A_width = getComputedStyle(A).width;
    const D = document.getElementById("D");
    const D_width = getComputedStyle(D).width;
    const content = document.getElementById("content");
    const content_width = getComputedStyle(content).width;
    const result = document.querySelector(".result");
    result.innerHTML = `A, B, C 缩放之后的长度是${A_width},<br />
    E缩放之后的长度是${D_width}, <br />
    容器宽度是${content_width}`
  </script>

</body>

</html>

10、flex 作用:flex-grow、flex-shrink、flex-basis三个属性的简写
取值:

单值语法:值必须是以下之一:
一个 <flex-grow> 的有效值:此时简写会扩展为 flex: <flex-grow> 1 0。
一个<flex-basis>的有效值:此时简写会扩展为 flex: 1 1 <flex-basis>。
关键字 none 或者全局关键字(见后面)之一。
双值语法:
第一个值必须是一个 flex-grow 的有效值。
第二个值必须是以下之一:
一个 flex-shrink的有效值:此时简写会扩展为 flex: <flex-grow> <flex-shrink> 0。
一个 flex-basis 的有效值:此时简写会扩展为 flex: <flex-grow> 1 <flex-basis>。
三值语法:值必须按照以下顺序指定:
一个 flex-grow 的有效值。
一个 flex-shrink 的有效值。
一个 flex-basis 的有效值。

全局关键字

全局关键字:

initial
元素会根据自身宽高设置尺寸。它会缩短自身以适应 flex 容器,但不会伸长并吸收 flex 容器中的额外自由空间来适应 flex 容器。相当于将属性设置为"flex: 0 1 auto"。

auto
元素会根据自身的宽度与高度来确定尺寸,但是会伸长并吸收 flex 容器中额外的自由空间,也会缩短自身来适应 flex 容器。这相当于将属性设置为 “flex: 1 1 auto”.

none
元素会根据自身宽高来设置尺寸。它是完全非弹性的:既不会缩短,也不会伸长来适应 flex 容器。相当于将属性设置为"flex: 0 0 auto"。

flex属性与以往的简写属性不同,推荐使用简写形式,因为这样可以尽可能避免多次分开书写导致的布局不一致,并且可以提高对浏览器的兼容性。

<'flex-grow'>
定义 flex 项目的 flex-grow 。负值无效。省略时默认值为 1。 (初始值为 0)

<'flex-shrink'>
定义 flex 元素的 flex-shrink 。负值无效。省略时默认值为1。 (初始值为 1)

<'flex-basis'>
定义 flex 元素的 flex-basis 属性。若值为0,则必须加上单位,以免被视作伸缩性。省略时默认值为 0。(初始值为 auto)

采用逻辑推断的方法,初始值肯定会从安全性的角度考虑,所以,元素尽量不要随意放大,所以flex-grow属性初始为0;容器会尽量容纳下所有的元素,所以flex-shrink属性初始值为1;为了以元素自身为主导,flex-basis初始值为auto。而所谓的默认值,是在flex简写的写法中被省略时补充的值,以上规则能够体现出来。

11、order 作用:将弹性子元素从兄弟节点中移动到指定位置,覆盖源码顺序,值越小,位置越靠前
取值:整数,初始值是0
注意:慎重使用,因为视觉布局与源码顺序差别太大会影响网站的可访问性。在大多数浏览器里使用 Tab 键浏览元素的顺序与源码保持一致,如果视觉上差别太大就会令人困惑。视力受损的用户使用的大部分屏幕阅读器也是根据源码的顺序来的。
12、align-self 作用:跟弹性容器的 align-items 属性效果相同,但是它能单独给弹性子元素设定不同的对齐方式。
取值与效果:auto 为初始值,会以容器的 align-items 值为准。其他值会覆盖容器的设置。align-self属性支持的关键字与 align-items 一样:flex-start、flex-end、center、stretch 以及 baseline。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容