网页元素一般分为 普通流,浮动流,定位流。其中普通流和浮动流在一个层级上,定位流>浮动流>普通流。
css布局方式有以下几种:
float布局position布局flex布局grid布局
一、float布局: none | left | right | inherit
1. Float 属性指定一个元素应沿其容器的左侧或右侧放置(容器的边框,或者碰到另外一个浮动元素),允许文本和内联元素环绕它,原本设计是为了实现文字环绕图片的效果(报纸上常见的效果)
2. float会将元素 inline-block化
某些情况下它会修改 display 值的计算值。如 block、inline 都会成为 inline-block。所以如果行内级元素设置float,是不需要再去设置 display 的,如:
span {
float: left;
display: inline-block; /* 多余的设置 */
}
3. 使用float(元素浮动)代表元素会脱离文档流(被移出正常的文档流),然后向左(float:left)或向右平移(float:right)
- 如果浮动元素的上一个兄弟元素是块级元素的,浮动元素直接在新的一行进行左右平移。
- 如果浮动元素的上一个兄弟元素是行内级元素的话,就涉及到行盒的情况了,那么就在当前行盒进行左右平移,且外顶部对齐当前行盒的顶部。当当前行不够,则换行向左或者向右浮动。
- 如果浮动元素比较多的话,会一个接一个(向左或者向右水平排放),直到填满容器一整行,之后换行至下一行。
4. float会导致**“浮动高度塌陷**”:
如果浮动元素的父元素没有设定高度,当其子元素浮动后,父元素就因为内部没有子元素撑起从而高度变为0;
从而就有清除浮动的几种方式。
二、position 布局: static,absolute, fixed, relative
- static: 默认值,任意
position: static;的元素不会被特殊的定位
2. absolute(绝对定位): 脱离文档流,相对与最近**position**不为**static**的父元素进行定位,可以使用left,right,top,buttom进行定位。
3. relative(相对定位): relative 不脱离文档流,相对于自己来定位的。relative 的元素尽管表面上看到它偏离了原来的位置,但它实际上在文档流中还是没变。根据top,right,bottom,left的值按照它理应所在的位置进行偏移,relative的“相对的”意思也正体现于此。
4. fixed: 脱离文档流,相对于浏览器窗口来进行定位的,top 、 right 、 bottom 和 left 属性都可用。
三、flex布局:
Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局
单元块被称之为 flex item,每个项目占据的主轴空间为 (main size), 占据的交叉轴的空间为 (cross size)
注意:当时设置 flex 布局之后,子元素的 float、clear、vertical-align 的属性将会失效。
(1). flex容器:
要实现flex布局,首先需要指定一个容器,任何一个容器内部的元素都恶意进行flex布局。任何一个容器都可以通过如下手段指定为flex容器:
.container {
display: flex | inline-flex; //可以有两种取值 块状或 行内的 flex 容器盒子
}
六种属性可以设置在容器上,它们分别是:
-
flex-direction
-
flex-wrap
-
flex-flow
-
justify-content
-
align-items
-
align-content
1. flex-direction: 决定主轴的方向(即项目的排列方向)
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
默认值为:row, 主轴为水平方向,起点在左端(左->右)。

与row相反的row-reverse:主轴为水平方向,起点在右端(右->左)

Colum:主轴为垂直方向 ,起点为上方(上->下)
Colum-reverse:主轴为垂直方向,起点是下方(下->上)

2. flex-wrap: 决定容器内项目是否可换行
注:以下例子默认主轴为水平方向
.container{
flex-wrap: nowrap | wrap | wrap-reverse
}
默认值:nowrap 不换行,即当主轴尺寸固定时,当空间不足时,项目尺寸会随之调整而并不会挤到下一行。

wrap:换行,即当项目主轴总尺寸超出容器时换行,项目会随之调整换到下一行。第一行在上方。

wrap-reverse: 换行,即当项目主轴总尺寸超出容器时换行,项目会随之调整换到下一行。第一行在下方。

3. flex-flow: flex-direction 和 flex-wrap 的简写形式,建议分开书写
.container {
flex-flow: <flex-direction> || <flex-wrap>;
}
4. justify-content:定义了项目在主轴的对齐方式。
.container{
justify-content: flex-start| flex-end|center|space-around|space-between|space-evenly|stretch
}
建立在主轴为水平方向时测试,即 flex-direction: row
默认值**flex-start:**左对齐

flex-end: 右对齐

center: 水平居中

space-around: 每个项目两侧的间隔相等,所以项目之间的间隔比项目与边缘的间隔大一倍。

space-between: 两端对齐,每个项目中间间隔相等两端对齐,即剩余空间等分成间隙。

**space-evenly: **
元素会被拉伸以适应容器的大小
5. align-items: 定义了项目在交叉轴上的对齐方式
.container{
align-items: flex-start| flex-end|center| baseline | stretch
}
默认stretch:当项目未设置高度或者设置为auto时,将占满整个容器的高度(容器高度设置为100px,则项目高度为100px)

**flex-start:**交叉轴起点对齐,假设容器高度设置为 100px,而项目分别为 20px, 40px, 60px, 80px, 100px, 则如下图显示。

**flex-end:**交叉轴终点对齐,假设容器高度设置为 100px,而项目分别为 20px, 40px, 60px, 80px, 100px, 则如下图显示。

center: 交叉轴中点对齐

**baseline:**项目以第一行文字基线对齐

6. align-content: 定义了多根轴线的对齐方式,如果项目只有一根轴线,那么该属性将不起作用。
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
当你 flex-wrap 设置为 nowrap 的时候,容器仅存在一根轴线,因为项目不会换行,就不会产生多条轴线。
当你 flex-wrap 设置为 wrap 的时候,容器可能会出现多条轴线,这时候你就需要去设置多条轴线之间的对齐方式了。
默认stretch:项目未设置宽度或者height:auto时,项目的高度平分多条轴线垂直方向上的空间。

当设置了高度,则高度不会撑开,但是项目还是会平分垂直方向的空间。

flex-start: 多条轴线在交叉轴上的起点对齐

flex-end: 多条轴线在交叉轴上的终点对齐。

**center:**多条轴线在交叉轴的中间对齐

**space-around:**每个轴线两侧的间隔相等,所以轴线中间的间隔会比边缘大一倍。

**space-between:**轴线两端对齐,每条轴上中间间隔相等,即剩余空间等分成间隙。

(2)Flex 项目(Flex item)
有六种属性可运用在 item 项目上:
- order
- flex-basis
- flex-grow
- flex-shrink
- flex
- align-self
**1. order:可以定义项目的排列顺序,数值越小,排列越靠前。**默认值为 0,数值可以为负数。
.item{
order: <Number>
}

2. flex-basis: 定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间
.item {
flex-basis: <length> | auto;
}
默认值:auto,即项目本来的大小, 这时候 item 的宽高取决于 width 或 height 的值
当主轴为水平方向的时候,当设置了 flex-basis,项目的宽度设置值会失效,flex-basis 需要跟 flex-grow 和 flex-shrink 配合使用才能发挥效果。
- 当 flex-basis 值为 0 % 时,是把该项目视为零尺寸的,故即使声明该尺寸为 140px,也并没有什么用。
- 当 flex-basis 值为 auto 时,则跟根据尺寸的设定值(假如为 100px),则这 100px 不会纳入剩余空间。
3. flex-grow: 定义项目的放大比例(伸张因子)
.item{
flex-grow: <Number>
}
默认值为 0,即如果存在剩余空间,也不放大.
所有的项目都以 flex-basis 的值进行排列后,仍有剩余空间,那么这时候 flex-grow 就会发挥作用了。

当容器的宽度不够,且flex-wrap:nowrap,则flex-grow不生效
4. flex-shrink: 定义了项目的缩小比例(收缩因子)
.item{
flex-shrink:<number>
}
默认值: 1,即如果空间不足,该项目将缩小,负值对该属性无效。当所有项目的宽度总和超过容器宽度,也未设置flex-shirnk,则会整体按同等比例缩小。

