Flex布局讲解

目录

  • 一、什么是Flex布局?
  • 二、Flex的基本概念
  • 三、Flex的语法规则
    • 1. Flex容器属性
      • (1). flex-direction
      • (2). flex-wrap
      • (3). flex-flow
      • (4). justify-content
      • (5). align-items
      • (6). align-content
    • 2. Flex元素项属性
      • (1). order
      • (2). flex-grow
      • (3). flex-shrink
      • (4). flex-basis
      • (5). flex
      • (6). align-self
  • 总结

本文所述内容主要参考自阮一峰的 Flex 布局教程:语法篇,感兴趣的可以点击链接阅读原文。作者还有一篇关于Flex布局的实例篇,写的非常通俗易懂,欢迎参考: Flex 布局教程:实例篇。

一、什么是Flex布局?

Flex布局是 Flexible box(弹性盒子)的缩写,因此常被称作“弹性布局”,它是对传统盒模型的补充和增强。在传统的盒模型中,布局盒子与子元素的关联性较弱,概念性地说,布局盒子只是为内部元素提供了布局边界。比如某个div内包含了3个左浮动的子元素(为了从视觉上区分三个子元素,我们设置了10像素的间距):

<style>
  #container {
      
  	background-color: #F5F5D5;
  }
  .inner-element {
      
    display: inline-block;
    width: 100px;
    height: 100px;
    float: left;
    margin-left: 20px;
    background-color: #E64A19;
  }
style>
<div id="container">
  <div class="inner-element">内部元素1div>
  <div class="inner-element">内部元素2div>
  <div class="inner-element">内部元素3div>
  <div style="clear: both;">div>
div>

Flex布局讲解_第1张图片
而在实际开发中,一个很常见的需求是,让这3个元素自动填充盒子中剩余的空白,即下面的效果:
Flex布局讲解_第2张图片
在传统的盒模型中,由于盒子只为子元素提供布局边界,而没有提供像剩余布局空间这样的信息,所以上面的效果只能通过复杂的js计算出来。而通过js来计算布局,不仅会增加js引擎的执行成本,还可能造成重绘甚至重排,影响网页性能。

传统盒模型中的布局盒子就像一道无形的屏障,内部元素只有“撞到”它的边界时,才知道它的存在。这种以子元素为布局实体的方式使得自适应布局很难实现。为此,我们需要一种更灵活的,能够为内部元素提供更多排列规则的布局方式。Flex布局就是这样一种新的布局方式。

Flex布局是从外部盒子的角度出发,来动态安置内部的子元素。在必要的情况下,它还可能对子元素进行一定的压缩或拉伸,以满足布局的需要。除了这些,Flex布局还会在盒子的大小发生变化时,重新计算内部子元素的布局,这是由CSS布局引擎自动完成的,所以性能非常高。此外,启用了Flex布局的盒子会自动生成一个BFC(Block formatting context,块格式化上下文),使得其内部布局的变化不会对外部造成影响,所以Flex布局得到了很广泛的应用。比如上面的布局,只需要以下几条样式声明即可(省略了背景颜色等非关键样式):

<style>
  /* 定义弹性盒子 */
  #container {
      
    display: flex;  /* 启用flex布局 */
    jsutify-content: space-between;  /* 自动分配空白 */
  }
  .inner-element {
      
    width: 100px;
  }
style>

Flex布局能实现的效果远不止这样,下面我们就来深入了解Flex布局。

二、Flex的基本概念

首先我们先来理解Flex布局中一些重要的概念,它们是我们理解Flex布局的基础。

启用了Flex布局的元素称为Flex容器(Flex container),简称“容器”,它内部的每个直接子元素称为元素项(Flex item)。一个Flex布局描述的就是每个元素项在该容器内是如何放置的。以下是Flex布局示意图(图片来自阮一峰教程):
Flex布局讲解_第3张图片
Flex布局内的各个元素项采用线性排列的方式。这里所说的线性,既可以是水平方向,也可以是垂直方向,两个方向都支持逆序排列。沿着元素项排列方向上的轴线我们称为主轴(即main axis,注意,主轴既可能是水平方向,也可能是垂直方向);而主轴垂直方向上的轴线我们称为交叉轴(即cross axis)。

