flex 弹性布局技巧

157 阅读5分钟

弹性布局 flex

读《CSS新世界》flex布局篇笔记

子项特性

  1. flex 子项块转化
  2. flex 子项浮动失效
  3. flex 子项支持 z-index 属性
  4. flex 子项的 margin 值不会合并
  5. flex 子项是格式化的尺寸
  6. flex 子项若被绝对定位,则会脱离弹性布局

布局设置

  1. flex-direction 属性与整体布局方向

    flex-direction: row | row-reverse | column | column-reverse;
    
  2. flex-wrap 属性与整体布局的换行表现

    flex-wrap: nowrap | wrap | wrap-reverse;
    
  3. flex-flow 属性是 flex-directionflex-wrap 的缩写

css对齐特性综述

通用描述性:

  • justify 表示水平方向的样式设置;
  • align 表示垂直方向的样式设置;
  • items (有s) 表示全体元素的样式设置;
  • content 表示整体布局的样式设置;
  • self 表示元素自身的样式设置,其一定是应用在子元素上的。

justify-content 属性就表示整体布局的水平对齐设 置,align-items 就表示全体元素的垂直对齐样式设置。

  1. justify-content 属性与整体布局的水平对齐

    justify-content: normal | flex-start | flex-end | center | space-between | space-around | space-evenly;
    
  2. 垂直对齐属性 align-itemsalign-self

    区别: align-self属性是设置在具体的某一个flex子项上的,而align-items属性是设置在flex容器元素上的,控制所有flex子项的垂直对齐方式。

    align-items: stretch | flex-start | flex-end | center | baseline;
    ​
    align-self: auto | stretch | flex-start | flex-end | center | baseline;
    
    • autoalign-self属性的默认值,表示flex子项的垂直对齐 方式是由flex容器的align-items属性值决定的。
    • stretch可以看成弹性布局中align-items属性的默认值,表示flex子项在垂直方向上拉伸。
  3. align-content 属性与整体布局的垂直对齐

    区别: align-content属性和align-items属性的区别在于align-items属性设置的是每一个flex子项的垂直对齐方式,而align-content属性将所有flex子项作为一个整体进行垂直对齐设置

    align-content: stretch | flex-start | flex-end | center | space-between | space-around | space-evenly;
    
  4. order 属性与单个子项的顺序控制

    order: <integer>; /* 整数值,默认值是 0 */
    

深入理解 flex 属性

flex属性是flex-grow、flex-shrink和flex-basis这3个属性的缩写。

flex:auto 等同于 flex: 1 1 auto , 作用为 flex 子项自动填满剩余空间或自动收缩;

flex:none 等同于 flex:0 0 auto , 作用为 flex 子项没有弹性, 涉河固定尺寸元素(无需设置width属性)。

语法:

flex: auto;
flex: none;
flex: <'flex-grow'> <'flex-shrink'>? || <'flex-basis'>
​
flex-grow: <number>; /* 数值,可以是小数,默认值是 0 */
flex-shrink: <number>; /* 数值,默认值是 1 */
flex-basis: <length> | auto; /* 默认值是 auto */

【注】只有flex-basis的属性值支持长度值

单值语法等同于备注
flex: initiateflex: 0 1 auto初始值, 通常用来还原已经设置的CSS属性,常用于希望元素尺寸收缩,同时元素内容较多又能自动换行的场景中可以不做任何flex属性设置。
flex: 0flex: 0 1 0%使用场景少,元素尺寸表现为最小内容宽度。 适用于: 元素内容的主体是替换元素,这种情 况下文字内容就会被包围在替换元素的宽度下。
flex: noneflex: 0 0 auto推荐,元素最终尺寸通常表现为最大内容宽度。 适合设置在内容不能换行显示的小控件元素上,如按钮。
flex: 1flex: 1 1 0%推荐,在容器尺寸不足时会优先最小化内容尺寸,常用于等分列表或等比例列表。
flex: autoflex: 1 1 auto适用场景少, 但很有用。在容器尺寸不 足时会优先最大化内容尺寸。 多用于内容固定和内容可控的布局场景,例如导航数量不固定且每个导航文字数量也不固定的导航效果。适合基于内容动态适配的布局。

flex-basis 属性与尺寸计算规则:

最大最小尺寸限制 > 弹性增长或收缩 > 基础尺寸

* 弹性布局最后一行不对齐的处理

通用思路: 使用足够的空白标签进行填充占位,具体的占位数量是由最多列数的个数决定的。

  1. 若每一行列数固定

    A. 模拟**space-between**属性值和间隙大小,也就是说,我们不使用justify-content:space-between声明模拟两 端对齐效果,而使用margin对最后一行内容中出现的间隙进行控制。

    .container {
      display: flex;
      flex-wrap: wrap;
    }
    .list {
      width: 24%; height: 100px;
      background-color: skyblue;
      margin-top: 15px;
    }
    .list:not(:nth-child(4n)) {
      margin-right: calc(4% / 3);
    }
    

    B. 根据元素的个数给最后一个元素设置动态margin 值。

    .container {
      display: flex;
      /* 两端对齐 */
      justify-content: space-between; flex-wrap: wrap;
    } .list {
      width: 24%; height: 100px;
      background-color: skyblue;
      margin-top: 15px;
    }
    /* 如果最后一行是3个元素 */ 
    .list:last-child:nth-child(4n - 1) {
      margin-right: calc(24% + 4% / 3);
    }
    /* 如果最后一行是2个元素 */ 
    .list:last-child:nth-child(4n - 2) {
      margin-right: calc(48% + 8% / 3);
    }
    
  2. 若 flex 子项宽度不固定 (常用)

    A. 给最后一项设置 margin-right:auto

    .container {
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
    }
    .list {
      background-color: skyblue;
      margin: 10px;
    }
    /* 最后一项margin-right:auto */ 
    .list:last-child {
      margin-right: auto;
    }
    

    B. 使用伪元素在列表的末尾创建一个flex子项,并设置 flex:auto 或设置 flex:1

    .container {
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
    }
    .list {
      background-color: skyblue;
      margin: 10px;
    }
    /* 使用伪元素辅助左对齐 */ 
    .container::after {
      content: '';
      flex: auto; /* 或者flex: 1 */ 
    }
    
  3. 若每一行列数不固定

    通用思路, 利用空白标签进行占位填充:

    <div class="container">
      <div class="list"></div>
      <div class="list"></div>
      <div class="list"></div>
      <div class="list"></div>
      <div class="list"></div>
      <div class="list"></div>
      <div class="list"></div>
      <i></i><i></i><i></i><i></i><i></i>
    </div>
    <style>
      .container {
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;
        margin-right: -10px;
      } .list {
        width: 100px; height:100px;
        background-color: skyblue;
        margin: 15px 10px 0 0;
      }
      /* 与列表元素一样的元素宽度和margin值 */ 
      .container > i {
        width: 100px;
        margin-right: 10px;
      }
    </style>
    
  4. 若列数不固定且 HTML 又无法调整: 改用 Grid布局