flex 布局

 

7.1 传统布局与flex布局

传统布局:

  • 兼容性好
  • 布局繁琐
  • 局限性,对移动端的支持不好

flex 唐兴布局

  • 操作方便,布局极为简单,移动端应用广泛
  • PC段浏览器支持情况较差
  • IE11或更低版本,不支持或仅部分支持

建议:

  • PC端页面,使用传统布局
  • 移动端页面或者不考虑兼容性问题的PC段页面布局,使用flex 弹性布局

7.2 爱的初体验

html 代码

<div>
    <span>10</span>
    <span>20</span>
    <span>30</span>
</div>

css 代码

<style>
body {
    background-color: #ccc;
}
div{
     80%;
    height: 200px;
    background-color: #000;
}
span{
    height: 100px;
    background-color: #fff;
}

</style>

mark

加入flex

为 div 加入如下 css 样式

mark

运行结果

mark

总结

  • 在为div设置 display:flex 之前,span元素的 display=inline
  • 在为div设置 display:flex 之后,span 元素的display=block,所以高度生效,但是因为宽度没有设置,故为内容宽度
  • 可见,通过为父元素设置 display:flex 子元素无论原来是什么元素,都会变成 block,但是宽度并不会占据父元素的100%,而且也不会独占1行

设置固定宽度

可以为span元素设置宽度

span{
     100px;
    height: 100px;
    background-color: #fff;
}

设置后,宽度会生效,但是,当调整浏览器宽度,默认情况下,span的宽度仍然会压缩

设置对齐方式

在 div 中加入如下代码

mark

运行结果

mark

设置平分

也可以不设置固定宽度,而是使用如下代码

span {
    /*  100px; */
    flex: 1;
    height: 100px;
    background-color: #fff;
}

此种设置三个span元素将会评分父元素的宽度

mark

7.3 布局原理

flex:flex box 的缩写

意为 弹性布局,用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex,但是我们不会变态到将 i 标签指定为 flex

  • 当我们将父盒子设置为flex后,子元素的float、clear、vertical-align 属性失效

采用Flex布局的元素,成为Flex容器(flex container),简称“容器”,它的所有子元素自动成为容器成员,成为Flex项目(flex item),简称“项目”

子元素可以横向排列,也可以纵向排列

mark

布局原理总结

通过给父盒子添加flex属性,来控制子盒子的位置和排列方式

7.4 容器常用属性

一下属性用于设置容器,也就是父盒子

  • felx-direction:设置主轴的方向,也就是项目横向排列还是纵向排列
  • justify-content:设置主轴上的子元素的排列方式
  • flex-wrap:设置子元素是否换行
  • align-content:设置侧轴上子元素的排列方式(多行)
  • align-items:设置侧轴上的子元素排列方式(单行)
  • flex-flow:复合属性,相当于同时设置了flex-directon 和 flex-wrap

7.4.1 flex-direction

在flex布局中,分为主轴和侧轴

默认情况下,水平方向为主轴,水平向右,垂直方向为侧轴,垂直向下

mark

flex-direction 属性可以改变默认的主轴设置

设置行为主轴

设置水平方向为主轴,项目从左向右排列

body {
    background-color: #ccc;
}

div {
    display:flex;
    /*设置容器的主轴为X轴,也就是行为主轴,此值为默认值*/
    flex-direction: row;
     800px;
    height: 400px;
    background-color: #000;
}

span {
     100px;
    height: 100px;
    background-color: #fff;
    border: 1px solid black;
}

设置主轴反转

反转主轴

设置水平方向为主轴,项目从右向左排列

只需要将如下代码

flex-direction: row;

修改为

flex-direction: row-reverse;

设置列为主轴

设置主轴为垂直方向,项目从上到下排列

设置 flex-direction 的值 column

flex-direction: column;

将上面的代码改为

flex-direction: column-reverse;

项目从下到上排列

总结

  • 主轴不是固定的
  • 项目永远沿主轴排列,所以设置主轴为水平方向,项目1行排列;设置主轴为垂直方向,项目1列排

7.4.2 justify-content

设置主轴上项目的排列方式

使用此属性之前,要确定主轴是哪一个,主轴不一样,设置的值也不一样

  • flex-start 默认值,从头部开始,如果主轴是x轴,则从左到右
  • flex-end 从尾部开始排列,如果主轴是y轴,则从又到左
  • center 在主轴居中对齐,如果主轴是x轴,则水平居中
  • spance-around 评分剩余空间
  • spance-between 先两边贴边,再评分剩余空间

