第二章:flex布局

简介

  1. flex布局(Flexible布局,弹性布局)是在小程序开发经常使用的布局方式
  2. 官方文档
    1. https://www.w3.org/TR/css-flexbox-1/
    2. https://www.w3.org/TR/css-align-3/
    3. W3C是一个组织,专门用于制定html、css规范的组织
  3. flex container与flex items的概念
    1. 开启了flex布局的元素叫 flex container
      1. 一旦一个元素使用了flex布局就叫它flex容器(flex container)
    2. flex container 里面的直接子元素叫做 flex items
  4. 如何开启flex布局?
    1. 设置display属性为flex或者inline-flex 可以成为flex container
      1. flex:flex container以block-level (块级元素)形式存在
      2. inline-flex:flex container以inline-level(行内元素)形式存在 (更像是行内块级,因为可以设置width、height)
    2. 注意:块级、行内块级、行内标签之前的区别
    3. 代码举例:

       //标签
       <view class="texstView1">texstView1</view>
       <view class="texstView2">texstView2</view>
              
       //css样式
       .texstView1 {
         background: red;
         //块级block-level形式存在
         display: flex;
       }
       .texstView2 {
         background: gray;
         //行内inline-level形式存在
         display: inline-flex;
         //设置宽高有效,更像是行内块级
         //height: 100rpx;
         //width: 400rpx;
       }
      

      pic

  5. Flex兼容性问题
    1. PC端:由于flex现在没有IE低版本的支持,即不建议用flex做PC端界面开发
    2. 移动端:可以用flex,虽然国产的UC浏览器的安卓低版本不支持flex语法,但它支持flexbox写法

常用CSS属性

  1. 应用在 flex container 上的CSS属性

     flex-flow 
     flex-direction 设置主轴方向
     flex-wrap
     justify-content
     align-items
     align-content
    
  2. 应用在flex items上的CSS属性

     flex
     flex-grow
     flex-basis
     flex-shrink
     order
     align-self
    

flex 布局模型

pic

  1. 1个flex container内部有2个 flex items

应用在 flex container 上的 CSS 属性

flex-direction

  1. flex items 默认都是沿着main axis(主轴)从main start开始往main end 方向排布
  2. flex-direction 决定了main axis 的方向,有4个取值
    1. row(默认值)、row-reverse、column、column-reverse

pic

justify-content

  1. justify-content决定了flex items 在main axis上的对齐方式
    1. flex-start(默认值):与main start 对齐
    2. flex-end:与main end对齐
    3. center:居中对齐
    4. space-between:
      1. flex items 之间的距离相等
      2. 与main start、main end两端对齐
    5. space-evenly:
      1. flex items之间的距离相等
      2. flex items与main start、main end之间的距离等于flex items之间的距离
    6. space-around:
      1. flex items之间的距离相等
      2. flex items与main start、main end之间的距离是flex items之间距离的一半

      pic

align-items

  1. align-items决定了flex items在 cross axis上的对齐方式
    1. stretch(默认值): 当flex items在cross axis方向的size(width、height)为auto时,会自动拉伸至填充flex container
    2. flex-start: 与 cross start对齐
    3. flex-end:与 cross end 对齐
    4. center:居中对齐
    5. baseline: 与基准线对齐
      1. 跟字体有关,比如下图的foo字体,4个items的foo字体大小都是不同的
      2. 那4个item的foo字体的底部就是基线,让4个items的基线对齐。
  2. 注意:交叉轴只有2个方向,没有反方向!!!
    1. 无论主轴是row还是row-reverse,交叉轴都是从上到下
    2. 无论主轴是column还是column-reverse,交叉轴都是从左到右

    pic

flex-wrap

  1. flex-wrap决定了flex container是单行还是多行
    1. nowrap(默认):单行
      1. 内容过多压缩到容器中,不是剪掉
    2. wrap:多行
    3. wrap-reverse:多行(对比wrap,cross start与cross end相反)

flex-flow

  1. flex-flow是flex-direction || flex-wrap的简写
    1. 比如 flex-flow: column wrap 等价于
      1. flex-direction: column
      2. flex-wrap: wrap
    2. 比如 flex-flow: row-reverse 等价于
      1. flex-direction: row-reverse
      2. flex-wrap: nowrap
    3. 比如 flex-flow: wrap 等价于
      1. flex-direction: row
      2. flex-wrap: wrap

