12_CSS Flex布局

111 阅读6分钟

CSS Flex布局

长久以来,CSS 布局中唯一可靠且跨浏览器兼容的布局工具只有 float 和 position

但是这两种方法本身存在很大的局限性,所以flex是真正意义上的css的第一个布局方案

flex 布局(Flexible 布局,弹性布局,Flexbox布局)是一种用于按行或按列布局元素的一维布局方法

弹性布局内的元素可以膨胀以填充额外的空间, 可以收缩以适应更小的空间

通常我们使用Flexbox来进行布局的方案称之为flex布局(flex layout)

基本概念

flex container 和 flex item

分类说明
flex container开启了 flex 布局的那个元素
flex itemflex container 里面的直接子元素

我们常说的flex盒子 指代的是 flex container + flex items

Snipaste_2022-10-21_22-37-31.png

Flex item 的特点:

  1. flex item的布局将受flex container属性的设置来进行控制和布局
  2. flex item不再严格区分块级元素和行内级元素
  3. flex item默认情况下是包裹内容的, 但是可以设置宽度和高度

开启flex布局的方式

我们可以设置display属性的值为flex或者inline-flex来为当前元素开启弹性布局

flex类型说明
flexflex container 以 block-level 形式存在
inline-flexflex container 以inline-level形式存在

flex布局的模型

Snipaste_2022-10-21_22-38-38.png

flex是一个一维布局,一行如果放不下,且需要换行显示的时候,可以使用交叉轴来控制这些元素之间的排列方式

container相关属性

flex-direction

flex items 默认都是沿着 main axis(主轴)从 main start 开始往 main end 方向排布

flex-direction 决定了 main axis 的方向

因此我们可以使用flex-direction来改变元素的排列方向

说明
row元素从左往右排列,默认值
row-reverse元素从右往左排列
column元素从上往下排列
column-reverse元素从下往上排列

Snipaste_2022-10-21_22-40-03.png

flex-wrap

flex-wrap 决定了 flex container 是单行还是多行

说明
nowrap单行显示,不换行 --- 默认值
wrap多行显示
wrap-reverse多行 对比 wrap,cross start 与 cross end 相反

因为默认情况下,flex布局的flex-wrap的值是nowrap

也就是不换行,此时一行元素放不下的时候,

flex会尽可能的去压缩我们元素的宽度或者高度

所以即使我们为flex-item显示设置了对应的宽度和高度

在flex布局中,元素最终展示出来的宽度或高度不一定是我们所设置的宽度和高度

元素显示设置的宽度和高度只能说存在关系,但是不是必然要素

flex-flow

Snipaste_2022-10-21_22-44-28.png flex-flow 属性是 flex-direction 和 flex-wrap 的简写

并且顺序任何, 并且都可以省略

<flex-direction> || <flex-wrap>

justify-content

justify-content 决定了flex items在 main axis上的对齐方式

Snipaste_2022-10-21_22-42-17.png

align-items

align-items 决定了 flex items在cross axis上的对齐方式

Snipaste_2022-10-21_22-44-28.png

align-content

align-content 决定了多行flex items在cross axis上的对齐方式,用法与 justify-content 类似

Snipaste_2022-10-21_22-46-09.png

align-content使用的先决条件

  1. 必须有多行align-items
  2. 必须存在剩余空间,可以给flex container划分空格

所以align-content在实际开发中很少使用

因为在实际开发中,在绝大多数情况下,flex-container的高度是由flex-container中的内容撑开的

这也就意味着,没有剩余的空间给align-content进行分配

此时设置或者不设置align-content属性,效果都是一致的

item相关属性

order

order 决定了 flex items 的排布顺序

  • 可以设置任意整数(正整数、负整数、0)
  • 值越小就越排在前面
  • 默认值是 0

Snipaste_2022-10-21_22-48-22.png

align-self

flex items 可以通过 align-self 覆盖 flex container 设置的 align-items

  • auto(默认值): 遵从 flex container 的 align-items 设置
  • stretch、flex-start、flex-end、center、baseline,效果跟 align-items 一致

Snipaste_2022-10-21_22-49-59.png

flex-grow

flex-grow 决定了 flex items 如何扩展 (拉伸/成长)

  • 可以设置任意非负数字(正小数、正整数、0),默认值是 0
  • 当 flex container 在 main axis 方向上有剩余 size 时,flex-grow 属性才会有效
  • flex items 扩展后的最终 size 不能超过 max-width/max-height

