flexbox布局是CSS3中新增的布局属性,但任何样式属性起作用的前提则是,它必须有对应的html结构。我们首先在html 文件中定义相应的结构,才能使用布局样式。我们简单地写一个ul li 列表,体验一个flex 布局的强大。新建一个index.html 书写结构,一个index.css 书写样式。
index.html , 为了以后便于说明,给每一个li 作了一个1,2,3 标记。
<ul> <li>1</li> <li>2</li> <li>3</li> </ul>
index.css, 主要是提供默认样式,以便后面进行操作。
ul { margin: 0; padding:0; width: 600px; margin: 100px auto; background: grey; } li { list-style: none; width: 100px; height: 100px; margin: 8px; text-align: center; line-height: 100px; font-size: 20px; } li:nth-child(1) { background: red; } li:nth-child(2) { background: green; } li:nth-child(3) { background: yellow; }
现在在html页面中展示如下:
基本的内容已经完成,现在可以使用flexbox了。使用flex布局,首先要定义一个flex容器。容器,容器,肯定是指父元素,因为它包含子元素,可以称之为容器,在我们这个例子中就是在ul,给ul设置怎样的样式才能使之成了flex 容器,那就是display: flex, 或display:inline-flex. 设为flex 或 inline-flex 都会使ul变成了flex容器,它们的区别是设置display:flex 后,ul 仍然是块级元素,独占一行,而display:inline-flex 则使ul 成了行内元素,可以和其他行内元素进行水平排列。我们可以在ul 后面添加一个span标签实验一个,html 修改如下
<ul> <li>1</li> <li>2</li> <li>3</li> </ul> <span>测试ul 是行内元素还是块级元素</span>
给ul添加dispaly: flex 属性:
ul { display: flex; /*增加 display: flex;属性*/ margin: 0; padding:0; width: 600px; margin: 100px auto; background: grey; }
可以看到页面如下,给ul 设置display:flex 后,ul仍然是块级元素
把ul 的display: flex 换成display:inline-flex, 页面展示如下:
display: inline-flex , 确实使ul变成了一个行内元素,在水平方向上进行排列。
不管设置成什么,ul 都成了flex容器,因为我们发现, li元素由原来的垂直排列变成了水平排列。这时元素li也有了另外一个名称,叫flex items(flex 项目)。flex容器中的每一个元素都称之为一个flex项目。 这就是flex布局中非常重要的两个概念: flex 容器和flex 项目。
当一个元素成为了flex容器后,它默认存在两根轴上,主轴(main axis)和 侧轴(cross axis), 它就是我们平常理解的水平轴和垂直轴,因为在一个平面中,只有这两根轴,flex布局也是在平面上布局,它也不例外,那为什么不叫水平轴和垂直轴?因为主轴的方向是不固定的,它即可以是水平方向,也可以是垂直方向。当主轴是水平方向时,侧轴就是重直方向,当主轴是垂直方向时,侧轴就是水平方向。 它有两种可能,所以不能简单称之为水平轴或垂直轴。
主轴是什么方向也很重要,因为它影响了flex 项目的排列。就像上图展示,如果主轴是水平方向,flex 项目就是水平方向依次排列。如果主轴是垂直方向,那么flex项目就会沿着垂直方向依次排列。所以当一个元素成为flex 容器时,我们首先要确定的就是主轴的方向。正好flex-direction属性提供这样的设置。
flex-direction 定义了主轴的方向,相应地也确定了侧轴的方向,因为只有这两个轴且它们是垂直关系。它有四个属性值:row || row-reverse || column || column-reverse。
row: 主轴为水平方向,元素从左边开始排列。
row-reverse: 主轴方向为水平方向,不过元素从右向左开始排列。
column: 主轴为垂直方向,元素从上到下排列。
column-reverse: 主轴为垂直方向,不过元素是从下向上排列。
reverse是反转的意思,row-reverse 就是表示,在row的基础进行反转,原来是从左到右排列,那么现在是从右到左, column-reverse 就表示从下到上。
它的默认值是row , 甚至我们不设置这个属性,它的值也是row. 这也就解释了上面,当我们只给ul 设置display:flex, 时,所有的li 横向排列。
除了flex-direction之外,还有5个属性可以用到flex 容器上,就是父元素上,它们是: flex-wrap, flex-flow, Justify-content, Align-items, Align-content。下面 我们一一介绍
flex-wrap: 它定义了当我们的flex项目非常多时,在flex容器中一行放不下时,元素怎么排列,到底换不换行。 它有三种属性值: nowrap, wrap 和wrap-reverse;
nowrap 是它的默认值,表示不换行,这么多项目始终在一行排列,这就导致了所有的项目都要进行缩小处理。
wrap 表示可以换行,那么一行放不下的元素,就会放到下一行,形成了多行。
wrap-reverse , 可能你已经猜到了,它也是表示可以换行,不过方向相反而已。
我们给ul 元素分加别添加 这三个属性试一试, 这时我们设置方轴方向为row, flex-drection: nowrap
ul { display: flex; /*增加 display: flex;属性*/ flex-direction: row; /*设置主轴方向*/ flex-wrap: nowrap; /*设置是否多行显示*/ margin: 0; padding:0; width: 600px; margin: 100px auto; background: grey; }
由于li元素也较少,能在一行放下,我们再写几个li, 使flex 项目在一行放不下。
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> </ul>
这时页面展示如下,在no-wrap 下,无论flex项目有多少,它都不会换行,每个项目只会进行缩小来适应整个容器的宽度。
现在把flex-wrap:nowrap 改成flex-wrap:wrap, 可以看到以下展示,两行显示,flex项目换行了。
现在再把flex-wrap: wrap 换成 flex-wrap: wrap-reverse, 可以看到 元素换行,且第一行在下面,对上面的图进行了反转
flex-flow: 它是上面两个属性的简写,flex-flow: flex-direction 的取值 flex-wrap 的取值, 如: flex-flow: row wrap, 这时就不介绍了。
Justify-content: 它定义了flex items 在主轴上怎样进行排列。 Flex-start , flex-end, center, space-between, space-around
Align-items 定义了flex items 在侧轴cross axis上怎么进行排列。 Flex-start , flex-end, center ,stretch, baseline. 默认取值 stretch. Baseline
Align-content: 只有在flex-warp: wrap 形成多行时才起作用。它和aling-item 设置,多行时,元素在侧轴上怎么排列。
用在单个flex 项目上的属性:Order || Flex-grow || Flex-shrink || Flex-basis
Order 顺序,重新排列每一个flex item 顺序。默认属性是0,也就是每一个flex items 按照它们在html中定义的结构进行排列。
Just content 定义的元素在主轴上怎么排列,是在容器的左边,右边还是中间。
Align items 定义的项目在侧轴上怎么排列。它有两个值strech base。Strech 就默认属性,如果我们的item 没有设置高度或高度为auto, 那么它会在侧轴方向上进行提伸,占满整个侧轴的空间。
Baseline 主要指的是如是flex-item 中有p , p标签中的下面对齐, 如果没有p标签,则元素的底部对齐。
Align self: 主要对一个元素在侧轴上的对齐方式进行设置,默认属性是auto,所以不设置的话,它跟align-item属性一致。 如果进行设置,它不会覆盖掉align-item属性。
单个flex item 属性的设置
Flex-basis:控制每一个flex-item默认尺寸大小,在其它属性之前,它和item的宽度或高度相互换,如果我们设置的主轴是水平方向flex-direction row, 它就和元素的宽度相互换,如果我们设置的主轴方向是垂直方向flex-direction column, 它就和元素的高度相互换。
Flex-grow: 它指的是当flex-item没有占满整个flex-contain 的空间时,每一个元素怎么变化,要不要变大去占据空间,grow 就是生长,长大的意思,它的默认值是0,不会进行变化。 这时我们把每一个flex-item的flex-grow值设为1, 可以看到它占满了整个flex container的空间, flex-grow 的值覆盖了width的值。 那么这个属性值1 代表什么呢/? 我们把所有的值都设为999, 它的形为和刚才设为1 没有什么区别。
现在我们把其中一个flex-item的值改为flex-grow 改为2, 可以发现这个元素变大了,再改3, 它更大了,从这里可以看出它不是一个绝对值,它是相对值,是某个元素相对其化元素的比例。当设置每一个项目的flex-grow 为1时,一共有6 个元素,那么就是6,整个flex-container会被分成6份,每一个flex-item 各占一份,所以都相同。如果我们其中一个flex-flow设为2. 还是6个元素,那么整个flex container 就分成1+1+2+1+1+1 = 7份,其余5个各1/7, 而第三个占2/7,所以第三个就相对变大了, flex-grow 设置的某个或某些项目相对于其他项目的比例。
Flex-shrink : shrink 收缩,当每一个flex item 的宽度总和超过 flex-contaier容器的时候,每一个项目都会进行收缩。它的默认值是1, 表示每一个元素都会比例收缩。 如果把某个元素的flex-shrink 设为0, 它就不会进行收缩。 如果把它设置3,和flex-grow 一样,它也是比例,每一个flex item收缩1, 它收缩3, 它比别的项目收缩更严重。
Flex: 是上面三个属性简写,像边框border属性一样。 Flex: flex-grow flex-shrink flex-basis
它的默认取值为0 1 auto,这和我们平时没有设置这个属性表现一致,flex-basis: auto 表示,它和元素的宽度或高度保持一致,flex-grow等于0, 表示 如果父元素有剩余空间,它并不会扩大,
Flex-shrink, 如果父元素空间不足,它会进行收缩。
现在我们设置两个元素,一个是flex: 2 1 300px; 一个是1 2 300px; 父元素的宽度为640px;正好放下这个元素。
现在我们看一下flex-shrink是怎么工作的?当我们把容器宽度改为430px; 整个容器损失了210px的空间,由于第一个元素的flex-shrink 是1, 第二个shrink是2, 所以这损失的210px, 分成了3份,第一个元素占1份,也就是70px, 所以第一个元素损失了70px,宽度变为了300-70 =230px; 第二个元素占两份,也就是140px, 所以第二个元素损失了140px;宽度变为了300-140= 160px; flex-grow 的工作原理也是一样,当我们把容器宽度增大到940px;时, 它多获得了300px的空间,每一个元素都会增大,由于第一个是flex-flow是2, 第二个flex-flow是1, 所以这多出来的300px, 也是分成了3份,第一个项目占2份,200px, 宽度增大到300+200 =500px; 第二个占1份,100px, 宽度增大到300+100 =400px;