align-content

  1. align-content决定了多行flex items在cross axis上的对齐方式,用法与justify-content类似
    1. stretch:(默认值)与align-items的stretch类似
    2. flex-start: 与cross start对齐
    3. flex-end:与 cross end对齐
    4. center:居中对齐
    5. space-between:
      1. flex items之间的距离相等
      2. 与cross start、cross end两端对齐
    6. space-evenly:
      1. flex items之间的距离相等
      2. flex items与cross start、cross end之间的距离等于flex items之间的距离
    7. space-around:
      1. flex items之间的距离相等
      2. flex items与cross start、cross end之间的距离是flex items之间距离的一半
    8. 注意:如果设置了该属性,就不要设置单行对齐属性align-items,否则会有冲突

pic

应用在 flex items 上的 CSS 属性

order

  1. order决定了flex items的排布顺序
    1. 可以设置任意整数(正整数、负整数、0),值越小就越排在前面
    2. 默认值是0

align-self

  1. flex items可以通过align-self覆盖flex container设置的align-items
    1. auto(默认值): 遵从flex container的align-items设置
    2. stretch、flex-start、flex-end、center、baseline,效果跟align-items一致

flex-grow

  1. flex-grow决定了flex items如何扩展
    1. 可以设置任意负数字(正小数、正整数、0),默认值是0
    2. 当flex container在main axis方向上有剩余size时,flex-grow属性才会有效
    3. 就是说当主轴方向上有多余的空间时,可以通过给item设置flex-grow,使该item在主轴方向上的size扩展不同的比例来瓜分剩余的空间。
  2. 如果所有flex items的flex-grow总和sum超过1,每个flex item扩展的size为
    1. (flex container的剩余size)*flex-grow/sum
    2. sum大于1,items扩展会占满主轴剩余的空间
  3. 如果所有flex items的flex-grow总和sum不超过1,每个flex item扩展的size为
    1. (flex container的剩余size)*flex-grow
    2. 注意:sum小于1,items扩展不会占满主轴剩余的空间
  4. flex item扩展后的最终size不能超过max-width\max-height
    1. item有2个属性:max-width\max-height,一旦设置,即使扩展也不会超过该值。

flex-shrink

  1. flex-shrink决定了flex items如何收缩
    1. 可以设置任意非负数字(正小数、正整数、0),默认值是1
    2. 当flex items在main axis方向上超过了flex container的size,flex-shrink属性才会有效
    3. 就是说当主轴方向上所有的item的size之和大于父元素的size时,可以通过给item设置flex-shrink,使该item在主轴方向上的size收缩不同的比例来瓜分超出父元素的空间。
  2. 如果所有flex items的flex-shrink总和超过1,每个flex item收缩的size为
    1. (flex items超出flex container的size)*收缩比例/所有flex items的收缩比例之和
    2. flex-shrink总和超过1,items的收缩会将超出父元素的空间收缩完,即items不会超出父元素
  3. 如果所有flex items的flex-shrink总和sum不超过1,每个flex item收缩的size为
    1. (flex items超出flex container的size * sum) *收缩比例/所有flex items的收缩比例之和
    2. flex-shrink总和小于1,items的收缩不会将超出父元素的空间收缩完,即items会超出父元素
    3. 注意:这个sum指的是所有items的flex-shrink之和
  4. 收缩比例 = flex-shrink * flex item的base size
    1. base size 就是 flex item 放入flex container之前的size
    2. 注意:这里的收缩比例可不是flex-shrink,跟扩展比例不一样,扩展直接是flex-grow !!!

       背景:
       有6个items,主轴为row,父元素宽度为500
       每个tiem的宽度为110、120、130、140、150、160 , flex-shrink为:1、2、3、4、5、6
      
       超出空间: 110+120+130+140+150+160 - 500 = 310;
      
       注意:收缩比例不是flex-shrink,跟扩展比例不一样!!!
      
       收缩比例 = flex-shrink * item的主轴方向size
       item1收缩比例 = 110 *1;
       ...
       item6的收缩比例= 160 *6;
      
       ---------sum>1----------
      
       item1的收缩size为: 310*(110*1)/(110*1+120*2+...160*6)
       ...
       item6的收缩size为: 310*(160*6)/(110*1+120*2+...160*6)
              
       --------sum<1----------
       如果flex-shrink为:0.1、0.1、0.1、0.1、0.1、0.1
       则flex-shrink之和sum为0.6<1
       item1的收缩size为: 310*0.6*(110*0.1)/(110*0.1+120*0.1+...160*0.1)
       ...
       item6的收缩size为: 310*0.6*(160*0.1)/(110*0.1+120*0.1+...160*0.1)
      
  5. flex item收缩后的最终size不能小于min-width\min-height
    1. item有2个属性:min-width\min-height,一旦设置,即使扩展也不会小于该值。

flex-basis

  1. flex-basis用来设置flex items在main axis方向上的base size(如果主轴为row,那么这个base size就是width)
    1. auto(默认值)
    2. content:取决于内容本身的size
    3. 设置固定值比如:100px
  2. 决定flex items最终base size的因素,从优先级高到低(就是说item可以设置各种size,但是有优先级)
    1. max-width\max-height\min-width\min-height
    2. flex-basis
    3. width\height
    4. 内容本身的size

flex

  1. flex是flex-grow flex-shrink ? || flex-basis 的简写
    1. 默认值是 0 1 auto
    2. none:0 0 auto
  2. ?指的是flex-shrink 可有可无,即:0 auto

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            border: 1px solid #000000;
            width: 500px;
            height: 500px;
            margin-left: 20px;
            margin-top: 20px;
            /* 开启flex布局 */
            display: flex;
            /* 设置主轴方向:row、 row-reverse、column、column-reverse */
            flex-direction: row;
            /* 设置主轴方向对齐方式  flex-start、flex-end、center、space-between、space-evenly、space-around*/
            /* justify-content: center; */
            /* 设置交叉轴的对齐方式:stretch(默认)、flex-start、flex-end、center、center*/
            align-items: center;
            /* nowrap(默认)、wrap、wrap-reverse*/
            /* flex-wrap: wrap; */
            /* 多行items在cross轴上的对齐方式:stretch、flex-start、flex-end、center、space-between、space-evenly、space-around */
            /* align-content: stretch; */
        }
        .item{
            /* 如果size为auto,那么就会是stretch */
            width: 100px;
            height: 100px;

            /* width: auto;
            height: auto; */
            font-size: 50px;
            color: white;
            /* 内容居中 */
            text-align: center;
            line-height: 80px;
        }
        .item:nth-of-type(1){
            background-color: red;
            /* flex-grow: 1; */
            width: 110px;
            flex-shrink: 1;
        }
        .item:nth-of-type(2){
            background-color: green;
            /* 决定了flex items的排布顺序,越小排在越前面 */
            /* order: 1; */
            width: 120px;
            flex-shrink: 2;
        }
        .item:nth-of-type(3){
            background-color: blue;
            /* 当前item覆盖掉父元素的align-items设置,默认值:auto,遵从父元素的lign-items设置 */
            /* align-self: flex-start; */
            width: 130px;
            flex-shrink: 3;
        }
        .item:nth-of-type(4){
            background-color: yellow;
            width: 140px;
            flex-shrink: 4;
        }
        .item:nth-of-type(5){
            background-color: grey;
            width: 150px;
            flex-shrink: 5;
        }
        .item:nth-of-type(6){
            background-color: purple;
            flex-shrink: 6;
        }
        /* .item:nth-of-type(7){
            background-color: rgb(0, 255, 0);
        } */
        /* 

        背景:
        有6个items,主轴为row,父元素宽度为500
        每个tiem的宽度为110、120、130、140、150、160 , flex-shrink为:1、2、3、4、5、6

        超出空间: 110+120+130+140+150+160 - 500 = 310;

        注意:收缩比例不是flex-shrink,跟扩展比例不一样!!!

        收缩比例 = flex-shrink * item的主轴方向size
        item1收缩比例 = 110 *1;
        ...
        item6的收缩比例= 160 *6;

        ----------

        item1的收缩size为: 310*(110*1)/(110*1+120*2+...160*6)
        ...
        item6的收缩size为: 310*(110*6)/(110*1+120*2+...160*6)
         */
    </style>
</head>
<body>
    <!-- div>div.item*3   :一个div里面有4个div子元素 -->
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
        <!-- <div class="item">7</div> -->
    </div>
   
</body>
</html>
Table of Contents