css flexbox 弹性布局

164 阅读5分钟

1.概念

  • 容器: 指父容器
  • 项目: 指容器里的子元素
  • 主轴: 指弹性布局的多个项目排列方向上的一根轴,如果 按x轴排列,那么x轴就是主轴
  • 交叉轴:指与主轴交叉的一根轴称为交叉轴 image.png

2.容器属性

dispaly

flex

父容器会独占一行,宽度100%

<!DOCTYPE html>
<html>
<head> 
    <style>
        .outer {
            display: flex;
            background-color: gold; 
        }
        .box{
            height: 100px;
            width: 100px;
            background-color: bisque;
            border: 1px solid #000 ;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div> 
        <div class="box"></div>
    </div>
</body>
</html>

image.png

inline-flex

父容器根据行内元素 确定宽度

 .outer {
    display: flex;
    background-color: gold; 
}

image.png

flex-direction

可指定容器的主轴及其排列方向。

row

  • row,默认值,即主轴是x轴,项目从最左端开始向右排列
  • row-reverse,表示项目从最右侧开始,从右向左排列

image.png

column

  • column,即主轴是y轴,项目从最上端开始向下排列
  • column-reverse,表示项目从最下侧开始,从下向上排列 image.png

flex-wrap

当一个主轴排列不下所有项目时,是否换行显示。 • nowrap,默认值,表示空间不够时,也不换行,项目自动缩小; • wrap,表示当内容放不下时应该换行显示

flex-flow

  • flex-direction和flex-wrap的简写形式
  • 语法格式:flex-flow: row nowrap

justify-content

专门定义项目在主轴上的对齐方式。 image.png flex-start 左对齐
flex-end 右对齐
center 居中
space-around 中间缝隙平分,两边的是缝隙宽度各一半
space-evenly 所有缝隙平分
space-between 两边不留缝隙,中间所有缝隙平分

space-around/evenly/between 差异

<html>
<head>
<title>test-justify-content:flex-space</title>
<style>
     body { margin: 0;margin-top: 50px;}
     h2 {font-size: 18px;}
    .box {
        background-color: gainsboro; 
        width: 100%; 
        display: flex; 
        line-height: 100px;
    }
    .box div{ 
        background-color: beige; 
        width: 100px; 
        border: 1px solid black; 
        text-align: center;
    }
    .box.around{ justify-content: space-around;}
    .box.evenly{ justify-content: space-evenly;}
    .box.between{ justify-content: space-between}
</style>
</head>

<body>    
    <h2>space-around(中间缝隙平分,两边的是缝隙宽度各一半)</h2>
<div class="box around">
    <div>aa</div>
    <div>bb</div>
    <div>cc</div> 
</div>
<h2>space-evenly(所有缝隙平分)</h2>
<div class="box evenly"> 
    <div>aa</div>
    <div>bb</div>
    <div>cc</div> 
</div>
<h2>space-between(两边不留缝隙,中间所有缝隙平分)</h2>
<div class="box between"> 
    <div>aa</div>
    <div>bb</div>
    <div>cc</div> 
</div>
<body>
</html>

image.png

align-items

专门定义所有项目在交叉轴上的统一对齐方式。

image.png

flex-start 左对齐
flex-end 右对齐
center 居中 baseline 基线对齐
stretch 默认撑满整个容器高度

align-content

控制 多行交叉轴的对齐方式

触发条件

  1. 支持换行flex-wrap: wrap; /支持换行/
  2. 内容足够多
  3. 父容器设置了高度

flex-start 左对齐
flex-end 右对齐
center 居中
space-between 两端对齐
space-around 使项目之间的间隔相等

例子

<!DOCTYPE html>
<html>
<head> 
    <style>
        .outer {
            display: flex; 
            width: 800px; 
            outline: 1px solid red; 
            flex-wrap: wrap;
            height: 800px;
            align-content: center;
        }
        .box{
            height: 100px;
            width: 200px;
            outline: 1px solid #000; 
        } 
        .box1{ 
            background-color: bisque;
            height: 50px;
        }
        .box2{
           background-color: antiquewhite;
        }
        .box3{
            background-color: rebeccapurple;
            height: 200px;
        }
        .box4{
            background-color: yellowgreen;
        }
        .box5{ 
            background-color: grey;
            height: 300px;
        }
        .box6{ 
            background-color: darkcyan;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="box box1">11</div>
        <div class="box box2">22</div>
        <div class="box box3">33</div> 
        <div class="box box4">44</div> 
        <div class="box box5">55</div> 
        <div class="box box6">66</div> 
    </div>
</body>
</html>

把换行的每一行做为布局的最小单元处理,再以整个父容器做居中处理 image.png

当 align-content 改成 align-items

则控制的是每个box为布局最小单元,在自己当前行中做居中处理

 .outer {
    display: flex; 
    width: 800px; 
    outline: 1px solid red; 
    flex-wrap: wrap;
    height: 800px;
    align-items: center; /*这里改成单行中的单个元素的布局*/
}
           

image.png

3.项目属性

order

专门定义项目的排列顺序。 无单位,越小越在前面

.box1{
    order:1
}
.box2{
    order:3
}
.box3{
    order:2
}
<div class="box1">11</div>
<div class="box2">22</div>
<div class="box3">33</div> 

image.png

flex-grow

设置放大比例(无单位),支持小数位

例子:flex-grow:2;

放大的计算逻辑

<!DOCTYPE html>
<html>
<head> 
    <style>
        .outer {
            display: flex;
            background-color: gold; 
            width: 1000px;
            border: 1px solid green;
        }
        .box{
            height: 100px;
            width: 100px;
            background-color: bisque;
            border-right: 1px solid #000 ;
        }

        .box1{
            flex-grow: 2;
        }
        .box2{
            flex-grow: 1;
        }
        .box3{
            flex-grow: 1;
        }
        .box4{
            flex-grow: 1;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="box box1">11</div>
        <div class="box box2">22</div>
        <div class="box box3">33</div> 
        <div class="box box4">44</div> 
    </div>
</body>
</html>

image.png

公式计算

当父容器的宽度1000px,所有子元素的总和宽度400px 大的时候,就会触发flex-grow 的计算,重新弹性计算每一个格子的宽度

  • 多出的宽度 = [父容器宽度 1000px] - [每个子元素宽度之和 100px +100px +100px +100px ] = 600px

  • box1 元素可新增宽度的比例 = [box1的 grow值: 2 ] / [所有子元素 grow的值和 2+ 1+1+1] = 2 / 5 = 0.4

  • box1多加的宽度 = 0.4 * 600px = 240px

  • box1最终宽度 = [当前宽度 100px] + [box1多加的宽度 240px] = 340px

image.png

image.png

flex-shrink

设置当空间不足时的收缩比例(无单位)

image.png

缩小的计算逻辑

<!DOCTYPE html>
<html>
<head> 
    <style>
        .outer {
            display: flex;
            background-color: gold; 
            width: 1000px; 
            outline: 1px solid red; 
        }
        .box{
            height: 100px;
            width: 500px;
            background-color: bisque;
            outline: 1px solid #000; 
        }

        .box1{
            flex-shrink: 2;
        }
        .box2{
            flex-shrink: 1;
        }
        .box3{
            flex-shrink: 1;
        }
        .box4{
            flex-shrink: 1;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="box box1">11</div>
        <div class="box box2">22</div>
        <div class="box box3">33</div> 
        <div class="box box4">44</div> 
    </div>
</body>
</html>

image.png

公式计算

当父容器的宽度1000px,所有子元素的总和宽度 2000px 大的时候,就会触发flex-shrink 的计算,重新弹性计算每一个格子的宽度

  • 溢出的宽度 = [父容器宽度 1000px] - [每个子元素宽度之和 500px +500px +500px +500px ] = 绝对值(-1000px) = 1000px

  • box1 元素需要减去宽度的比例 = [box1的 grow值: 2 ] / [所有子元素 grow的值和 2+ 1+1+1] = 2 / 5 = 0.4

  • box1需要减去的宽度 = 0.4 * 1000px = 400px

  • box1最终宽度 = [当前宽度 500px] - [box1徐需要减去的宽度 400px] = 100px

image.png

image.png

场景2

  • 当 flex-shrink: 0; box4 不参与计算
.box1{
    flex-shrink: 2; 
}
.box2{
    flex-shrink: 1;
}
.box3{
    flex-shrink: 1;
}
.box4{
    flex-shrink: 0;
}
  • 溢出的宽度 = [父容器宽度 1000px - 500px ] - [每个子元素宽度之和 500px +500px +500px ] = 绝对值(-1000px) = 1000px

  • box1 元素需要减去宽度的比例 = [box1的 grow值: 2 ] / [所有子元素 grow的值和 2+ 1+1.5+1] = 2 / 4 = 0.5

  • box1需要减去的宽度 = 0.5 * 1000px = 500px

  • box1最终宽度 = [当前宽度 500px] - [box1徐需要减去的宽度 500px] = 0

      注意即使 box1 的 flex-shrink: 3 ,只要小于0 都按0处理
    

image.png

image.png 这里把box1 的内容11去掉,可以看到宽度设置为0

flex-basis

设置初始大小(有单位) px 或者 %

例子:flex-basis:20%;

依次获取的优先级顺序

  • flex-basis > width > content(行内元素宽度)
  • 当 flex-basis 大于 max-width , max-width > flex-basis
  • 当 flex-basis 小于 min-width , min-width > flex-basis

flex 简写

flex-growflex-shrinkflex-basis的合并简写

单值

  • 一个无单位数(): 它会被当作flex-grow的值。
  • 一个有效的宽度(width)值: 它会被当作 flex-basis的值。
  • 关键字none, auto,或initial (比较少用)
flex: initial == flex: 0 1 auto
flex: none == flex: 0 0 auto
flex: auto == flex: 1 1 auto
flex: number == flex: number 1 0%

例子:

flex: 1 等同于 flex: 1 1 0,即放大比例:1,收缩比例为 1,初始大小为 0。

flex: auto 等同于flex: 1 1 auto

双值

第一个值必须为flex-grow。 第二个值可以是flex-shrink或者flex-basis

例子:

flex:2 2;

flex:2 10px;

三值

  • flex-grow
  • flex-shrink
  • flex-basis

例子:

flex:1 1 auto

为什么 flex:1; 同时设置 width=0 会产生什么效果?

<!DOCTYPE html>
<html>
<head> 
    <style>
        .parentBox{ 
            display:flex; 
            border: 3px solid black; 
        }
        .box{ 
            flex:1 ; 
        }
        .inner {
            width: 1200px;
            background-color: blueviolet;
            height: 100px;;
        }
    </style>
</head>
<body>
    <div class="parentBox">
        <div class="box"></div>
         <div class="box">
           <div class="inner"></div>
         </div>
    </div>
</body>
</html>

image.png

一般如果不设置width,那么每一个box的最大分配宽度等于父容器宽度。即box.maxWidth = parentBox.width

当第一个box的内容超出1/2的,就会溢出。

如果设置width:0 ,则 每个box的最大可分配宽度只能是 parentBox的1/2 ,即 box.maxWidth= parentBox.width /2

.box{ 
    flex:1 ; 
    width:0;
}

image.png