css布局----flex弹性布局(移动端完美解决方案)

Flexible Box 模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。本文给出了 flexbox 的主要特性。

我们说 flexbox 是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度上的元素布局,一行或者一列。作为对比的是另外一个二维布局网格布局,以后会和大家讲到

目录

1,如何使用
2, Flexbox的两根轴线
3, Flex 容器
4,API以及用例

1,- 如何使用-因为css用法过于简单,所以先给大家介绍简单的使用方法,随后介绍一些重要的概念

    <style type="text/css">
        #flex-box {
            background: #ccc;
            display: flex;  /* display 属性规定元素应该生成的框的类型 ,我们是flex*/
            flex-direction: row; /* 接下来我们会讲到*/
        }
        #flex-box > div {
            background: #5990dc;
            margin: 20px;
            padding: 40px;
        }
    </style>
    <div id="flex-box">
        <div>block1</div>
        <div>block2</div>
        <div>block3</div>
    </div>

效果图如下:
image.png

2,- Flexbox的两根轴线

当使用 flex 布局时,首先想到的是两根轴线 — 主轴和交叉轴。主轴由 flex-direction 定义,另一根轴垂直于它。我们使用 flexbox 的所有属性都跟这两根轴线有关, 所以有必要在一开始首先理解它。

主轴

主轴由 flex-direction 定义,可以取4个值:

  • row
  • row-reverse
  • column
  • column-reverse
    如果你选择了 row 或者 row-reverse,你的主轴将沿着 inline 方向延伸。

如果你选择了 row 或者 row-reverse,你的主轴将沿着 **inline **方向延伸。

If flex-direction is set to row the main axis runs along the row in the inline direction.

选择 column 或者 column-reverse 时,你的主轴会沿着上下方向延伸 — 也就是 block 排列的方向。

If flex-direction is set to column the main axis runs in the block direction.

交叉轴

交叉轴垂直于主轴,所以如果你的flex-direction (主轴) 设成了 row 或者 row-reverse 的话,交叉轴的方向就是沿着列向下的。

If flex-direction is set to row then the cross axis runs in the block direction.

如果主轴方向设成了 column 或者 column-reverse,交叉轴就是水平方向。

If flex-direction is set to column then the cross axis runs in the inline direction.

理解主轴和交叉轴的概念对于对齐 flexbox 里面的元素是很重要的;flexbox 的特性是沿着主轴或者交叉轴对齐之中的元素。

Flex 容器

文档中采用了 flexbox 的区域就叫做 flex 容器。为了创建 flex 容器, 我们把一个容器的 display 属性值改为 flex 或者 inline-flex。 完成这一步之后,容器中的直系子元素就会变为 flex 元素。所有CSS属性都会有一个初始值,所以 flex 容器中的所有 flex 元素都会有下列行为:

  • 元素排列为一行 (flex-direction 属性的初始值是 row)。
  • 元素从主轴的起始线开始。
  • 元素不会在主维度方向拉伸,但是可以缩小。
  • 元素被拉伸来填充交叉轴大小。
  • flex-basis 属性为 auto。
  • flex-wrap 属性为 nowrap。

这会让你的元素呈线形排列,并且把自己的大小作为主轴上的大小。如果有太多元素超出容器,它们会溢出而不会换行。如果一些元素比其他元素高,那么元素会沿交叉轴被拉伸来填满它的大小。

Flex布局主要的API

display: flex; 规定元素应该生成flex的类型,直系子元素就会变为 flex 元素
flex-direction: row | column | row-reverse | column-reverse; 更改flex方向

为了更好地控制 flex 元素,有三个属性可以作用于它们:在使用这三个属性之前我们简单了解一下布局空白(available space)这个概念

image.png
flex-grow 定义了该元素的布局空白(available space)的基准值。 该属性的默认值是 auto 。此时,浏览器会检测这个元素是否具有确定的尺寸。 在上面的例子中, 所有元素都设定了宽度(width)为100px,所以 flex-basis 的值为100px。

如果没有给元素设定尺寸,flex-basis 的值采用元素内容的尺寸。这就解释了:我们给只要给Flex元素的父元素声明 display: flex ,所有子元素就会排成一行,且自动分配小大以充分展示元素的内容。

