Flex布局总结

260 阅读8分钟

Flex布局介绍

摘至MDN

flex 是一个CSS的display 属性中新添加一个值。 随着inline-flex的使用,它将使它适用的元素成为一个flex container(伸缩容器),而这个元素的每个子元素将成为 flex item(伸缩项目)。伸缩项目将参与到flex布局中,所有由CSS Flexible Box Layout Module(CSS伸缩盒布局模型)定义的属性都能被它们使用(要遵守max-height/ max-width所施加的约束)

flex布局由两部分构成,一是布局容器flex-container,二是容器里的每一项子元素flex-item

一、 设置flex布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flex</title>
    <style>
        html,body{
            margin: 0;
            padding: 0;
        }
        .box{
            width: 550px;
            height: 400px;
            background-color: #f00;
            color: #fff;
            text-align: center;
            /* 把display属性设置为flex则会启用弹性布局  */
            display: flex;
        }
        .item{
            width: 100px;
            height: 100px;
            line-height: 100px;
        }
        .item1{
            background-color: blue;
        }
        .item2{
            background-color: olive;
        }
        .item3{
            background-color: peachpuff;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item item1">item1</div>
        <div class="item item2">item2</div>
        <div class="item item3">item3</div>
    </div>
</body>
</html>

设置弹性布局前效果图

设置后

可以看出来设置完弹性布局后可以直接改变原来div块级元素的排布走向

二、flexbox的两个轴

在flex布局里引申出两个轴的概念,水平的为主轴(main axis),垂直的为交叉轴(cross axis),这两个轴决定我们Flex布局整体的排列方式和走向

主轴(main axis):水平轴,开始位置成为main start (默认为左侧),结束位置为main end(默认为右侧)

交叉轴(cross axis):垂直轴,开始位置为cross start(默认为布局上侧),结束位置为cross end(默认为布局下侧)

三、 flex-container容器的属性

  • flex-direction 决定主轴的排列方向
  • flex-wrap 决定当容器一排放不下是否换行显示
  • flex-flows 是flex-direction和flex-wrap的缩写属性
  • justify-content 决定在主轴的对齐方式
  • align-item 决定在交叉轴的对齐方式
  • align-content 决定了多行flex-item在交叉轴上的对其方式
  1. flex-direction(默认的值为row):

    • flex-direction: row;(主轴为水平方向,起点在左侧)
    • flex-direction:row-reverse;(主轴为水平方向,起点在右侧)
    • flex-direction: column;(主轴为垂直方向,起点在上侧)
    • flex-direction:column-reverse(主轴为垂直方向,起点在下侧)
  2. flex-wrap 决定当容器一排放不下是否换行显示

    • 把flex-container容器改为如下(默认为flex-wrap: nowrap;):
    <div class="box">
        <div class="item item1">item1</div>
        <div class="item item2">item2</div>
        <div class="item item3">item3</div>
        <div class="item item1">item4</div>
        <div class="item item2">item5</div>
        <div class="item item3">item6</div>
        <div class="item item1">item7</div>
        <div class="item item2">item8</div>
        <div class="item item3">item9</div>
    </div>
    

    展示效果为:

    • flex-wrap: wrap(当容器一排放换行显示)

    • flex-wrap: wrap-reverse(当容器一排放换行显示,并且第一行在下方,反向排列)

    以上效果可以看出来flex-wrap 决定当容器一排放不下是否换行显示,并且可以控制首行和次行的排列顺序,但是带来一个问题,当多行的时候第二行并不是直接位于第一行下方排列,而是中间有间隔后面会讲到这个属性 align-content

  3. flex-flows是flex-direction和flex-wrap两个属性的缩写属性,默认值为 row nowrap

  4. justify-content 决定在主轴的对齐方式

    • flex-start(默认值),左对齐
    • flex-end,右对齐
    • center: 居中
    • space-between:沿着主轴均匀地分布在对齐容器内。每对相邻项目之间的间距是相同的。第一项与主边缘齐平,最后一项与主边缘齐平
    • space-around:沿着主轴均匀地分布在对齐容器内。每对相邻项目之间的间距是相同的。第一个项目之前和最后一个项目之后的空白空间等于每对相邻项目之间的空白空间的一半
    • space-evenly:沿着主轴均匀地分布在对齐容器内。每对相邻项目之间的间距是相同的。第一项与主边缘齐平,最后一项与主边缘齐平

    justify-content 更多属性参考: developer.mozilla.org/en-US/docs/…

  5. align-item 决定在交叉轴的对齐方式

    • stretch(默认值):如果item未设置高度或设为auto,将占满整个容器的高度 之前布局里都给.item设置了高度100px,在不给.item设置高度时, align-item为stretch时,item将占满整个容器
    • flex-start:以交叉轴起点位置为起点,与该行的交叉起点齐平。
    • flex-end:以交叉轴终点位置为起点,与线的交叉端边缘齐平。
    • center:与交叉轴的中点对齐。
    • baseline: 与容器里的第一行文字的基线对齐,当我们修改了item里的字体后效果会很明显。
      align-item 更多属性参考: developer.mozilla.org/en-US/docs/…
  6. align-content 决定了当容器的子项很多并且flex-wrap设置换行后每行轴线的对齐方式,如果项目只有一根轴线,该属性不起作用,我们在使用flex-wrap属性的时候发现多行子项的时候换行后第一行和第二行有间距,align-content 就是为了设置多行item存在的属性

    • stretch(默认值):轴线占满整个交叉轴
    • flex-start:以交叉轴起点位置为起点
    • flex-end:以交叉轴终点位置为起点
    • center:与交叉轴的中点对齐。
    • space-between: 沿着横轴均匀地分布在对齐容器内。每对相邻项目之间的间距是相同的。第一项与横向容器中对齐容器的起始边缘齐平,最后一项与横向容器中对齐容器的终止端齐平
    • space-around: 沿着横轴均匀地分布在对齐容器内。每对相邻项目之间的间距是相同的。第一个项目之前和最后一个项目之后的空白空间等于每对相邻项目之间的空白空间的一半
    • space-evenly:沿着横轴均匀地分布在对齐容器内。每对相邻项之间的间隔,开始边缘和第一项以及结束边缘和最后项都完全相同
      align-content更多属性参考:developer.mozilla.org/en-US/docs/…

四、 flex-item子容器的属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flex</title>
    <!-- 
        order决定了flexitem顺序,order越小排序越在前面
        align-self覆盖父布局针对交叉轴的对齐方式
        flex-grow当所有flex-grow和大于1的时候,剩余数量按照比值进行分割 剩余200,200/sum*flex-grow
        flex-shrink决定了flex-item如何收缩,默认值为1
        flex-basis可以设置主轴元素大小
        flex是flex-grow|flex-shrink|flex-basis
     -->
    <style>
        html,body{
            margin: 0;
            padding: 0;
        }
        .box{
            width: 500px;
            height: 400px;
            background-color: #f00;
            color: #fff;
            text-align: center;
            display: flex;
            /* align-items: center; */
        }
        .item{
            width: 100px;
            height: 100px;
            line-height: 100px;
        }
        .item1{
            background-color: blue;
            /* flex-grow: 2; */
            /* order: 10; */
            flex-basis: 100px;
        }
        .item2{
            background-color: olive;
            /* flex-grow: 2; */
            /* height: 150px; */
            /* order: 6; */
        }
        .item3{
            background-color: peachpuff;
            /* flex-grow: 1; */
            /* align-self: flex-end; */
            /* order: 100; */
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="item item1">item1</div>
        <div class="item item2">item2</div>
        <div class="item item3">item3</div>
    </div>
</body>
</html>

以上为item的代码,之前三章介绍的是关于flex-container容器的属性,下面为容器内部的子项的属性。

  1. order决定了flexitem顺序,order越小排序越在前面
    • 分别给item1设置order:3,item2设置order:2,,item3设置order:1,效果如下:
  2. align-self覆盖父布局针对交叉轴的对齐方式
    • 给box设置align-items: center;item1设置align-self: start;会覆盖原来父布局交叉轴的对齐方式
  3. flex-grow当所有flex-grow和大于1的时候,剩余宽度按照比值进行分割,剩余200,200/sum*flex-grow,当所有flex-grow和小于1的时候直接X flex-grow
    • flex-container整体宽度为500,三个item宽度为100,剩余空间为500-300 = 200,item1的flex-grow为2,item2的flex-grow为2,item3的flex-grow为1,那么,item1的宽度就会为100+200/(2+2+1)X 2 = 180,item2也是180,item3则为140
    • item1的flex-grow为0.2,item2的flex-grow为0.2,item3的flex-grow为0.1,item1的宽度为100+ 200 X 0.2 = 140
  4. flex-shrink 决定了flex-item如何收缩,默认值为1
    • 设置每个item宽度为200px,由于父布局容器为500,宽度小于200 X 3,item会自动收缩
    • 如果item1的flex-shrink属性为0,其他项目都为1,则空间不足时,item1不缩小
  5. flex-basis可以设置主轴元素大小
    • 默认为auto,会读取item的width
    • 可以为具体的数值
    • 优先级高低:max-width/max-height/min-width/min-height --> flex-basis --> width/height --> 容器本身
  6. flex是flex-grow|flex-shrink|flex-basis 三个属性的简写,默认值为0 1 auto。后两个属性可选。