在 Web 前端开发中,CSS 布局是非常重要的知识技能。本篇文章主要是记录我在学习 CSS 布局知识时的学习笔记,阅读之前需要你了解部分的 CSS 和 HTML 知识。
几个重要的 CSS 布局相关属性
display 属性
display
是 CSS 中非常重要的用来控制布局的属性, HTML 中每个元素都有一个默认的display
属性,大多数元素该属性的默认值为block
或inline
,block
元素被称为块级元素,inline
元素通常被称为行内元素。display
属性值通常有如下几种取值:
block
:块级元素。它会新开始一行,HTML 中大多数元素都默认为该值,如:div
、p
、form
等元素。inline
:行内元素。它不会新开始一行,行内元素可以在段落中而不打乱段落布局。span
、a
等元素默认为该值。inline-block
:它是block
和inline
的结合体,主要用来把块级元素变换为行内元素,方便布局。flex
:一种新的布局方式,可以让布局更简单。none
:设置为该值的元素会被隐藏,布局时此类型元素可以不用考虑。
margin 属性
margin
属性用于指定本元素距离周围元素的距离,在布局时,会经常用到。
max-width 属性
max-width
用于指定当前元素最大宽度,当父容器宽度变小时,元素宽度会减小,但是当父容器宽度变大时,该元素最大宽度为指定宽度。
盒子模型
CSS 元素由内容、内边距、边框、外边距组成,我们平时设置元素的 width
和 height
等相关属性时,默认情况下,设置的都只是内容的大小,内边距,边框、外边距都可能会增大元素的实际大小。具体内容可能参考这篇文章:CSS 基础框盒模型介绍。
如下所示,两个div
元素都设置了同样的宽度,但是设置了外边距和边框的div
元素明显实际宽度更大一些。
代码示例:
<style>
#box-model .simple {
width: 500px;
margin: 20px auto;
border: 2px solid green;
}
#box-model .fancy {
width: 500px;
margin: 20px auto;
padding: 50px;
border: 10px solid green;
}
</style>
<div class="simple">
I'm use box-sizing, My width is 500px.
</div>
<div class="fancy">
I'm use box-sizing, My width is 500px.
</div>
box-sizing 属性
当把一个元素的 box-sizing
属性设置为 border-box
时,内边距和边框不会再增加元素的实际大小。
如下所示,两个div
元素都设置了同样的宽度,但是设置了内边距和边框的div
元素实际宽度没有变大。
代码示例如下:
<style>
#box-sizing .simple {
box-sizing: border-box;
width: 500px;
margin: 20px auto;
border: 2px solid green;
}
#box-sizing .fancy {
box-sizing: border-box;
width: 500px;
margin: 20px auto;
padding: 50px;
border: 10px solid green;
}
</style>
<div class="simple">
I'm use box-sizing, My width is 500px.
</div>
<div class="fancy">
I'm use box-sizing, My width is 500px.
</div>
使用 position 布局
position 属性
position
属性是 CSS 布局中常用的属性,可以有如下的取值:
static
:默认值,当一个元素被设置为static
时,表示元素不能被positioned
(主要为absolute
服务)。relative
:与static
基本一致,区别在于元素可以被positioned
。fixed
:固定定位,元素会相对于整个视窗(可以理解为浏览器窗口)定位,即使页面发生滚动,它还是会停留在相同的位置。absolute
:绝对定位,与fixed
相似,但它的定位是相对于最近的可以被positioned
的祖先元素。
position 布局示例
使用 position
完成如下所示的布局:
代码示例:
<style>
#position-layout {
width: 90%;
margin: 0 auto;
position: relative;
border: 2px solid green;
}
#position-layout .nav {
position: absolute;
top: 0px;
left: 0px;
width: 200px;
padding-left: 20px;
border: 2px solid red;
box-sizing: border-box;
}
#position-layout section {
margin-left: 200px;
border: 2px solid orange;
box-sizing: border-box;
}
</style>
<div id="position-layout">
<div class="nav">
<li><a href="#">menuItem1</a></li>
<li><a href="#">menuItem2</a></li>
<li><a href="#">menuItem3</a></li>
</div>
<section>
This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.
</section>
<section>
This is a long section too.This is a long section too.This is a long
section too.This is a long section too.This is a long section too.This
is a long section too.This is a long section too.This is a long section
too.This is a long section too.This is a long section too.This is a long
section too.This is a long section too.
</section>
</div>
使用 float 布局
float 属性
为了防止影响后续元素,在使用 float
时注意使用 clear
清除浮动。
float
可以用于实现如下所示的文字环绕图片效果:
代码示例:
<style>
#float {
overflow: auto;
border: 2px solid orange;
}
#float img {
width: 200px;
float: left;
margin: 0 1em 1em 0;
}
#float:after {
content: '.';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
</style>
<div id="float">
<img
src="https://cn.bing.com/th?id=OHR.RhinosOxpecker_ZH-CN6392794613_1920x1080.jpg"
/>
<section>
犀牛(学名:Dicerorhinus)是哺乳类犀科的总称,有4属5种。是世界上最大的奇蹄目动物,
犀类动物腿短、体肥笨拙,体长2.2-4.5米,肩高1.2-2米,体重2000-5000千克。前后肢均三趾;
皮厚粗糙,并于肩腰等处成褶皱排列,毛被稀少而硬,甚或大部无毛;耳呈卵圆形,头大而长,颈短粗,长唇延长伸出;
头部有实心的独角或双角(有的雌性无角),起源于真皮,角脱落仍能复生;无犬齿;尾细短,身体呈黄褐、褐、黑或灰色。
栖息于低地或海拔2000多米的高地。夜间活动,独居或结成小群。生活区域从不脱离水源。食性因种类而异,
以草类为主,或以树叶、嫩枝、野果、地衣等为食物。母兽妊娠期18-19个月。寿命30-50年。
因犀牛角的装饰和药用价值而被大量捕捉,除白犀外均为濒危物种。分布于亚洲南部、东南亚和非洲撒哈拉以南地区
9月22日是“世界犀牛日”(World Rhino
Day)。2010年,“世界犀牛日”由南非世界自然基金会创办(WWF-South
Africa),现已为全世界广泛接受。该活动旨在关注全球稀有动物。
在渐新世出现了有史以来最大陆生哺乳动物——巨犀,它体格健壮和高大,体长约8米,身高5米。不过虽然巨犀和犀牛同属奇蹄目,但并不属于犀牛科。
中新世的后期,出现了独角犀牛的祖先。独角犀牛仅存爪哇犀牛和印度犀牛,均分布在亚洲。在中新世以后出现的犀牛体型与现代犀牛相接近。
其中有下唇比上唇略大些的大唇犀,下颌有两颗大牙向前伸出,生活在沼泽地带,以水中的植物为食。
上新世后期(约300万年前),双角犀牛出现。双角犀牛有苏门达腊犀、白犀牛和黑犀牛。第四纪时期人类已经出现,早期的犀牛以板齿犀、披毛犀为代表。
板齿犀个体巨大,5米长,身披厚甲,在额部生有大角,约2米长,牙齿的齿冠高,呈方柱状,草地上生活,
更新世时期在中国华北的及欧洲等地曾有板齿犀生活;披毛犀和猛犸象外形相似,巨大的身体及长着粗毛的厚皮可以抵御寒冷,长鼻上有一对巨角,
前面一支最长可达1米,生活在寒冷地带。这两种犀类先后在不同的时期都已经灭绝了。
在犀类的后代中,现仅残存有犀牛科的4属5种,主要分布在亚洲和非洲,其中分布在亚洲的犀牛已经濒临绝种。
主要是因为犀牛角作为药材,其实犀牛角跟指甲是一样的构造,随数量减少现在也不容易买到真正的犀牛角,
市场还得以购买是因为现在商贩懂得以牛角替代来获利,甚至用相似成分的猫狗爪磨成假货变换充数。
</section>
</div>
float 布局示例
使用 float
完成如下所示的布局:
代码示例:
<style>
#float-layout {
width: 90%;
margin: 0 auto;
border: 2px solid green;
}
#float-layout .nav {
float: left;
width: 200px;
padding-left: 20px;
border: 2px solid red;
box-sizing: border-box;
}
#float-layout section {
margin-left: 200px;
border: 2px solid orange;
box-sizing: border-box;
}
#float-layout:after {
content: '.';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
</style>
<div id="float-layout">
<div class="nav">
<li><a href="#">menuItem1</a></li>
<li><a href="#">menuItem2</a></li>
<li><a href="#">menuItem3</a></li>
</div>
<section>
This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.
</section>
<section>
This is a long section too.This is a long section too.This is a long
section too.This is a long section too.This is a long section too.This
is a long section too.This is a long section too.This is a long section
too.This is a long section too.This is a long section too.This is a long
section too.This is a long section too.
</section>
</div>
使用 inline-block 布局
使用 inline-block 的注意事项
vertical-align
属性会影响到inline-block
元素,可能需要把它的值设置为top
。- 需要设置每一列的宽度
- 如果源代码中
inline-block
元素之间有空格或者换行,那么列之间会产生空隙。如果同行的元素使用了百分比宽度且加起来和是100%宽度,但是由于代码的换行,导致列之间有空隙,会出现元素无法排列在同一行的现象。
inline-block 布局示例
使用 inline-block
完成如下所示的布局:
代码示例:
<style>
#inline-block-layout {
width: 90%;
margin: 0 auto;
border: 2px solid green;
font-size: 0;
}
#inline-block-layout .nav {
display: inline-block;
vertical-align: top;
width: 25%;
padding-left: 20px;
border: 2px solid red;
box-sizing: border-box;
font-size: 16px;
}
#inline-block-layout .column {
display: inline-block;
vertical-align: top;
width: 75%;
border: 2px solid red;
box-sizing: border-box;
font-size: 16px;
}
#inline-block-layout .column section {
border: 2px solid orange;
box-sizing: border-box;
}
</style>
<div id="inline-block-layout">
<div class="nav">
<li><a href="#">menuItem1</a></li>
<li><a href="#">menuItem2</a></li>
<li><a href="#">menuItem3</a></li>
</div>
<div class="column">
<section>
This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.
</section>
<section>
This is a long section too.This is a long section too.This is a long
section too.This is a long section too.This is a long section too.This
is a long section too.This is a long section too.This is a long
section too.This is a long section too.This is a long section too.This
is a long section too.This is a long section too.
</section>
</div>
</div>
使用 flexbox 布局
flextbox
是一种新的布局方式,可能会有一些旧的浏览器无法支持 flexbox
布局。使用flexbox
布局可以轻松实现复杂的布局,可以非常容易的实现垂直居中和水平居中,使用起来极为方便。
flexbox 简单布局示例
使用 flexbox
完成如下所示的布局:
代码示例:
<style>
#flexbox-layout {
display: flex;
width: 90%;
margin: 0 auto;
border: 2px solid green;
}
#flexbox-layout .nav {
width: 200px;
padding-left: 20px;
border: 2px solid red;
box-sizing: border-box;
}
#flexbox-layout .column {
flex: 1;
border: 2px solid red;
box-sizing: border-box;
}
#flexbox-layout .column section {
border: 2px solid orange;
box-sizing: border-box;
}
</style>
<div id="flexbox-layout">
<div class="nav">
<li><a href="#">menuItem1</a></li>
<li><a href="#">menuItem2</a></li>
<li><a href="#">menuItem3</a></li>
</div>
<div class="column">
<section>
This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.
</section>
<section>
This is a long section too.This is a long section too.This is a long
section too.This is a long section too.This is a long section too.This
is a long section too.This is a long section too.This is a long
section too.This is a long section too.This is a long section too.This
is a long section too.This is a long section too.
</section>
</div>
</div>
flexbox 复杂布局示例
实现如下所示四列布局方式,左边两列固定宽度,右边两列分别占剩下的空间1/3和2/3。
示例代码:
<style>
#flexbox-complex-layout {
display: flex;
width: 90%;
margin: 0 auto;
border: 2px solid green;
}
#flexbox-complex-layout .nav {
width: 200px;
min-width: 100px;
border: 2px solid red;
box-sizing: border-box;
}
#flexbox-complex-layout .carousel {
flex: none;
width: 200px;
border: 2px solid red;
box-sizing: border-box;
}
#flexbox-complex-layout .column1 {
flex: 1;
border: 2px solid red;
box-sizing: border-box;
}
#flexbox-complex-layout .column2 {
flex: 2;
border: 2px solid red;
box-sizing: border-box;
}
</style>
<div id="flexbox-complex-layout">
<div class="nav">
I have 200px width when the space is enough, otherwise my width is
100px.
</div>
<div class="carousel">
I have 200px width whenever the space is enough or not.
</div>
<div class="column1">
I have one third width of the left space.
</div>
<div class="column2">
I have two third width of the left space.
</div>
</div>
flexbox 水平与垂直居中示例
实现如下所示的水平与垂直方向上的居中。
示例代码:
<style>
#flexbox-easy-center {
display: flex;
width: 90%;
height: 100px;
margin: 0 auto;
align-items: center;
justify-content: center;
border: 2px solid green;
box-sizing: border-box;
}
#flexbox-easy-center section {
border: 2px solid green;
box-sizing: border-box;
}
</style>
<div id="flexbox-easy-center">
<section>
I'm in the middle of the container.
</section>
</div>
媒体查询与响应式
布局随着不同大小的视窗动态调整布局,这就被称为响应式布局,响应式布局可以通过媒体查询来实现。
如下图表示,当视窗的宽度大于600px
时,采用两栏式布局,当宽度小于600px
时,采用单栏式布局,菜单也切换为横向菜单。
示例代码:
<style>
#media-query {
width: 90%;
margin: 0 auto;
position: relative;
border: 2px solid green;
}
#media-query .nav {
padding-left: 20px;
border: 2px solid red;
box-sizing: border-box;
}
#media-query section {
border: 2px solid orange;
box-sizing: border-box;
}
@media screen and (min-width: 600px) {
#media-query .nav {
position: absolute;
top: 0px;
left: 0px;
width: 25%;
}
#media-query section {
margin-left: 25%;
}
}
@media screen and (max-width: 599px) {
#media-query .nav li {
display: inline;
}
}
</style>
<div id="media-query">
<div class="nav">
<li><a href="#">menuItem1</a></li>
<li><a href="#">menuItem2</a></li>
<li><a href="#">menuItem3</a></li>
</div>
<section>
This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.This is a long section.This is a long section.This is a long
section.
</section>
<section>
This is a long section too.This is a long section too.This is a long
section too.This is a long section too.This is a long section too.This
is a long section too.This is a long section too.This is a long section
too.This is a long section too.This is a long section too.This is a long
section too.This is a long section too.
</section>
</div>
元素居中
元素居中是常用的布局技巧,包括水平居中和垂直居中。下文的居中示例代码使用的通用CSS代码如下所示:
<style>
h4 {
text-align: center;
}
#align-center > div {
margin-top: 50px;
width: 100%;
height: 100px;
box-sizing: border-box;
}
#align-center .child {
height: 30px;
border: 2px solid black;
}
#vertical-center > div {
margin-top: 50px;
width: 100%;
height: 100px;
box-sizing: border-box;
}
#vertical-center .child {
height: 30px;
border: 2px solid black;
}
</style>
水平居中的常用方法
水平居中包括以下几种常见实现方式。水平居中效果如下图所示:
子元素为inline
父元素设置text-align: center
,代码示例:
<style>
#align-center > .inline {
text-align: center;
border: 2px solid green;
}
#align-center > .inline > .child {
display: inline;
}
</style>
<div id="align-center">
<div class="inline">
<div class="child">I am inline</div>
</div>
</div>
子元素为block
并且宽度固定
子元素设置margin: 0 auto
,代码示例:
<style>
#align-center > .block-width {
border: 2px solid blue;
}
#align-center > .block-width > .child {
display: block;
width: 200px;
margin: 0 auto;
}
</style>
<div id="align-center">
<div class="block-width">
<div class="child">
I am block with width
</div>
</div>
</div>
子元素为block
并且宽度不固定
设置子元素display: inline
,设置父元素text-align: center
,代码示例:
<style>
#align-center > .block-no-width {
border: 2px solid red;
text-align: center;
}
#align-center > .block-no-width > .child {
display: inline;
}
</style>
<div id="align-center">
<div class="block-no-width">
<div class="child">
I am block without width
</div>
</div>
</div>
使用transform
父元素设置position: relative
,子元素使用绝对定位与transform
配合实现,代码示例:
<style>
#align-center > .transform {
position: relative;
border: 2px solid orange;
}
#align-center > .transform > .child {
position: absolute;
transform: translate(-50%, 0);
left: 50%;
}
</style>
<div id="align-center">
<div class="transform">
<div class="child">
I am transform
</div>
</div>
</div>
使用flex
父元素设置flex
布局与justify-content: center
,代码示例:
<style>
#align-center > .flex {
display: flex;
justify-content: center;
border: 2px solid purple;
}
</style>
<div id="align-center">
<div class="flex">
<div class="child">I am flex</div>
</div>
</div>
垂直居中的常用方法
垂直居中包括以下几种常见实现方式。水平居中效果如下图所示:
子元素为block
父元素设置position: relative
,子元素使用绝对定位与margin
配合实现,代码示例:
<style>
#vertical-center > .block {
position: relative;
border: 2px solid green;
}
#vertical-center > .block > .child {
display: block;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
}
</style>
<div id="vertical-center">
<div class="block">
<div class="child">I am block</div>
</div>
</div>
子元素为inline
父元素设置line-height
与height
值相等,代码示例:
<style>
#vertical-center > .inline {
border: 2px solid blue;
line-height: 100px;
}
#vertical-center > .inline > .child {
display: inline;
}
</style>
<div id="vertical-center">
<div class="inline">
<div class="child">I am inline</div>
</div>
</div>
子元素为inline-block
父元素添加after
伪元素,子元素设置vertical-align: middle
,代码示例:
<style>
#vertical-center > .inline-block {
border: 2px solid red;
}
#vertical-center > .inline-block:after {
content: '';
height: 100%;
display: inline-block;
vertical-align: middle;
}
#vertical-center > .inline-block > .child {
display: inline-block;
vertical-align: middle;
}
</style>
<div id="vertical-center">
<div class="inline-block">
<div class="child">I am inline-block</div>
</div>
</div>
使用transform
父元素设置position: relative
,子元素使用绝对定义配合transform
实现,代码示例:
<style>
#vertical-center > .transform {
position: relative;
border: 2px solid orange;
}
#vertical-center > .transform > .child {
position: absolute;
transform: translate(0, -50%);
top: 50%;
}
</style>
<div id="vertical-center">
<div class="transform">
<div class="child">I am transform</div>
</div>
</div>
使用flex
父元素设置flex
布局与align-items: center
,代码示例:
<style>
#vertical-center > .flex {
display: flex;
align-items: center;
border: 2px solid purple;
}
</style>
<div id="vertical-center">
<div class="flex">
<div class="child">I am flex</div>
</div>
</div>