如果一个项目的 flex-shrink 属性为 0,其他项目都为 1,则空间不足时,前者不缩小
5. flex: flex-grow, flex-shrink 和 flex-basis的简写
.item{
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
flex 的默认值是以上三个属性值的组合。假设以上三个属性同样取默认值,则 flex 的默认值是 0 1 auto。
关于 flex 取值,还有许多特殊的情况,可以按以下来进行划分:
- 当 flex 取值为一个非负数字,则该数字为 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%,如下是等同的:
.item {flex: 1;}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
- 当 flex 取值为 0 时,对应的三个值分别为 0 1 0%
.item {flex: 0;}
.item {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 0%;
}
- 当 flex 取值为一个长度或百分比,则视为 flex-basis 值,flex-grow 取 1,flex-shrink 取 1,有如下等同情况(注意 0% 是一个百分比而不是一个非负数字)
.item-1 {flex: 0%;}
.item-1 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
.item-2 {flex: 24px;}
.item-2 {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 24px;
}
- 当 flex 取值为两个非负数字,则分别视为 flex-grow 和 flex-shrink 的值,flex-basis 取 0%,如下是等同的:
.item {flex: 2 3;}
.item {
flex-grow: 2;
flex-shrink: 3;
flex-basis: 0%;
}
- 当 flex 取值为一个非负数字和一个长度或百分比,则分别视为 flex-grow 和 flex-basis 的值,flex-shrink 取 1,如下是等同的:
.item {flex: 11 32px;}
.item {
flex-grow: 11;
flex-shrink: 1;
flex-basis: 32px;
}
建议优先使用这个属性,而不是单独写三个分离的属性。
注:在同一时间,flex-shrink 和 flex-grow 只有一个能起作用,空间足够时,flex-grow 就有发挥的余地,而空间不足时,flex-shrink 就能起作用。
当flex-wrap 的值为 wrap | wrap-reverse 时,表明可以换行,既然可以换行,一般情况下空间就总是足够的,即可以使用使用 flex-grow ,flex-shrink 当然就不会起作用,
当flex-wrap值为nowrap,且子项宽度和不及父容器宽度时,flex-grow 会起作用,子项会根据 flex-grow 设定的值放大(为0的项不放大), 且子项宽度和超过父容器宽度时,flex-shrink 会起作用,子项会根据 flex-shrink 设定的值进行缩小(为0的项不缩小)。但这里有一个较为特殊情况,就是当这一行所有子项 flex-shrink 都为0时,也就是说所有的子项都不能缩小,就会出现讨厌的横向滚动条
6. align-self: 允许单个项目有与其他项目不一样的对齐方式
单个项目覆盖 align-items 定义的属性
默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
例:容器 align-items 设置为 flex-start,而第三个项目align-self为flex-end即会出现如下图的情况。

四、grid布局
网格布局(Grid)是最强大的 CSS 布局方案。
它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置了。
Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局
指定一个容器采用网格布局。默认情况下,容器元素都是块级元素,但也可以设成行内元素。
.contaier{ display: grid | inline-grid; }

.contaier{
display: inline-grid;
}

注意,设为网格布局以后,容器子元素(项目)的
float、display: inline-block、display: table-cell、vertical-align和column-*等设置都将失效。
容器指定了网格布局以后,接着就要划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
指定了一个三行三列的网格,列宽和行高都是100px。除了使用单位,也可以设置百分比。

repeat:
.container {
display: grid;
grid-template-columns: repeat(3, 33.33%);
grid-template-rows: repeat(3, 33.33%);
}
使用repeat(number, 百分比)也能达到上面效果。
auto-fill
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
}
//表示每列宽度100px,然后自动填充,直到容器不能放置更多的列。
fr关键字:代表比例关系
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
//代表第一列与第二列比例相同
.container {
display: grid;
grid-template-columns: 1fr 2fr;
}
//代表第二列比例比第一列大一倍
auto 关键字:自已决定长度
grid-template-columns: 100px auto 100px;