目录
一、CSS盒模型
(一)盒模型--content
在网页布局中,页面其实是由一个个大小不一的小块构成,例如淘宝页面当中就很常见,比如浏览商品的时候,商品的缩略图:
下面我们来学习如何在页面中画出一个矩形的格子:
要画一个矩形的格子,首先要了解一个新的标签 -- div
标签。
在学习HTML
的时候,我们已经接触过了类似于div
的标签,比如
h
标签p
标签ul
标签li
标签
这些标签有一个共同的特性,就是可以独占一行,它们都是在div
标签的基础上进行改造的,添加了 margin、padding、文字大小等等,当然了,还被赋予了其它默认的特性,这里我们不做过多解释。
最后可以总结为,div
就是一个干净透彻的矩形:
由四部分组成:
- 内容区
content
- 内边距
padding
- 边框
border
- 外边距
margin
注意顺序,由内到外。
如果由外到内讲,就是 外边距、边框、内边距、内容区
如果你觉得有些抽象,那么可以用现实生活中的例子帮助我们理解:
编程的概念总是抽象的,现实例子可以 帮助 我们理解概念,但千万不要等同
由于 div
是一个矩形,那么实际上 内边距、边框、外边距 又由 上、下、左、右 四条边组成。
把 div 拆分的这么细,就意味着四条边既可以统一设置样式,也可以分开设置样式。
内容区是最中心的完整区域,就没有四边的概念了。换句话说,内容区的四条边的样式,由 内边距、边框、外边距 的样式决定
div 矩形的四个组成部分,就是所谓的“盒模型”,也是本章的主要内容,我们会一一学到。
内容区:content
首先我们要学习的是 div 的 content
。
div
标签写出来的时候是没有高度的,但是有宽度,宽度默认和父标签的宽度是一样的。比如我们在页面中只写一句代码:
<div></div>
通过审查元素(审查元素的技术在进阶中会讲到)可以看到div
的尺寸
可以看到,div 的宽度是1661px
高度是0px
,与前文中讲到的div
标签默认是没有高度的,宽度和父标签的宽度一样,如果直接在body
标签里写一个div
标签,那么div
的父标签就是body
标签,如果是下面代码中这样写的,那么div
的父标签就是li
标签,那么div
的默认宽度就是li
标签的宽度。
<ul>
<li>
<div></div>
</li>
</ul>
这里所说的宽度不是肉眼看到的宽度,而是 width 属性设置的宽度
width/height
要画一个矩形,首先要设置矩形的宽高,矩形的宽高对应两个 CSS 属性width
,height
,它们的值是数字,单位是px
。
下面我们来画一个宽 200px,高 100px 的矩形:
核心代码如下:
<div class="box"></div>
.box {
width: 200px;
height: 100px;
}
但仅仅这样写,我们在页面上是看不到这个矩形的,因为我们还没有给它着色,而 div 默认是不填充颜色的。
要给矩形添加背景颜色,需要学习一个新的 CSS 属性,background-color
--背景颜色,这个属性的值跟我们设置字体颜色时候学的一样,有十六进制,rgb
,rgba
,英文单词形式的颜色,下面我们给刚才设置的矩形添加一下背景颜色,最终实现的效果如下:
核心代码如下:
<div class="box"></div>
.box {
width: 200px;
height: 100px;
background-color: purple;
}
效果如下:
此时我们看到的紫色的矩形就是这一章我们要学习的盒模型中的content
。
百分百尺寸
设置块元素的宽高,除了px
形式,还有%
形式,比如说:
<div class="father">
<div class="son"></div>
</div>
.father {
width: 200px;
height: 80px;
background-color: #5b6dcd;
}
.son {
width: 60%;
height: 20%;
background-color: #fec03e;
}
注意:这里的%
是相对于父元素的,也就是说,子元素的宽度是父元素的60%
(200px*60%=120px
),子元素的高度的20%
(80px*20%=16px
),所以首先要确定父元素的尺寸是存在的。
什么情况下,父元素的尺寸是不存在的呢?比如说,我们想设置一个矩形,矩形铺满整个浏览器的屏幕,我们或许会这样去设置:
<div class="bg"></div>
.bg {
width: 100%;
height: 100%;
background-color: blue;
}
这时候你会发现,浏览器依然是白色,这是因为.bg
的父元素body
的高度默认是0px
,0px
的百分之百还是0px
,但是body
的宽是有的,默认和浏览器页面宽度一样。
(二) 盒模型--padding
经过上一节的学习,大家已经了解了盒模型的一部分,即内容部分,接下来要学习的是盒模型中的内边距--padding
,比如说我们最常见的网页的标题栏部分(点击可以放大图片):
我们可以很清楚的看到,由绿色边框圈起来的文字,距离上、下、左、右都有一定的距离,或许这个例子看起来有点难受,它太小了,我们可以换一个更大更明显的例子:
这样看起来就舒服多了,接下来我们来仿写一个上面的案例:
核心代码如下:
<div class="box">
All afternoon his tractor pulls a flat wagon with bales to the barn, then back to the waiting chopped field.
It trails a feather of smoke. Down the block we bend with the season: shoes to polish for a big game,storm windows to batten or patch.
And how like a field is the whole sky now that the maples have shed their leaves, too.
</div>
.box{
width:300px;
height:300px;
background-color:purple;
padding:20px;
color:white;
}
效果如下:
为了能够更好的理解padding,可以参考一下下面这张图:
注意:padding
区域是包含在背景颜色区域内的,也就是说背景颜色包含了padding
和content
。
padding分开写
padding默认是给矩形四周添加相同的内边距,但是我们在实际应用当中会有四周内边距不同的情况,因此我们就要分别给矩形设置内边距,没有设置的内边距默认为0。
.box {
padding: 20px;
}
上面的代码等价于:
.box {
padding-top: 20px; /*上内边距*/
padding-right: 20px; /*右内边距*/
padding-bottom: 20px; /*下内边距*/
padding-left: 20px; /*左内边距*/
}
padding简写
学习padding
分开写的形式主要是为了更好的理解如何简写padding
,现在我们知道了padding
分为top
、right
、bottom
、left
,在简写的时候就会从这四个方向上去设置。
之前我们知道这种形式的简写padding: 20px
,意思是给content
的上、右、下、左四个方向上都设置了相同的padding
,它最初的形式是这样
div{
padding:20px 20px 20px 20px;
}
这四个值分别代表,上、右、下、左,如果四个值都一样,就可以写成padding:20px;
,如果不一样,可以分为一下几种情况:
1. 上下一样,左右一样
例如:
div{
padding-top: 20px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
}
上下一样,写一个即可,左右一样,写一个即可,最后变成:
div{
padding: 20px 30px;
}
那么,有人会问,后面的两个值可以颠倒位置吗?答案是不可以
div{
padding: 30px 20px;
}
/* 这句话就会被翻译为 */
div{
padding-top: 30px;
padding-bottom: 30px;
padding-left: 20px;
padding-right: 20px;
}
永远记住,第一个值是上,第二个值是右,第三个值如果没有,就和第一个值保持一致,第四个值如果没有就和第二个值保持一致。
2. 上下一样,左右不一样
比如:
div{
padding-top: 20px;
padding-bottom: 20px;
padding-left: 10px;
padding-right: 30px;
}
使用简写形式要这样写:
div{
padding: 20px 30px 20px 10px;
}
3. 上下不一样,左右一样
比如:
div{
padding-top: 30px;
padding-bottom: 20px;
padding-left: 10px;
padding-right: 10px;
}
使用简写形式要这样写:
div{
padding: 30px 10px 20px;
}
可以这样来理解,第一个值是上30px
,第二个值是右10px
,第三个值是下20px
,第四个值是左,但是没有,所以要跟右一致。
总结下来就是上、右、下、左按照顺序去填写,没有的值就跟对立面的值一样,下对上,左对右。
box-sizing
box-sizing
规定了如何计算一个元素的总宽度和高度,它有两个值content-box
,border-box
,默认是content-box
。
-
content-box
尺寸计算公式:width = 内容的宽度 height = 内容的高度
-
border-box
尺寸计算公式:width = border + padding + 内容的宽度 height = border + padding + 内容的高度
也就是说,
box-sizing
规定了两种计算方法,每个值代表一种计算方法。工程师 不能 任意写计算公式
这里的内容就是我们学过的content
,border
属性我们还没有学,但是在这里已经可以说明一下box-sizing
属性的性质,下一节学习border
的时候,我们会将border
的尺寸也算进去。
举个例子说明一下:
<div class="father">
<div class="son"></div>
</div>
.father{
width:200px;
height: 100px;
background-color: #5C70CA;
}
.son{
box-sizing: content-box;
width: 100%;
height: 40px;
background-color:#FEC03E;
}
修改一下CSS
代码:
.father{
width:200px;
height: 100px;
background-color: #5C70CA;
}
.son{
box-sizing: content-box;
width: 100%;
height: 40px;
/* 添加padding */
padding: 0px 20px;
background-color:#FEC03E;
}
效果如下:
子元素超出的原因就是,width: 100%
属性给子元素设置了和父元素content
一样的宽,又设置了padding
在原有的基础上又增加了左右padding
超出了父元素content
区域。
.father{
width:200px;
height: 100px;
background-color: #5C70CA;
}
.son{
/* 修改box-sizing */
box-sizing: border-box;
width: 100%;
height: 40px;
/* 添加padding */
padding: 0px 20px;
background-color:#FEC03E;
}
效果如下:
border-box
的width
包含了content
、padding
、border
,所以设置padding
,border
后不会溢出父元素的content
。
(三)盒模型--border
学习了盒模型的content
、padding
之后,基本上我们就可以满足很多开发的需求,接下来我们要学习的是盒模型中的边框--border
。
边框就是包裹在padding
外面的一层线,说到线,肯定会有粗细、颜色,首先我们要学习如何给一个矩形设置边框线。
给矩形设置边框线
设置边框线的语法是(请注意花括号里面的内容,.box 是类名,类名是可以自己定义的):
.box {
/* 设置矩形大小 */
width: 200px;
height: 30px;
/* 设置边框线 */
border-width: 2px;
border-color: grey;
border-style: solid;
}
显示效果如下:
这样我们就给一个类名为 box 的矩形的四周添加上了边框线,接下来我们要来解释一下每一个属性具体是什么意思:
border-width
:边框的粗细,单位是 px
border-color
:边框的颜色,颜色值和我们之前学的文字、背景的颜色表示方法是一样的
border-style
:边框的线型,solid
为实线,dashed
为虚线,当然还有其它的线型,最常用的是这两种
边框的简写
通过上面的演示我们发现,仅仅是简单的设置了一个边框,就需要三行代码,显得很繁琐,其实 CSS 代码中是有很多简写的方式的,拿边框来说,我们完全可以用一行代码来实现上面三行代码的效果。
.box {
border: 2px solid blue;
}
补充一点:border
后面跟的三个值之间要用空格隔开,值的顺序是可以忽略的,比如你可以写成 2px blue solid
,效果是一样的。
分别设置边框
在我们学习padding
的时候,我们曾经给padding
的上下左右设置了不同的值,那么在border
中同样是可以这样设置的。
首先我们来看一种繁琐的设置方式,但是并不推荐这种:
.box {
/*设置顶部border*/
border-top-color: blue;
border-top-style: solid;
border-top-width: 2px;
/*那么接下来,left,right,bottom是类似的,这里忽略不写*/
}
效果如下:
我们重点关注推荐的书写方式:
.box {
/* 添加顶部border */
border-top: 1px solid black;
/*添加右侧border*/
border-right: 3px solid orange;
/*添加底部border*/
border-bottom: 5px dashed pink;
/*添加左侧border*/
border-left: 10px dashed purple;
}
这样我们就可以随心所欲的给矩形的四周添加不同的边框了。点击查看一下下方案例的最终效果,感受一下吧~
利用层叠性设置边框
在实际应用当中,我们可能会遇到这样一种情况,要设置一个矩形,矩形的左、右、上的边框样式是相同的,但是下边框的样式是不一样的。
这时候我们就可以用属性的层叠性来实现,核心代码如下:
.box {
/*设置矩形的宽*/
width: 300px;
/*设置矩形的高*/
height: 300px;
/*设置矩形的背景颜色*/
background-color: white;
/*设置矩形的边框*/
/*统一设置矩形的所有边框样式*/
border: 2px solid black;
/*重新设置一个下边框的样式来层叠掉统一设置的边框的样式*/
border-bottom: 5px solid orange;
}
有了这个方法,我们就可以在特定的情况下,加以灵活的应用,来减少代码书写量。
无边框
在上一个案例中,我们用排除法将下边框设置成了特殊的样式,那么如果我们需要让下边框不显示呢?
这时候就需要border
的另一个属性值--none
.box {
border-bottom: none;
}
圆角
在很多场景下,矩形一般都不是四四方方的,需要一点点的圆角来点缀,圆角的属性是归类于边框的,即border-radius
。有了之前的基础,相信圆角对大家来说很好理解。
圆角的统一设置
首先先来说一下圆角的设置方法:
.box {
border-radius: 12px;
}
上面这段代码只是设置圆角的方法,此时如果不设置矩形的宽、高,背景色或者边框颜色,圆角是看不出来的,但是请记住,看不到并不代表不存在。
如果要看到效果,需要这样写:
div {
width: 200px;
height: 200px;
border-radius: 18px;
border: 1px solid black;
}
实现效果如下:
或者设置背景颜色也可以看到效果:
div {
width: 200px;
height: 200px;
background-color: violet;
border-radius: 18px;
}
实现效果如下:
圆角分开设置
与padding
、border
属性一样,border-radius
属性也是可以拆开来设置的,只不过它没有上下左右,而是左上角,右上角,右下角,左下角。具体写法如下:
.box {
width: 200px;
height: 200px;
background-color: violet;
border-top-left-radius: 5px;
border-top-right-radius: 10px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 15px;
}
实现效果如下:
阴影
<div class="box"></div>
.box {
width: 200px;
height: 200px;
border: 1px solid #c4c4c4;
/* x偏移量 | y偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 */
box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
border-radius: 15px;
}
实现效果如下:
阴影的实现原理可以看作是在矩形下面有一个重叠的,同样大小的矩形,如果它在 x 轴、y 轴上移动,就会有阴影的效果。
- x 偏移量:在 x 轴上移动,向右为正
- y 偏移量:在 y 轴上移动,向下为正
- 阴影模糊半径:就是边线的清晰度
- 阴影扩散半径:就是向外伸展
- 阴影颜色:就是矩形下面那个矩形的背景色。
(四)盒模型--margin
在这一节我们要学习的是盒模型中的margin---外边距。所谓外边距就是矩形和矩形之间的距离,我们可以看一下下面这张图:
如果想要中间红色边框的矩形与四周绿色背景的矩形之间有一定的间隙,就可以给红色边框的矩形设置一个margin属性。
接下来我们来实现一下下图的页面效果,来感受一下margin的作用(因为我们还没有学习浮动,所以暂时还不能设置左右margin):
具体实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>案例</title>
<style>
div {
width: 300px;
height: 100px;
background-color: #D5E8D4;
border: 1px solid #82B366;
}
.box{
background-color: #F5F5F5;
border: 1px solid #FF0818;
margin-top: 20px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div></div>
<div class="box"></div>
<div></div>
</body>
</html>
下面我们看一下这段代码
.box{
background-color: #F5F5F5;
border: 1px solid #FF0818;
margin-top: 20px;
margin-bottom: 20px;
}
在这个代码演示中,我们可以通过这一段代码看出,其实margin的设置方式跟padding是一样的,可以得出margin的书写方式:
.box{
/*总写*/
margin: 20px;
/*分开写*/
margin-top: 20px;
margin-right: 20px;
margin-bottom: 20px;
margin-left: 20px;
}
两个盒子之间margin的计算
水平距离
首先我们来看最容易理解的水平距离,下图中,第一个盒子的右margin为30px,第二个盒子的左margin为20x,那么最后两个盒子之间的水平距离就是30px+20px=50px;如果第二个盒子没有设置magrin-left,那么默认为第二个盒子的margin-left为0px。
垂直距离
水平距离很符合我们的常规理解,但是垂直距离就略有不同,垂直距离取两个盒子margin的最大值。
如下图所示,首先,只给其中一个盒子设置margin-bottom,两个盒子之间的垂直距离就是第一个盒子的margin-bottom; 然后,给第二个盒子设置一个margin-top,但是值小于第一个盒子的margin-bottom的值,得到两个盒子之间的垂直距离,是取两个margin的最大值; 最后,将下方盒子的margin-top设置为50px,大于第一个盒子的margin-bottom,两盒子之间的垂直距离变成了50px。
在实际应用当中,我们如果要设置两个盒子之间的垂直距离,一般不会去写两个margin,比如我要设置两个盒子之间的垂直距离为50px
不推荐
.box1{
margin-bottom: 20px;
}
.box2{
margin-top: 50px;
}
推荐
.box1{
margin-bottom: 50px;
}
不推荐
.box2{
margin-top: 50px;
}
因此,要设置两个盒子之间的垂直距离,选择其中的一个去设置即可。
盒子左右居中
margin还有一个作用就是使盒子可以在父盒子中左右居中,但是有一个前提,就是必须有宽度。
例如下面这个案例:
<div class="father">
<div class="son"></div>
</div>
.father{
width:400px;
height:200px;
border: 1px solid #ccc;
}
.son{
width:200px;
height:100px;
margin:0 auto;
border: 1px solid #ccc;
}
此时如果将son中的width去掉,你就会发现居中效果失效了。
(五)盒模型--display:block/none
display: block
块元素性质一--独占一行
在学HTML
的标签的时候,我们应该对块、行内这种词汇有所了解,比如说我们常用的h
标签就是一个块级标签,这样的标签的性质就是独占一行,例如:
<span>这是一个span标签</span>
<h3>这是一个h3标签</h3>
<h4>这是一个h4标签</h4>
这段代码的结果只能是这样:
这是一个 span 标签
这是一个h3标签
这是一个h4标签
而不会是这样:
这就是块元素的性质,独占一行,如下图所示,第一行是两个行内元素,可以并排显示;第二行是一个块元素,内容部分是蓝色部分,剩下的部分用灰色占位,所以其它的标签元素不能跟它在同一行显示。
块元素性质二--可以设置宽高
首先我们做一个对比实验,在一个行内元素上添加背景颜色,设置宽高,看看背景颜色的范围是否可以扩大,以span
标签为例:
<span class="demo"> 这是一个span标签 </span>
.demo {
width: 300px;
height: 100px;
background-color: #fff2cc;
}
得到的效果如下
可以看到,我们即使给行内元素span
设置了宽、高,却根本不会生效。
接下来我们在上面的代码基础上将span
标签修改成div
标签看看效果:
<div class="demo">这是一个div标签</div>
.demo {
width: 300px;
height: 100px;
background-color: #fff2cc;
}
得到的效果如下
行内元素和块元素之间的转换
标签是行内元素还是块元素,其根本原因就是标签自带的默认display
属性:
- 块元素默认的
display
属性的值是block
- 行内元素默认的
display
属性的值是inline
行内元素转块元素
接上面的那个案例,我们要想给span
标签设置宽、高,首先要让span
标签转换成块元素,然后再给它设置宽高,我们的做法是这样:
<span class="demo"> 这是一个span标签 </span>
.demo {
/*将span标签转换成块元素*/
display: block;
width: 300px;
height: 100px;
background-color: #fff2cc;
}
得到的效果如下
块元素转行内元素
行内元素可以通过display
属性转换成块元素,从而达到设置宽高的目的,那么我们也可以用这个方法让块元素失去设置宽高的能力,我们的做法是这样:
<div class="demo">这是一个span标签</div>
.demo {
/*将div标签转换成行内元素*/
display: inline;
/* 转换成行内元素以后,宽、高的设置就会失效,即使我们仍然设置了它们 */
width: 300px;
height: 100px;
/* 背景颜色也不会是300*100范围,而是文字有多少面积,背景颜色就又多少面积 */
background-color: #fff2cc;
}
得到的效果如下
display: none;
none
就是无的意思,也就是说,当给标签设置了这个属性值,标签就会消失,在网页布局中最常用的就是用none
、block
来控制元素的显示和隐藏。
可以看一下下面这个例子:
<div>盒子1</div>
<div class="box2">盒子2</div>
<div>盒子3</div>
div {
width: 300px;
height: 100px;
/* 使用text-align属性让文字左右居中 */
text-align: center;
margin-bottom: 10px;
background-color: #d5e8d4;
/* 使用行高让文字上下居中 */
line-height: 100px;
}
.box2 {
display: none;
}
得到的效果如下