flex-shrink flex-grow 若被赋值为一个正整数, flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。这会使该元素延展,并占据此方向轴上的布局空白(available space)。如果有其他元素也被允许延展,那么他们会各自占据布局空白的一部分。

如果我们给上例中的所有元素设定 flex-grow 值为1, 容器中的布局空白会被这些元素平分。它们会延展以填满容器主轴方向上的空间。
flex-grow 属性可以按比例分配空间。如果第一个元素 flex-grow 值为2, 其他元素值为1,则第一个元素将占有2/4(上例中,即为 200px 中的 100px), 另外两个元素各占有1/4(各50px)。

flex-basis属性 flex-basis 指定了 flex 元素在主轴方向上的初始大小。如果不使用 box-sizing 来改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的宽或者高(取决于主轴的方向)的尺寸大小。"

这三个属性为了方便编码,我们一般都会混合着写在 flex 简写形式中:

    <style type="text/css">
        #flex-box {
            background: #ccc;
            display: flex;
            flex-direction: row;
        }
        #flex-box > div {
            flex: 1 1 auto;  /* 从左到右的参数依次为 flex-grow,flex-shrink,flex-basis */
            background: #5990dc;
            margin: 20px;
            padding: 40px;
        }
    </style>
    <div id="flex-box">
        <div>block1</div>
        <div>block2</div>
        <div>block3</div>
    </div>

我们来看看flex元素自适应后的效果
image.png

flex元素对齐和空间分配

align-items属性将所有直接子节点上的align-self值设置为一个组。 align-self属性设置项目在其包含块中的对齐方式。") 属性可以使元素在交叉轴方向对齐。
这个属性的初始值为stretch,这就是为什么flex元素会默认被拉伸到最高元素的高度。实际上,它们被拉伸来填满flex容器 —— 最高的元素定义了容器的高度。

你也可以设置align-items的值为flex-start,使flex元素按flex容器的顶部对齐, flex-end 使它们按flex容器的下部对齐, 或者center使它们居中对齐. 在实例中尝试——我给出了flex容器的高度,以便你可以看到元素在容器中移动。看看如果更改 align-items的值为下列值会发生什么:

  • stretch
  • flex-start
  • flex-end
  • center
<style type="text/css">
        #flex-box {
            height: 400px;
            background: #ccc;
            display: flex;
            flex-direction: row;
            align-items: center;   /* 这个时候flex元素就会在交叉轴的地方居中对齐 */
        }
        #flex-box > div {
            /* flex: 1 1 auto;  为了更方便查看效果,我们先注释 */
            background: #5990dc;
            margin: 20px;
            padding: 40px;
        }
    </style>
    <div id="flex-box">
        <div>block1</div>
        <div>block2</div>
        <div>block3</div>
    </div>
image.png

justify-content属性用来使元素在主轴方向上对齐,主轴方向是通过 flex-direction 设置的方向。初始值是flex-start,元素从容器的起始线排列。但是你也可以把值设置为flex-end,从终止线开始排列,或者center,在中间排列.

你也可以把值设置为space-between,把元素排列好之后的剩余空间拿出来,平均分配到元素之间,所以元素之间间隔相等。或者使用space-around,使每个元素的左右空间相等。

在实例中尝试下列justify-content属性的值:

  • stretch
  • flex-start
  • flex-end
  • center
  • space-around
  • space-between
<style type="text/css">
        #flex-box {
            height: 400px;
            background: #ccc;
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: center;  /* 结合align-items:center 和 justify-content: center 我们就能实现我们所说的垂直水平居中 */
        }
        #flex-box > div {
            /*flex: 1 1 auto;*/
            background: #5990dc;
            margin: 20px;
            padding: 40px;
        }
    </style>
    <div id="flex-box">
        <div>block1</div>
        <div>block2</div>
        <div>block3</div>
    </div>

最终效果:
image.png

最主要的flex用法介绍完了,目前几乎能兼容所有移动端(你要相信人们换手机的速度)

更详细的内容请参阅:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox