CSS flex布局

443 阅读4分钟

flex简介

弹性盒模型布局,先需要指定一个容器,后续的所有布局操作都是基于此容器来定义的。

核心:容器会根据布局的需要调整其中所包含的子元素的尺寸、顺序来填充容器的所有可用空间。

思想:flex元素是可以让设置的布局根据浏览器的大小变化进行自动伸缩的。

原理:通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。 设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。

运用场景:

  • 元素的垂直水平居中
  • 多列布局
  • 网格布局

怎么设置这个容器呢?display:flex

flex 内容宽度等分

.box{
    display:flex
}
.box div{
    flex:1;   // flex-grow1
    border:1px solid red
}
<div class="box">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

image.png

flex-grow:当父控件还有剩余空间的时候,是否进行放大(grow)其中数值代表的是放大比例,值为0的时候表示不放大.

flex弹性布局实现瀑布流

.box{
   display:flex;
   flex-flow:column wrap;
   height:100vh
}
.item{
  margin:10px;
  width:calc(100%/3 -  20px)
}
.item img{
  width:100px;
  height:100px;
}
<div class="box">
   <div class="item">
      <img src="./imgs/1.jpg" alt="2">
   </div>
</div>

flex:1解析

flex属性是 flex-grow + flex-shrink + flex-basis 的缩写。

注意点:flex:1,让所有弹性盒模型对象的子元素都有相同的长度,忽略他们内部的内容。

  • flex-grow:定义项目的的放大比例;

    • 默认为0,即使存在剩余空间,也不会放大;
    • 所有项目的flex-grow为1:等分剩余空间(自动放大占位);
    • flex-grow为n的项目,占据的空间(放大的比例)是flex-grow为1的n倍。
  • flex-shrink:定义项目的缩小比例;

    • 默认为1,即如果空间不足,该项目将缩小;
    • 所有项目的flex-shrink为1:当空间不足时,缩小的比例相同;
    • flex-shrink为0:空间不足时,该项目不会缩小;
    • flex-shrink为n的项目,空间不足时缩小的比例是flex-shrink为1的n倍。
  • flex-basis: 定义在分配多余空间之前,项目占据的主轴空间(main size),浏览器根据此属性计算主轴是否有多余空间,

    • 默认值为auto,即 项目原本大小;
    • 设置后项目将占据固定空间。
  • flex的属性默认值为:0 1 auto (不放大会缩小)

  • flex为none: 0 0 auto(不放大不缩小)

  • flex为auto: 1 1 auto(放大且缩小)

  • flex为一个非负数字n:该数字为flex-grow的值:

flex:n; => flex-grow:n flex-shrik:1; flex-basis:0%

  • flex 为一个长度或百分比L:视为flex-basis的值 flex:L = flex-grow:1;flex-shrink:1;flex-basis:L

⚠️:

一个值时:
  • 一个无单位的值会被认为是flex-grow的值
  • 一个有效单位的宽度值,会被认为是flex-basis
两个值时:
  • 第一个值必须是:无单位数,认为是flex-grow
  • 第二个值必须是:一个无单位数:认为是flex-shrik;一个有效单位宽度:认为是flex-basis
三个值时:
  • 第一个值必须是无单位数,认为是flex-grow
  • 第二个值必须是无单位数,认为是flex-shrink
  • 第三个值必须是有效单位宽度,认为是flex-basis

面试题:说说你对flex的理解

flex布局的元素,简称“容器”。它的所有的子元素自动成为容器成员。

弹性布局由父级容器、子容器构成,通过设置主轴和交叉轴来控制子元素的排列方式。

  • flex-direction:row|row-reverse|column|column-reverse;该属性定义了子元素排列方向.

  • justify-content:flex-start|flex-end|center; 该属性定义了子元素在主轴上的对齐方式。

  • align-items:flex-start|flex-end|center; 定义项目在交叉轴上如何对齐。

flex-basis与width的问题

  • 当flex-basis与width同时设置时,width不起作用
    • 当主轴为横向时,即:flex-direction:row | row-reverse.flex-basis设置的大小为宽度时,会覆盖width的值
  • 当flex-basis与max-width或者min-width同时设置时,flex-basis不起作用
    • 当主轴为纵向时,即:flex-direction:column | column-reverse.flex-basis设置的大小为高度时,会覆盖height的值

width、min-width与max-width

  • width 与 max-width 同时设置时,取的是两者中最小的值。

  • width 与 min-width 同时设置时,取的是两者中最大的值。

  • min-width 与 max-width 同时设置时,取的是 min-width

  • 当三者同时设置时。

1:计算min-width与width中的最大值, 若两者中最大值为min-width 则取的是 min-width; 若最大值为width 则再进行第2步比较。

2:计算min-width与max-width中的最大值, 取的是两者中最大的值。伪伪代码如下 Math.max(minWidth, width) == minWidth ? minWidth: Math.min(width, maxWdith)

弹性元素取值优先级由高到低:

  • max-width,max-height,min-width,min-height
  • flex-basis
  • width,height
  • 内容本身的size

flex布局子元素宽度超出父元素问题

问题:当flex子元素里的子元素的宽度过大,超出flex父元素时,设置flex:1并不能限制flex元素的尺寸:

image.png

解决方案: 1:子元素强行设置宽度,让子元素的宽度由flex:1属性来分配(在firefox浏览器中,失效) 2:子元素设置overflow不为visible