7.4.2.1 X轴为主轴时

flex-start

body {
    background-color: #ccc;
}

div {
    display:flex;
    /*设置容器的主轴为X轴,也就是行为主轴,此值为默认值*/
    flex-direction: row;
    /* 设置项目从左到右排列 */
    justify-content: flex-start;
     800px;
    height: 400px;
    background-color: #000;
}

span {
     100px;
    height: 100px;
    background-color: #fff;
    border: 1px solid black;
}

mark

这与没设置 justify-content:flex-start 没有区别

修改 justiry-content 的值为 flex-end

flex-end

/* 设置项目从左到右排列 */
justify-content: flex-end;

mark

注意,这里仅仅是改变了项目的起始方向,并没有改变项目的排列顺序,而我们上面说的 flex-direction 的翻转会改变项目的排列顺序

将 justify-content 的值设置为 center,所有元素居中显示,两边编剧一致

center

justify-content:center;

mark

spance-around

justify-content:space-around;

问题:为什么明明是评分剩余空间,项目的中间距离,看起来是左侧两侧边距的2倍?

mark

注意:

  • 容器-所有项目宽度之和,就是主轴上剩余的空间,这里的平分是指项目之间的距离平分这些空间
  • 如果设置项目的flex:1,而不是设置项目的固定宽度,那么无论 justify-content 的值设置为什么,都没有效果,因为项目会自动占满整个容器宽度

space-between

justify-content:space-between;

mark

7.4.2.2 Y 轴为主轴

省略

7.4.3 flex-wrap

传统布局中,设置子盒子浮动后,如果1行占不下,会自动另起一行

但是在 flex 布局中,则不然

html 代码

<div>
    <span>10</span>
    <span>20</span>
    <span>30</span>        
    <span>40</span>
</div>

css 代码

body {
    background-color: #ccc;
}

div {
    display:flex;
    /*设置容器的主轴为X轴,也就是行为主轴,此值为默认值*/
    flex-direction: row;
    /* 设置项目从左到右排列 */
    justify-content:flex-start;
     500px;
    height: 400px;
    background-color: #000;
}
span {
     150px;
    height: 100px;
    background-color: #fff;
    border: 1px solid black;
}

我们发现,当1行站不下所有项目时,会自动缩小项目的宽度

如果不希望改变宽度,而是另起一行,只需要在容器中据加入如下设置即可

flex-wrap: wrap;

mark

问题:为什么两行之间的垂直间距这么大?

扩展

如果主轴为Y轴,则效果如下

mark

7.4.4 align-items

设置项目在侧轴上的排列方式

但是此属性适合项目为单行时

侧轴默认是Y轴,当然可以改变

  • flex-start 默认值,从上到下
  • flex-end 从下到上
  • center 挤在一起居中
  • stretch 拉伸

7.4.4.1 解决的问题

当前只能通过 justify-content 设置项目在主轴上的位置

div {
    display:flex;
    /*设置容器的主轴为X轴,也就是行为主轴,此值为默认值*/
    flex-direction: row;
    /* 设置项目从左到右排列 */
    justify-content:center;          
     500px;
    height: 400px;
    background-color: #000;
}

mark

无法设置项目在侧轴上居中,对于当前来说,侧轴是y轴,那么也就是设置垂直居中

有人可能想到做如下修改

flex-direction: column;

但这样只是修改了主轴为y轴

mark

当前属性就是用来解决这个问题的

7.4.4.2 设置侧轴居中

只需要在容器中加入

mark

效果

mark

问题:如果主轴为y轴呢?

mark

效果

mark

当然此属性的只也可以设置为其他几个

其他几个值都比较简单,稍微需要注意的是 stretch ,意思是拉伸,如果主轴是x轴,那么就会拉伸项目的高度与父元素一样高,但是项目不能设置固定高度,否则无效

7.4.5 align-content

设置侧轴上的子元素的排列方式

