Flex布局及常见面试题

846 阅读5分钟

Flex布局及常见面试题

flex布局

前言

简单介绍下常用属性。想要学习请参考阮一峰-Flex 布局教程

flex

Flex是Flexible Box的缩写,意为”弹性布局”。

基本概念

  • 容器 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。
  • 轴 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

Flex项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

Flex属性分为两部分,一部分作用于容器称容器属性,另一部分作用于项目称为项目属性。

Flex容器属性

父容器与子容器

.box {
  display: flex; /* 或者 inline-flex */
}

父容器

父容器可以统一设置子容器的排列方式,子容器也可以单独设置自身的排列方式,如果两者同时设置,以子容器的设置为准。

  1. flex-direction [dəˈrekʃn] 设置主轴方向
    //  
    flex-direction: row | row-reverse | column | column-reverse
    
    • row:主轴沿着水平方向向右
    • row-reverse:主轴沿着水平方向向左
    • column:主轴变成Y轴方向,方向从上到下布局
    • column-reverse:主轴变成Y轴方向,方向从下到上
  2. justify-content [ˈdʒʌstɪfaɪ][ˈkɑːntent , kənˈtent]设置子容器沿主轴排列
    • flex-start:起始端对齐
    • flex-end:末尾段对齐
    • center:居中对齐
    • space-around:子容器沿主轴均匀分布,位于首尾两端的子容器到父容器的距离是子容器间距的一半。
    • space-between:子容器沿主轴均匀分布,位于首尾两端的子容器与父容器相切。
  3. align-items 设置子容器如何沿交叉轴排列 用于定义如何沿着交叉轴方向分配子容器的间距。
    • flex-start*:起始端对齐
    • flex-end:末尾段对齐
    • center:居中对齐
    • baseline:基线对齐,这里的 baseline 默认是指首行文字,即 first baseline,所有子容器向基线对齐,交叉轴起点到元素基线距离最大的子容器将会与交叉轴起始端相切以确定基线。
    • stretch:子容器沿交叉轴方向的尺寸拉伸至与父容器一致。 (不常用)
  4. flex-wrap
        // 换行| 不允许换行 | 逆向换行(以末尾为换行起点)
flex-wrap: wrap | nowrap | wrap-reverse
  1. flex-flow flex-direction 和 flex-wrap 的复合模式。
  • 单独设置flex-direction取值
flex-flow: row | column
  • 单独设置flex-wrap取值
flex-flow: wrap | nowrap | wrap-reverse
  • 同时设置两者取值
flex-flow: row wrap
flex-flow: column nowrap
  1. align-content 定义子容器在交叉轴的排列方式,也就是对齐方式
  • flex-start 起始端对齐
  • flex-end 末尾段对齐
  • center 居中对齐
  • space-between 等间距均匀分布
  • space-around 等边距均匀分布
  • stretch 拉伸对齐
  • baseline 基线对齐 两者区别: align-content 适用于多行,且在多行才生效

子容器

子容器是有弹性的(flex 即弹性),它们会自动填充剩余空间,子容器的伸缩比例由 flex 属性确定。 flex 的值可以是无单位数字(如:1, 2, 3),也可以是有单位数字(如:15px,30px,60px),还可以是 none 关键字。子容器会按照 flex 定义的尺寸比例自动伸缩,如果取值为 none 则不伸缩。

  1. flex-grow 设置扩展比例 子容器弹性伸展的比例,简单理解,就是把剩余的空间按比例分配给子容器。
  2. flex-shrink设置收缩比例 子容器弹性收缩的比例。简单理解,就是当你子容器超出的部分,会按照对应的比例给子容器减去对应的值。
  3. flex-basis 设置基准大小
  • 不伸缩的情况下,flex-basis给子容器设置大小才有作用。
  • 当主轴为横向时 flex-basis设置的大小为宽度,并且会覆盖witdh值
  • 当主轴为纵向时 flex-basis设置的大小为高度,并且会覆盖height值
  1. flex flex-grow flex-shrink flex-basis的简写
flex:1
flex:auto
  1. order 设置排列顺序

每个子容器的order属性默认为0 通过设置order属性值,改变子容器的排列顺序。 可以是负值,数值越小的话,排的越靠前。 6. align-self 单独设置子容器如何沿交叉轴排列

  • flex-start 起始端对齐
  • flex-end 末尾段对齐
  • center 居中对齐
  • baseline:基线对齐
  • stretch 拉伸对齐

常见前端Flex布局面试题

1. 实现水平垂直居中

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}
.parent {
    display: flex;
}
.child{
    margin:auto
}

2. flex:1 是什么意思? 可以取负数或百分数吗

  1. 一列固定 一列自适应
  2. 两边固定,中间自适应(圣杯布局)
  3. 正方形内对角线
.box {
  display: flex;
  justify-content: space-between;
}

.item:nth-child(2) {
  align-self: flex-end;
}

  1. 六面骰子布局
  2. 子容器等分及宽度计算

8. 怎么让flex布局最后一列表左对齐?

justify-content对齐问题描述

在flex布局中,justify-content属性可以控制列表的水平对齐方式。

如果最后一行列表个数不满,则会出现最后一行没有完全垂直对齐的问题

  1. 如果每一行列数是固定的

方法一:模拟space-between和间隙

.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);
  }

方法二:根据个数最后一个元素动态margin

.container {
   display:flex;
   jusrify-content:space-between;
   flex-wrap:wrap;
   }
.list {
  width: 24%; height: 100px;
  background-color:skyblue;
  margin-top:15px;
  }
.list:not(:nth-child(4n-1) {
  margin-right:calc(24% + 4% /3);
}
.list:not(:nth-child(4n-2) {
  margin-right:calc(48% +8% /3);
}

2. 如果每一子项宽度不固定 方法一:最后一项margin-right:auto

.container {
     display:flex;
     jusrify-content:space-between;
     flex-wrap:wrap;
     }
  .list {
    background-color:skyblue;
    margin-top:15px;
    }
  .list:last-child {
    margin-right:auto;
  }
  

方法二:创建伪元素并设置flex:auto 或 flex:1

.container {
   display:flex;
   jusrify-content:space-between;
   flex-wrap:wrap;
   }
.list {
  background-color:skyblue;
  margin-top:15px;
  }
.container::after {
  content:'';
  flex:auto;
}