CSS布局方法包括定位布局、浮动布局、弹性布局,通过这些布局方式,可以玩出各种不同的花样。
定位布局
定位布局通过position
属性来实现。
position: static
static
是默认值,是静态定位,就是元素出现在正常的元素流中。
position: relative
relative
是相对定位。在一个相对定位的元素上设置top
,left
,bottom
,right
属性会让它偏移其正常位置(如果不设置,则保持原位置不变)。但是其他元素不会受它的影响(即其他元素不会去弥补相对定位的元素偏移后的空隙位置)。
position: absolute
absolute
是绝对定位,它会相对于最近的“positioned”祖先元素定位(即position
值不是static
的元素)。如果没有“positioned”元素,那么它会相对于body
来定位。
position: fixed
fixed
是固定定位。固定定位的元素会相对于视窗来定位,意味着即使页面滚动,它还是会停留在相同的位置。
固定定位的元素会脱离文档流,也就是它原有的位置不会被保留。
position: sticky
粘性定位。最开始会像relative
那样对原来的位置进行偏移,一旦超过一定的阈值之后,就会作为fixed
定位,对于视窗进行定位。
浮动布局
浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边缘位置。
如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其他浮动块向下移动,直到有足够的空间。如果浮动元素的高度不同,那么它们向下移动时可能会被其他浮动元素“卡住”。
float
布局最开始是为了实现文字环绕而设计的。
但浮动元素并不仅仅实现这一的效果。浮动元素会在浮动层上面进行排布,原先文档流中的元素位置会被删除。但是浮动元素的浮动层部分会把补上来的元素的文字挤出去。
这是因为设置浮动的元素会形成BFC,并且元素的宽度不再适应父元素宽度,而是适应自身内容宽度。
清除浮动
clear
属性规定元素的哪一边不可以有浮动元素。
none
: 两边都可以有浮动元素left
:左边不可以有浮动元素right
:右边不可以有浮动元素both
:两边都不可以有浮动元素inherit
:继承父元素的clear
属性
clear
属性通常是和另一个被设置为浮动的元素搭配使用的。比如元素A设置了float:left
,那个设置clear:left
能让元素B不会和元素A发生重合,而是出现在元素A的下方,但元素A的浮动位置不会发生改变。
弹性布局
弹性布局能为盒模型提供很大的灵活性。定义了flex的容器是一个可伸缩容器,容器本身会根据容器中的元素动态设置资深大小,当容器被设置一个大小时,将会自动调整容器中的元素适应新大小。
Setup
所有的容器都可以指定为flex布局:
1 | .box { |
行内元素也可以使用flex布局:
1 | .box { |
webkit内核的浏览器要加上-webkit
前缀
1 | .box { |
设为Flex布局后,子元素的float
,clear
和vertical-align
属性均失效。
基本概念
设置为Flex的元素叫做Flex容器(flex container)。它的子元素被称为Flex项目(flex item)。
容器默认存在两条轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴开始的位置叫做main start
,结束位置叫做main end
,交叉轴的开始位置叫做cross start
,结束位置叫做cross end
。
单个项目占据的主轴空间叫做main size
,占据的交叉轴空间叫做cross size
。
容器属性
flex-direction
决定主轴的方向(即项目排列方向)1
2
3.box {
flex-direction: row | row-reverse | column | column-reverse;
}flex-wrap
如果一行排不下,如何换行1
2
3.box {
flex-wrap: nowrap | wrap | wrap-reverse; /* 不转行 | 转行,第一行在上 | 转行,第一行在下 */
}flex-flow
flex-direction
和flex-wrap
的缩写,默认是row nowrap
justify-content
项目在主轴上的对齐方式1
2
3.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}align-items
项目在交叉轴上如何对齐1
2
3.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}align-content
多根轴线的对齐方式1
2
3.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
项目属性
order
项目的排列顺序,数值越小,排列越靠前flex-grow
项目的放大比例(默认为0,按比例分配剩余空间)flex-shrink
项目的缩小比例,默认为1flex-basis
分配多余空间之前,项目占据的主轴空间align-self
运行单个项目有与其他项目不一样的对齐方式1
2
3.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
常见布局技巧
水平居中
行内元素
text-align: center
块级元素可以转换成行内元素,再
text-align: center
1
2
3<div class="wrapper">
<div class="test"></div>
</div>1
2
3
4
5
6
7
8
9
10
11
12.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
text-align: center;
}
.test {
width: 50px;
height: 50px;
background: red;
display: inline-block | inline-flex; //div转换成内联块级元素
}
块级元素
margin: auto
块级元素左右外边距
auto
可以实现水平居中。1
2
3
4
5
6
7
8
9
10
11.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
}
.test {
width: 50px;
height: 50px;
background: red;
margin: 0 auto;
}margin
计算1
2
3
4
5
6
7
8
9
10
11
12.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
}
.test {
width: 50px;
height: 50px;
background: red;
position: relative;
margin-left: calc(50% - 25px);
}弹性布局
1
2
3
4
5
6
7
8
9
10
11
12.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
display: flex;
justify-content: center;
}
.test {
width: 50px;
height: 50px;
background: red;
}绝对定位+
margin: auto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
position: relative;
}
.test {
width: 50px;
height: 50px;
background: red;
position: absolute;
left: 0;
right: 0;
margin: auto;
}
垂直居中
行内元素
line-height
设置为父容器的高度(适用于一行文字的情况)
块级元素
以下方法均达到下图效果:
1 | <div class="wrapper"> |
直接使用margin计算
1
2
3
4
5
6
7
8
9
10.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
}
.test {
width: 50px;
height: 50px;
margin-top: calc(50% - 25px);
}display:table-cell
+vertical-align: middle
1
2
3
4
5
6
7
8
9
10
11
12.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
display: table-cell;
vertical-align: middle;
}
.test {
width: 50px;
height: 50px;
background: red;
}flex
布局+align-items: center
1
2
3
4
5
6
7
8
9
10
11
12.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
display: flex;
align-items: center;
}
.test {
width: 50px;
height: 50px;
background: red;
}相对定位
1
2
3
4
5
6
7
8
9
10
11
12.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
}
.test {
width: 50px;
height: 50px;
position: relative;
top: 50%;
margin-top: -25px;
}绝对定位+负的
margin
1
2
3
4
5
6
7
8
9
10
11
12
13.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
position: relative;
}
.test {
width: 50px;
height: 50px;
position: absolute;
top: 50%;
margin-top: -25px;
}绝对定位 +
margin: auto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15.wrapper {
width: 200px;
height: 200px;
border: 1px solid black;
position: relative;
}
.test {
width: 50px;
height: 50px;
background: red;
position: absolute;
top: 0;
bottom: 0;
margin: auto;
}
两栏布局(一栏定宽,一栏自适应)
1 | <div class="left">定宽</div> |
目标效果:
1. 相对布局
1 | * { |
2. 绝对布局
1 | * { |
3. 浮动布局1-float
+ margin
1 | .left { |
4. 浮动布局: 两边都浮动
1 | .left { |
5. 弹性布局 + flex: 1
1 | body{ /* 应该加一层div包裹,避免其他元素布局受影响 */ |
三栏布局(两边定宽,中间自适应)
1. 左右float
, 中间margin
1 | <div class="left">左栏</div> |
1 | .left { |
缺点:当浏览器宽度小于左右栏宽度之和时,右栏会被挤下去
2. 左右position
定位,中间margin
1 | <div class="left">左栏</div> |
1 | * { |
缺点:当父元素有内外边距时,中间栏位置会产生偏差(所以加上了reset)
3. flex
布局
1 | <div id="wrapper"> |
1 | #wrapper { |
缺点:会有兼容性问题
参考