布局(layout)是指:
- 确定内容的大小和位置的算法。
- 依据元素、容器、兄弟节点和内容等信息来计算。
CSS中布局的分类:
- 常规流:包括行级、块级、表格布局、弹性(Flex)布局、网格(Grid)布局;
- 浮动(float)布局;
- 绝对定位布局
下面将汇总CSS中的几种经典布局技巧:
- 弹性(Flex)布局
- 网格(Grid)布局
- 绝对定位布局
1. 弹性(Flex)布局
2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。Flex布局将成为未来布局的首选方案。
Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为Flex布局。
.box{
display: flex;
}
行内元素也可以使用Flex布局:
.box{
display: inline-flex;
}
注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
1.1 基本概念
采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
1.2 相关属性及操作实践
以下6个属性设置在容器上:
- flex-direction:决定主轴的方向(即项目的排列方向)。
操作实践:
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
- flex-wrap:默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
操作实践:
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}
- flex-flow:flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
操作实践:
.box {
flex-flow: <flex-direction> <flex-wrap>;
}
- justify-content:justify-content属性定义了项目在主轴上的对齐方式。
操作实践:
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
- align-items:align-items属性定义项目在交叉轴上如何对齐。
操作实践:
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
- align-content:align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
操作实践:
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
2. 网格(Grid)布局
网格是一组相交的水平线和垂直线,它定义了网格的列和行。
CSS 提供了一个基于网格的布局系统,带有行和列,可以让我们更轻松地设计网页,而无需使用浮动和定位。
以下是一个简单的网页布局,使用了网格布局,包含六列和三行:
当一个 HTML 元素将 display 属性设置为 grid 或 inline-grid 后,它就变成了一个网格容器,这个元素的所有直系子元素将成为网格元素。
操作实践:
.grid-container {
display: grid;
}
2.1 网格单元
一个网格单元是在一个网格元素中最小的单位, 从概念上来讲其实它和表格的一个单元格很像。现在再看回我们前面的一个例子, 一旦一个网格元素被定义在一个父级元素当中,那么他的子级元素将会排列在每个事先定义好的网格单元中。在下面的图中,我会将第一个网格单元作高亮处理。
2.2 网格区域
网格元素可以向行或者列的方向扩展一个或多个单元,并且会创建一个网格区域。网格区域的形状应该是一个矩形 - 也就是说你不可能创建出一个类似于"L"形的网格区域。下图高亮的网格区域扩展了2列以及2行。
2.3 网格线
列与列,行与行之间的交接处就是网格线。
Grid 会为我们创建编号的网格线来让我们来定位每一个网格元素。
例如下面这个三列两行的网格中,就拥有四条纵向的网格线(灰色圆圈标记),以及三条横向的网格线(黑色圆圈标记)。
网格元素设置时可以参考这些行号。
下图则定义了四条纵向的网格线,以及四条横向的网格线:
网格线的编号顺序取决于文章的书写模式。在从左至右书写的语言中,编号为 1 的网格线位于最左边。在从右至左书写的语言中,编号为 1 的网格线位于最右边。
接下来我使用了 grid-column-start, grid-column-end, grid-row-start 和 grid-row-end 属性来演示如何使用网格线。
以下实例我们设置一个网格元素的网格线从第一列开始,第三列结束:
操作实践:
.item1 {
grid-column-start: 1;
grid-column-end: 3;
}
以下实例我们设置一个网格元素的网格线从第二行开始,第三行结束:
操作实践:
.item1 {
grid-row-start: 2;
grid-row-end: 3;
}
3. 绝对定位布局
CSS中Position属性值为absolute 和 fixed 统称为绝对定位。
3.1 absolute:元素会脱离文档流,如果设置偏移量,会影响其他元素的位置定位
只给第五个box设置absolute:
说明:元素在没有定义宽度的情况下,宽度由元素里面的内容决定,效果和用float方法一样。
3.2 absolute定位原理剖析:
(1)在父元素没有设置相对定位或绝对定位的情况下,元素相对于根元素定位(即html元素)(是父元素没有)。
(2)父元素设置了相对定位或绝对定位,元素会相对于离自己最近的设置了相对或绝对定位的父元素进行定位(或者说离自己最近的不是static的父元素进行定位,因为元素默认是static)。