主轴的开始位置我们称为main start(即主轴起点);主轴的结束位置我们称为main end(即主轴结束点);同样的,交叉轴的起点我们称为cross start(交叉轴起点);交叉轴的终点我们称为cross end(交叉轴结束点)。

容器内的每个元素项都有一定的宽高,它在主轴方向上所占的长度称为main size;它在交叉轴上所占的长度则称为cross size。默认情况下,元素项沿主轴方向排列,不会换行(排列不下时元素项可能会被压缩)。

以上概念对于理解和使用Flex布局非常重要,接下来我们来看Flex相关的语法。

三、Flex的语法规则

Flex的语法规则分为两类,一类是应用于Flex容器,另一类是应用于Flex的元素项,下面分别介绍:

1. Flex容器属性

Flex容器支持6个属性:

  • flex-direction,排列方向。
  • flex-wrap,换行方式。
  • flex-flow,以上两个属性的简写。
  • justify-content,元素项在主轴方向上的对齐方式,注意,主轴可能沿水平方向或竖直方向。
  • align-items,元素项在交叉轴方向上的对齐方式。
  • align-content,定义多条轴线的对齐方式。只有在允许换行的情况下才会存在多条轴线,如果只有一条轴线,则该属性不起作用。

依次来看这6个属性:

(1). flex-direction

定义元素项的排列方向,即主轴方向,可能有四个值:

  • row(默认值),沿水平方向排列,从左到右。
  • row-reverse,沿水平方向逆序排列,从右到左。
  • column,沿垂直方向排列,从上到下。
  • column-reverse,沿垂直方向逆序排列,从下往上。

四种排列方式的示意图如下:
Flex布局讲解_第4张图片

(2). flex-wrap

定义元素项的换行方式,当元素项在一行内排列不下时生效。该属性有三个值:

  • nowrap(默认),不换行。此时元素项会被压缩,以使其能排列在一行内。
    Flex布局讲解_第5张图片
  • wrap,换行。此时元素项会向下一行顺序排列。
    Flex布局讲解_第6张图片
  • wrap-reverse,换行并翻转行序。此时元素项会发生换行,但新的行在旧行的上面(或左面)。
    Flex布局讲解_第7张图片

(3). flex-flow

该属性是flex-directionflex-wrap的简写,默认值是:flex-flow: row nowrap。语法为:

.box {
     
  flex-flow:  || ;
}

(4). justify-content

定义元素项在主轴上的对齐方式。该属性支持5种对齐方式(假设主轴为从左到右):

  • flex-start(默认),左对齐(即与main-start对齐)。
  • flex-end,右对齐。
  • center,居中。
  • space-between,两端对齐,即空白只被分配到元素项之间,此时两端没有空白。
  • space-around,每个元素项两侧的间隔相等,此时元素项之间的间隙比两侧的间隙大一倍。
    Flex布局讲解_第8张图片
    根据图例我们再理解一下space-betweenspace-aroundspace-between的含义是空白位于元素项之间,这里有三个元素项,因此有两个间隙,它们会平分主轴上的剩余空间。space-around的含义是空白位于元素项两侧,这里有三个元素项,因此需要将剩余空间平分为6份,这就不难理解,为什么元素项之间的间隙宽度是两侧宽度的2倍。

(5). align-items

定义元素项在交叉轴上的对齐方式。该属性也支持5种对齐方式:

  • flex-start,与交叉轴的起点对齐。
  • flex-end,与交叉轴的终点对齐。
  • center,与交叉轴的中心对齐。
  • baseline,与元素项第一行文字的基线对齐。
  • stretch(默认),如果元素项未设置高度或设为auto,则元素项会占满整个高度。
    Flex布局讲解_第9张图片

(6). align-content

定义多根轴线的对齐方式,如果该项目只有一根轴线,那么该属性不起作用。该属性支持6个值:

  • flex-start,与交叉轴的起点对齐。
  • flex-end,与交叉轴的终点对齐。
  • center,与交叉轴的中点对齐。
  • space-between,与交叉轴的两端对齐,轴线之间平分剩余间隔。
  • space-around,每根轴线两侧的间隔相等,同样的,轴线之间的间隔会比两侧大一倍。
  • stretch,轴线拉伸占满整个交叉轴。
    Flex布局讲解_第10张图片

2. Flex元素项属性

Flex元素支持6个属性:

  • order,定义元素项的排列顺序。
  • flex-grow,定义元素项的放大比例。
  • flex-shrink,定义元素项的缩小比例。
  • flex-basis,定义在计算主轴剩余空间前,该元素项所占有的长度基准,默认auto,即元素项本身的长度。
  • flex,它是flex-growflex-shrinkflex-basis三个属性的简写。
  • align-self,单独设置某个元素项的对齐方式,它用于覆盖容器上为每个元素项设置的align-items属性。

(1). order

定义每个元素项的顺序,类型为整数(允许负数),元素项将按照order的值从小到大依次排列。默认情况下,每个元素项的order值都是0,所以会按书写顺序依次排列。例如:

<div style="display: flex;">
  <div style="order: 1;">元素项1div>
  <div style="order: 1;">元素项2div>
  <div style="order: 0;">元素项3div>
div>

此时第三个元素项会被放置在最前面,而前两个由于order值相等,因此会接着按序排列。

(2). flex-grow

定义元素项的放大比例,默认为0,即如果存在剩余空间,元素项也不会被放大。

当该属性的值不为0时,元素项将按与其他元素项的放大比例来分配剩余空间。

例如,现在有三个元素项,它们的flex-grow均为1。那么当容器内有剩余的空间时,三个元素项将分别得到1/(1+1+1),即三分之一的剩余空间,即,三个元素项会等分剩余空间。而假如三个值分别为1、2、1,则第一个和第三个会分配1/(1+2+1),即四分之一的剩余空间,第二个元素会得到四分之二的剩余空间,所以它的放大比例是另外两者的2倍。很容易理解,当放大比例被设置为0时,该元素项不会被放大。
Flex布局讲解_第11张图片

(3). flex-shrink

定义了元素项的缩小比例,默认为1,即如果空间不足,各个元素项将等比例缩小。如果某一项的值设置为0,则它不会被缩小。

整个缩小的计算过程是这样的:

  1. 计算出各个元素项的总长度
  2. 用元素项的总长度减去容器的实际长度,这个长度差就是需要消减的长度值
  3. 按照设置的缩小比例,来分配各个元素项需要缩小的实际长度

如现在有4个元素项,长度均为100像素,而Flex容器的长度只有300像素,并且flex-wrap设置为不换行。显然,这四个元素项需要压缩后才能放进容器内。我们来计算需要压缩的长度值:

100px * 4 - 300px = 100px

即必须让四个元素项压缩总计100像素的长度时,它们才能被正确放进容器内。假设四个元素项的flex-shrink均设置为1,那么它们将按1:1:1:1的比例来分配这100像素,于是,最终每个元素项被压缩25像素。同理,假如它们的flex-shrink值分别为2、1、1、1,则第一个元素项会被压缩40像素,其他的被压缩20像素(按照2:1:1:1分配这100像素)。如果某一项被设置为0,则不会被压缩。
Flex布局讲解_第12张图片

(4). flex-basis

定义元素项所占的主轴空间大小。默认情况下,浏览器会根据元素项的实际宽高计算它占有主轴空间的长度,但是修改该值即可使元素占有固定的空间。

该值的默认值为auto,即元素项本身的宽或高。把该值设置成如下值:

flex-basis: 200px;

可以使该元素项在主轴空间上始终占有200像素,而不管它的实际宽高。

(5). flex

它是flex-growflex-shrinkflex-basis这三个属性的简写。三个属性的默认值分别为:0 1 auto,即在空间剩余时默认不放大,空间不足时等比例缩小,并以其实际宽高计算所占主轴的空间。

(6). align-self

用于为单个元素项设置交叉轴上的对齐方式。

容器的align-items可以为每个元素项设置统一的交叉轴对齐方式,但是为某个元素项设置align-self可以使其拥有与其他元素项不同的对齐方式,取值与align-items是一致的。如:

.container {
     
  display: flex;
  align-items: flex-start;
}

#item3 {
     
  align-self: flex-end;
}

Flex布局讲解_第13张图片

总结

本文主要是讲解了Flex布局的基本语法,关于Flex的应用,可以参考阮一峰老师的博客原文:Flex 布局教程:实例篇。

你可能感兴趣的:(h5+css3,Flex)