flex-grow拉伸的计算方式如下:

flex items 的 flex-grow 总和 sum每个 flex item 扩展后的 size
大于1flex container 的剩余size * flex-grow / sum
小于1flex container 的剩余 size * flex-grow

Snipaste_2022-10-21_22-51-36.png

flex-shrink

flex-shrink 决定了 flex items 如何收缩(缩小)

  • 可以设置任意非负数字(正小数、正整数、0),默认值是 1

  • 当 flex items 在 main axis 方向上超过了 flex container 的 size,flex-shrink 属性才会有效,

    也就是元素溢出了,flex-shrink才会生效

  • flex items 收缩后的最终 size 不能小于 min-width/min-height

flex-shrink收缩的计算方式如下:

所有 flex items 的 flex-shrink 总和flex item 收缩的 size
大于1flex items 超出 flex container 的 size * 收缩比例 / 所有 flex items 的收缩比例之和
小于1 (此时flex items的总宽度依然会溢出,不推荐,很少设置)flex items 超出 flex container 的 size * 收缩比例

flex-basis(了解)

flex-basis 用来设置 flex items 在 main axis 方向上的 base-size

也就是用来设置元素在主轴上的大小

在绝大多数情况下,flex-basis的效果和width的效果是一致的

但是flex-basis的优先级高于width

他们的主要区别表现在显示长单词的时候

flex-basis是基准值,所以如果遇到长单词,无法换行显示的时候,会自动拉伸容器,使其可以正常显示长单词

width是显示设置的宽度值,如果遇到一行显示不小,且无法换行的长单词的时候,容器的宽度依旧是width所设置的那么宽,且长单词会溢出显示

flex-basis可以取的值:

  •  auto (默认值)
    
    • 如果没有设置width,那么默认值表现为内容的宽度
    • 如果设置width,那么默认值表现为width
  • 具体的宽度数值(100px)

  • 可以是一个百分比

    • 该百分比相对的是其父弹性盒容器主轴尺寸
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      width: 500px;
      height: 500px;
      background-color: orange;

      display: flex;
    }

    .item {
      /*
        width属性和flex-basis属性同时存在
        因为flex-basis的属性优先级更高
        所以宽度以flex-basis为准

        且此时flex-basis可以拉伸到的最大宽度为 width所设置的值
        例如
         1. 如果width的值为90px,此时flex-basis可以拉伸到的最大宽度为90px
            此时文本是放不下的,所以文本会溢出

         2. 如果width的值为300px,此时flex-basis可以拉伸到的最大宽度为300px
            此时文本是放的下的,所以flex-basis会自动拉伸为文本正好可以放下的宽度
      */
      width: 120px;
      /* 基础尺寸 */
      flex-basis: 120px;
      height: 120px;
    }
  </style>
</head>
<body>
  
  <div class="container">
    <div class="item item1">1</div>
    <div class="item item2">2我是coderwhy_why_hahahaha</div>
    <div class="item item3">3</div>
  </div>
  <!-- 该脚本用于生成div.item的随机色 -->
  <script src="./js/itemRandomColor.js"></script>
</body>
</html>

flex

flex 是 <flex-grow> <flex-shirink>? || <flex-basis> 的简写

flex 属性可以指定1个,2个或3个值

 # flex: none --> flex: 0 0 auto;
 # flex: auto --> flex: 1 1 auto;
 # flex: initial --> flex: 0 1 auto; ---> 恢复为默认初始值
 none | auto | initial | <flex-grow> <flex-shirink>? || <flex-basis>
 复制代码

单值语法: 值必须为以下其中之一:

  • 一个无单位数(<number>): 它会被当作<flex-grow>的值
  • 一个有效的宽度(width)值: 它会被当作 <flex-basis>的值
  • 关键字none,auto

双值语法: 第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值

第二个值必须为以下之一:

  • 一个无单位数:它会被当作 <flex-shrink> 的值
  • 一个有效的宽度值: 它会被当作<flex-basis> 的值

三值语法:

  • 第一个值必须为一个无单位数,并且它会被当作<flex-grow> 的值
  • 第二个值必须为一个无单位数,并且它会被当作 <flex-shrink>的值
  • 第三个值必须为一个有效的宽度值, 并且它会被当作<flex-basis> 的值