Skip to content

一. flex布局


1. 认识flexbox

  • Flexbox翻译为弹性盒子
    • 弹性盒子是一种用于按行或按列布局元素的一维布局方法
      • grid布局是二维的,但是出现的相对晚些,兼容性不太好,功能是比flex强大
    • 元素可以膨胀以填充额外的空间,收缩以适应更小的空间
    • 通常我们使用flexbox来进行布局的方案称之为flex布局(flex layout
  • flex布局时目前web开发中使用最多的布局方案:
    • flex布局(Flexible布局,弹性布局)
    • 目前特别在移动端可以说已经完全普及
    • 在**PC端也几乎已经完全普及和使用**,只有非常少数的网站需要兼容低版本浏览器的依然在用浮动来布局
  • 为什么需要flex布局呢?
    • 长久以来,css布局中唯一可靠而且浏览器兼容的布局工具只有floatspositioning
    • 但是这两种方法本身存在很大的局限性,并且他们用于布局实在是无奈之举
  • 如何让元素变成一个弹性盒子flexbox呢?
    • display: flex;

2. 原先布局存在的痛点

  • 原来的布局存在哪些痛点呢? 举例说明:
    • 比如在父内容里面垂直居中一个块内容

      image-20220410123707112
    • 比如使容器的所有子项等分可用宽度/高度,而不管有多少宽度/高度可用

    • 比如使多列布局中的所有列采用相同的高度,即使它们包含的内容量不同

3. flex布局的出现

  • 所以长久以来, 大家非常期待一种真正可以用于对元素布局的方案: 于是flex布局出现了

    • Nature and nature's laws lay hid in night; God said "Let Newton be" and all was light
    • 自然与自然的法则在黑夜隐藏,于是上帝说,让牛顿出现吧!于是世界就明亮了起来
  • flexbox在使用时, 我们最担心的是它的兼容性问题:

    • 我们可以在caniuse上查询到具体的兼容性

      image-20220410123904818

4. flex布局的特性

  • 两个重要的概念:

    • 开启了flex布局的元素叫做flex container

    • flex container里面的直接子元素叫做flex item

      image-20220410125816304
  • flex container中的子元素变成了flex item,具备以下特点:

    • flex item的布局将受flex container属性的设置来进行控制和布局
    • flex item不再严格区分块级元素和行内级元素
    • flex item默认情况下宽高是包裹内容的,可以设置宽高
  • 设置display属性为flex或者inline-flex可以成为flex container

    注意:

    • flex itemposition:absolute/fixed 的元素时,将不再具备 flex item 元素的特性

5. flex布局的模型

image-20220410131232790

6. flex相关的属性

应用在flex container上的CSS属性应用在flex items上的CSS属性
flex-flowflex-grow
flex-directionflex-basis
flex-wrapflex-shrink
flex-floworder
justify-contentalign-self
align-itemsflex
align-content

6.1 flex container相关的属性

flex-direction

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

  • flex-direction 决定了main axis的方向,有4个取值:

    • row(默认值)、row-reversecolumncolumn-reverse

      image-20220410163501557

flex-wrap

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

    • nowrap(默认):单行

    • wrap:多行

    • wrap-reverse:多行(对比wrap、cross startcross end相反)

      image-20220410164900029

flex-flow

  • flex-flow属性是flex-direction flex-wrap的简写

    • 顺序任意,并且都可以省略

      image-20220410165030297

justify-content

  • justify-content 决定了flex itemsmain axis上的对齐方式

    • flex-start(默认值):让flex itemsmain start对齐

    • flex-end:让flex items main end对齐

    • center:居中对齐

    • space-between

      • 同一行中的flex items之间的距离相等
      • main start、main end两端对齐
    • space-around

      • 同一行中的flex items之间的距离相等
      • flex itemsmain start、main end之间的距离是flex items之间距离的一半
    • space-evenly

      • 同一行中的flex items之间的距离相等

      • flex itemsmain start、main end之间的距离等于flex items之间的距离

        image-20220410171944417

align-items

  • align-items 决定了flex itemscross axis上的对齐方式

    • normal:在弹性布局中,效果和stretch一样(默认值),均匀分布项目,拉伸自动大小的项目直至填充盒子

    • stretchflex itemscross axis方向的sizeauto 时,会自动拉伸至填充 flex container

    • flex-start:与cross start对齐

    • flex-end:与cross end对齐

    • center:居中对齐

    • baseline:与基准线对齐

      image-20220410173426994

align-content

  • 该属性对单行弹性盒子模型无效(即:带有flex-wrap: nowrap

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

    • stretch(默认值):与align-itemsstretch 类似

    • flex-start:与cross start对齐

    • flex-end:与cross end对齐

    • center:居中对齐

    • space-between

      • 同一行中的flex items之间的距离相等
      • cross start、cross end两端对齐
    • space-around:

      • 同一行中的flex items之间的距离相等
      • flex items cross start、cross end之间的距离是flex items之间距离的一半
    • space-evenly:

      • 同一行中的flex items之间的距离相等

      • flex items cross start、cross end之间的距离 等于flex items之间的距离

        image-20220410174514634

6.2 flex items相关的属性

order

  • order 决定了flex items的排布顺序

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

    • 默认值是 0

      image-20220410212937259

align-self

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

    • auto(默认值):遵从flex containeralign-items设置

    • stretch、flex-start、flex-end、center、baseline,效果跟align-items一致

      image-20220410213639241

flex-grow

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

    • 可以设置任意非负数字(正小数、正整数、0),默认值是 0
    • flex containermain axis方向上有剩余size 时,flex-grow 属性才会有效
  • 如果所有flex itemsflex-grow总和sum 超过 1,每个flex item扩展的size

  • flex container 的剩余 size * flex-grow / sum

    image-20220410214616685
  • flex items 扩展后的最终size 不能超过 max-width\max-height

注意:

  • flex items没有设置具体的宽高且该flex items自身display值为flex时,其内部item文字内容单行不换行时,且内容溢出时,flex-grow会扩展出去,设置该flex itemsoverflow:hidden即可

flex-shrink

  • flex-shrink 决定了flex items如何收缩(缩小)
    • 可以设置任意非负数字(正小数、正整数、0),默认值是 1
    • flex itemsmain axis方向上超过了flex containersizeflex-shrink 属性才会有效
  • 如果所有flex itemsflex-shrink总和超过 1,每个flex item收缩的size
    • flex items 超出flex containersize * 收缩比例 / 所有flex items的收缩比例之和
  • flex items 收缩后的最终size 不能小于 min-width\min-height

注意:

  • img 不会收缩
  • flex item 超过 flex 容器的宽度时,flex item 默认会收缩至 flex 容器的宽度,如果想某个 flex item 不收缩,将其 flex-shrink: 0 即可

flex-basis

  • 设置 flex itemsmain axis方向上的 base size
    • auto(默认值)、具体的宽度数值(100px
  • 决定flex items最终base size的因素,从优先级高到低
    • max-width\max-height\min-width\min-height
    • flex-basis
    • width\height
    • 内容本身的 size
  • flex-grow0的情况下,flex-basis0的话,会导致item元素base宽度为0,如果内容有元素的话会呈多行显示,每行只显示一个单词(汉字)

flex

  • flex flex-grow||flex-shrink||flex-basis的简写,flex 属性可以指定1个,2个或3个值

    image-20220410220211578
  • 单值语法:值必须为以下其中之一:

    • 一个无单位数(<number>):它会被当作<flex-grow>的值,<flex-shrink>的值被假定为1,然后<flex-basis>的值被假定为0
    • 一个有效的宽度(width)值:它会被当作 <flex-basis>的值
    • 关键字noneautoinitial
  • 双值语法:第一个值必须为一个无单位数,并且它会被当作<flex-grow>的值

    • 第二个值必须为以下之一:
      • 一个无单位数:它会被当作<flex-shrink>的值
      • 一个有效的宽度值:它会被当作<flex-basis>的值
  • 三值语法

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

7. 常见问题的解决方案

image-20220410221336132
  • 类似上面使用justify-content:space-between最后一行可能会遇到的情况
  • 方法一:
    • 不设置space-between,给每个元素添加margin-right,最右边的margin-right: 0;
  • 方法二:
    • flex items最后面添加几个没有内容的元素即可,推荐i元素
      • flex items不区分块级、行内级,默认宽高由内容决定,需要设置添加的元素宽度等同于item的宽度高度设置为0不可见
      • 所以不给i元素添加内容,则没有宽高,就看不见,但是在space-between中,仍然会对添加的i元素进行排布
    • 添加个数:排布的列数 - 2
image-20220425125549562
  • 类似上面这种,给红框中间的flex子元素设置flex:1;,内层的元素设置nowrap的情况下,内容超出的时候,会将flex子元素撑开

    css
    .main .news-section .news {
      flex: 1;
      overflow: hidden;
      padding: 0 17px;
    }
  • flex1item 设置 overflow:hidden即可解决

image-20220426174738916
  • 如上图所示,flex容器中,因为连字符的一些影响导致红框的子元素内容本应该显示在一行的,却出现断字的情况
    • 方法一:
      • 使用不间断连字符,ctrl +shift +连字符键
    • 方法二:
      • 使用类似-符号的字符实体:&minus
    • 方法三:
      • 给内容溢出排不下的子元素设置flex: 1;
image-20221124213221159
  • 当浏览器窗口宽度减少的时候,主banner图宽度固定,保持图片核心内容居中显示

    css
    /* 方案一:img结构 */
    img {
      position: relative;
      transform: translateX(-50%);
      left: 50%;
    }
    
    /* 方案二:背景图 */
    background: url(../img/main_bg.jpg) no-repeat center top;

二. 去除元素内容滚动时默认的滚动条


  • 这里以类名为box的元素为例子

    css
    /* 去除类名为box的元素滚动时的滚动条 */
    .box::-webkit-scrollbar {
      display: none;
    }

Released under the MIT License.