这与 align-items 相似,区别在于,此属性用来设置多行项目(也就是项目换行)时的排列方式,在单行项目下时没有效果的

  • flex-start 默认值,在侧轴的头部开始排列
  • flex-end 在侧轴的尾部开始排列
  • center 在侧轴的中间显示
  • space-around 子项在侧轴评分剩余空间
  • space=between 子项在侧轴先分布在两头,再平分剩余空间
  • stretch 设置子项元素高度平分父元素

flex-start

mark

思考,主轴为y轴时如何排列

flex-end

mark

center

mark

space-around

mark

space-between

mark

**align-items 和 align-content 对比

  • align-items 适用于单行情况下,只有上对齐,下对齐,居中和拉伸
  • align-content 适用于多行,单行下无效,可以设置对上对齐、下对齐、居中、拉伸一级平分剩余空间等
  •  

7.4.6 flex-flow

flex-direction 和 flex-wrap 的复合属性

flex-flow: column nowrap;

7.5 项目常见属性

  • flex 项目占的份数
  • align-self 控制子项自己在侧轴的排列方式,前面的align-items 和 align-content 是对所有子项应用相同的排列方式,而这个属性是对单个子项应用个性化的排列方式
  • order 定义项目的排列顺序(前后顺序)

7.5.1 flex

定义子项目分配剩余空间,用 flex 属性表示占多少分

  • 分配的容器的剩余空间会增加到元素的宽度上
  • 项目一旦设置固定宽度,就不会参与分配剩余空间
  • flex 的默认值为0,0就表示不参与分配剩余空间
  • 项目一旦设置了flex,就不能再设置固定宽度
  • 如果flex 的值为其他数字,则表示在分配剩余空间时所占的分数

圣杯效果

<!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>
    /* 圣杯布局
flex属性设置的时项目在分配剩余空间时所占的分数


     */
    div {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
     margin:0 auto;
      align-content: space-between;
       80%;
      height: 400px;
      background-color: #ccc;
    }

    span {     
      background-color: orange;
      border: 1px solid black;
    }
    span:nth-child(1){     
       100px;
    }
    span:nth-child(3){
       100px;
    }
    span:nth-child(2){
      flex: 1;
    }
  </style>
</head>

<body>
  <div>
    <span>10</span>
    <span>20</span>
    <span>30</span>
  </div>
</body>

</html>

按比例分配

<!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>
    /* 圣杯布局
flex属性设置的时项目在分配剩余空间时所占的分数


     */
    div {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
     margin:0 auto;
      align-content: space-between;
       80%;
      height: 400px;
      background-color: #ccc;
    }

    span {   
      height: 100px;  
      background-color: orange;
      border: 1px solid black;
    }
    span:nth-child(1){     
      flex:2;
    }
    span:nth-child(3){
     flex: 3;
    }
    span:nth-child(2){
      flex: 1;
    }
  </style>
</head>

<body>
  <div>
    <span>10</span>
    <span>20</span>
    <span>30</span>
  </div>
</body>

</html>

7.5.2 align-self

<!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>
    /* align-items:设置项目再侧轴上的排列方式
    注意:侧轴不是固定的,但是默认情况下,垂直方向为侧轴
    align-items 的值如下
    flex-start:默认值,设置项目在侧轴上从头部开始,如果侧轴为y轴,则头部为顶部;如果
    侧轴为x轴,则头部为左侧
    flex-end:设置项目在侧轴上从尾部开始,如果侧轴为y轴,则尾部为容器的底部;如果
    侧轴为x轴,则尾部为右侧
    center:居中
    stretch:拉伸,将项目的高度拉伸至容器的高度,前提时项目不能设置高度
     */
    div {
      display: flex;
      flex-direction: row;
      /*设置项目在主轴上的排列方式*/
      justify-content: flex-start;
      /* 设置所有项目在侧轴上的排列方式(单行) */
      align-items:center;
       700px;
      height: 400px;
      background-color: #ccc;
    }

    span {
       150px;
      height: 100px;
      background-color: orange;
      border: 1px solid black;
    }
    span:nth-child(2){
      /* 单独设置此项目在侧轴上靠头部排列 */
      align-self: flex-start;
    }
    span:nth-child(1){
      /* 单独设置此项目在侧轴上靠尾部排列 */
      align-self: flex-end;
    }
  </style>
</head>

<body>
  <div>
    <span>10</span>
    <span>20</span>
    <span>30</span>
  </div>
</body>

</html>
原文地址:https://www.cnblogs.com/wjlbk/p/12633420.html