一、引言
本文总结了css的一些常用布局方式,如正常布局流、定位、浮动、flex、grid。
二、css布局
2.1布局基础
正常布局流
如果不对页面进行任何布局控制,默认按照源码中出现的先后次序依次显示,如:
盒模型
每一个元素都可以看作是一个盒子,每个盒子由四部分组成,margin、border、padding、content。
content:元素的实际内容区域,可以通过width和height属性设置内容区域的宽度和高度
padding:内边距,是内容区域与边框之间的空白区域,通过padding属性设置,可以分为padding-top、padding-left、padding-right、padding-bottom
border:边框,包围着内边距与内容区域,通过border属性设置,可以分为border-width、border-style、border-color
margin:外边距,是边框与相邻元素之间的空白区域,可以通过margin属性设置,分为margin-top、margin-right、margin-left、margin-bottom
可以通过设置box-sizing属性为border-box切换为怪异盒子模型。怪异盒子模型与标准盒模型的主要区别在于怪异盒子模型设置width和height属性实际包含content、padding和border总的大小,而标准盒子模型设置width和height属性就是content的大小。
<div id="box1">
content-box
</div>
<div id="box2">
border-box
</div>
<style>
#box1 {
box-sizing: content-box;
width: 200px;
height: 100px;
border: 1px solid red;
padding: 20px;
margin-bottom: 10px;
}
#box2 {
box-sizing: border-box;
width: 200px;
height: 100px;
border: 1px solid red;
padding: 20px;
}
</style>
2.2元素显示模式(display)
块级元素(block)
会有以下行为:
- 元素独占一行,后续内容会换行显示
- width和height属性有效
- 如果未指定width,将沿行向扩展,通常盒子会变得与其容器一样宽;如果未指定height,则根据内容高度扩展
常见默认block的元素有:<h1>~<h6>、<div>
行内元素(inline)
会产生以下行为:
- 元素会在同一行内水平排列
- 高度和宽度根据内容自动调整,设置width和height属性无效
- 设置padding、margin、border都会被应用,但是垂直方向的inlien不会被推开,水平方向会被推开
常见默认inline的元素有:<a>
、<span>、<em>、<strong>
<div>box1</div>
<div>box2</div>
<div>
<span>盒子1</span>
<span>盒子2</span>
<span>盒子3</span>
<span>盒子4</span>
</div>
<style>
div {
padding: 10px;
border: 1px solid red;
margin-bottom: 10px;
}
span {
width: 100px;
height: 50px;
border: 1px solid blue;
margin: 20px;
padding: 20px;
}
</style>
行内块元素(inline-block)
结合了inline和block元素的特点:
- 元素在同一行内水平排列,不会独占一行
- 可以设置宽度和高度
- 设置margin和padding水平、垂直方向都会被推开
- 可以包含其他块级元素或行内元素 如果将上面的span标签设置为inline-block,宽度和高度有效,并且垂直方向的元素也会被推开效果如下:
三种元素显示方式可以通过设置display属性切换。
2.3浮动
浮动的定义
允许元素脱离正常的文档流,并向左或向右浮动,直到碰到包含块的比边缘或另一个浮动元素的边缘为止。通常用于创建多列布局、文字环绕图片等效果。通过设置float属性为left/right实现
<div class="container">
<div class="float-left">这是左浮动的元素</div>
<p>这是环绕浮动元素的段落文本。</p>
</div>
<style>
.float-left {
float: left;
width: 100px;
height: 100px;
background-color: lightblue;
margin-right: 10px;
}
.container {
width: 400px;
border: 1px solid black;
}
</style>
清除浮动
由于浮动元素脱离了正常文档流,不占据原来的空间,这样可能会导致包含浮动元素的父元素高度塌陷,因此需要清除浮动。
方法一:clearfix
先向包含浮动内容及其本身的盒子后方插入一些生成的内容,并将这些内容清除浮动。
.container::after {
content: "";
display: block;
clear: both;
}
方法二:使用overflow
将包裹元素的overflow属性设置为除visible外的其他值,这样就能创建一个块级格式化上下文(BFC),BFC中浮动元素的宽高包含参与计算。
.container {
width: 400px;
border: 1px solid black;
overflow: auto;
}
块级格式化上下文(BFC)
特性:
- 同一bfc中俩相邻盒子margin会发生塌陷
- bfc计算高度时, 浮动元素也会参与
- bfc不会与浮动盒子重叠
触发方式:
- 根元素, 即html元素
- overflow:hidden, auto, scroll
- display: inline-block, table-cell, flex, grid
- position: fixed, absolute
- float: left, right
应用:
- 防止margin塌陷: 放在不同的bfc盒子里
- 清除内部浮动
缺点是使用overflow可能带来一些副作用,如出现滚动条。
方法三:display:flow-root
创建BFC,并且在使用上没有副作用。
.container {
width: 400px;
border: 1px solid black;
display:flow-root;
}
但是可能部分浏览器不支持
2.4定位
不同的定位方式
定位允许从正常文档流中取出元素,并使他们具有不同的行为。通过设置position属性实现不同类型的定位
| position属性值 | 名称 | 描述 |
|---|---|---|
| static | 静态定位 | 默认值,非定位元素 |
| relative | 相对定位 | 相对自身原本位置偏移,不脱离文档流 |
| absolute | 绝对定位 | 相对非static祖先元素定位 |
| fixed | 固定定位 | 相对视口绝对定位 |
| sticky | 粘性定位 | 相对定位和固定定位的混合,被定位的元素表现像相对定位,直到滚动到某一阈值,表现为固定 |
然后通过top、bottom、left、right来指定定位元素要移动的位置。
<div class="container">
<div class="static">static</div>
<div class="relative">relative</div>
<div class="absolute">absolute</div>
<div class="fixed">fixed</div>
</div>
<style>
.container {
width: 300px;
border: 1px solid red;
position: relative;
}
.static {
position: static;
top: 20px;
left: 30px;
}
.relative {
position: relative;
top: 0px;
left: 0px;
}
.absolute {
position: absolute;
top: 0;
left: 50px;
}
.fixed {
position: fixed;
top: 0px;
left: 0px;
}
</style>
定位叠放次序z-index
当元素开始重叠,可以设置z-index来确定元素堆叠的顺序。值越大越在上层。
2.5弹性盒子flex
通过设置display属性为flex,指定容器为flex布局。主要有六个属性设置在容器上。
- flex-direction:设置主轴方向,即项目排列方向
- flex-wrap:确认是否换行
- flex-flow:flex-direction和flex-wrap属性的简写形式
- justify-content:定义主轴上的对齐方式
- align-items:定义交叉轴上的对齐方式
- align-content:定义多根轴线的对齐方式
div{
display: flex;
flex-direction: row | row-reverse | column | column-reverse ;
flex-wrap: wrap | nowrap | wrap-reverse;
flex-flow: <flex-direction> <flex-wrap>;
justify-content: flex-start | flex-end | center | space-between | space-around;
align-items: flex-start | flex-end | center | baseline | stretch;
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
2.6网格grid
网格通常有多个行与列,以及行与行、列与列之间的间隙。通过把容器的display属性设置为grid来定义网格布局。
grid-template-columns:设置列,可以用任意长度单位,还有repeat函数、auto-fill关键字、fr关键字、minmax函数等多种定义行列大小的方式
grid-column-gap:定义列间隙
grid-row-gap:定义行间隙
至此就可以定义一个最基本的网格
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<style>
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
grid-gap: 20px;
}
.container div {
background-color: pink;
}
</style>