# CSS 盒子模型
在学习盒子模型之前,我们先来思考一个问题?网页布局的本质是什么?
- 我们所看到的网页本质上就是由一个个矩形框拼凑而成,矩形框里放置相关的图片,文字,视频等内容。
- 我们可以简单的把网页中的这种矩形框结构称为盒子模型。接下来我们站在专业的角度,来了解下盒子模型。
- 如下图所示:
# 一、盒子模型简介
TIP
- 所有 HTML 标签都可以看成矩形盒子,具有 (盒子模型) 结构。
- 盒模型由 4 个部分组成,分别是:
content
、padding
、border
、margin
- 盒模型有 5 个属性:
width
宽 、height
高 、border
边框 、padding
内边距 、margin
外边距
注:
width
、height
不是盒子的总宽度
在标准盒子模型下,盒子模型的 content 部分就是元素的 width 和 height 属性组成的矩形部分。
我们可以用现实生活中的相框类比:
简单盒子模型
<style>
.box {
/* 宽度 200px */
width: 200px;
/* 高度 200px */
height: 200px;
/* 边框 快捷键 bd */
border: 10px solid red;
/* 内边距 上右下左 30px */
padding: 30px;
/* 外边距 上右下左 30px */
margin: 30px;
}
</style>
<body>
<div class="box">我就是div盒子的内容</div>
</body>
# 二、盒模型的属性
包含内容:
- width、height 属性(宽、高),border 属性(边框)
- padding 属性(内边框),padding 的不同数值写法
- margin 属性(外边距),margin 的不同数值写法,margin 塌陷,margin 负值
- 去掉元素默认值,盒子水平居中,盒子模型占位计算
# 1、width 和 height 属性 - 宽和高
属性 | 单位 | 描述 |
---|---|---|
width | px 、移动端开发 (百分比、rem 、vh 、vw 等单位) | 盒子内容的宽度 |
height | px、移动端开发(百分比、rem 等单位) | 盒子内容的高度 |
<style>
div {
width: 100px; /*宽度*/
height: 100px; /*高度*/
background-color: pink; /*背景色*/
}
</style>
<body>
<div>我是div盒子</div>
</body>
# 1.1、width 和 height 的特性
TIP
块级元素
- 当块级元素(如:div,p,li,h1-h6 ......)等没有设置 width 属性时,盒子的宽度会自动撑满他的父元素。但并不意味着 width 可以继承,width 是无法继承的。
- 高度在没有设置时,其高度默认为内容高,如果内容为空,则高度为 0
- 支持宽高属性的设置
内联元素
- 内联元素(如:a,span,b,strong ......)的宽高是由其内容决定,如果内容为空,则宽高默认为 0
- 内联元素设置宽高属性无效
<style>
p {
background-color: skyblue;
}
div {
width: 300px;
height: 100px;
background-color: tomato;
}
span {
width: 400px; /*不生效*/
height: 50px; /*不生效*/
background-color: yellow;
}
</style>
<body>
<p>p标签为块级元素,独占一行,默认宽度同父元素宽一样(内容宽)</p>
<div>div是块级元素,我独占一行,同时支持宽高设置</div>
<span>span元素</span>
</body>
# 2、border 属性 - 边框
TIP
border 属性的三要素:
border 属性的值由三部分组成:线宽 线型(风格) 颜色;
/*
1px 线宽度
solid 线型
red 线颜色
*/
border: 1px solid red;
常见线型值 | 描述 |
---|---|
solid | 实线 |
dashed | 虚线 |
dotted | 点状线 |
double | 双边框 |
groove | 定义 3D 凹槽边框。效果取决于 border-color 值 |
ridge | 定义 3D 垄状边框。效果取决于 border-color 值 |
inset | 3D inset 边框。其效果取决于 border-color 的值。 |
outset | 3D outset 边框。其效果取决于 border-color 的值。 |
none | 无边框 |
hidden | 隐藏边框 |
<style>
div {
width: 50px; /* 宽 */
height: 50px; /* 高 */
}
.border1 {
border: 2px solid red; /*2px 实线 红色边框线 */
}
.border2 {
border: 4px dashed blue; /* 4px 虚线 蓝色边框 */
}
.no-border {
border: none; /*去掉边框线*/
}
</style>
<body>
<div class="border1">1</div>
<div class="no-border">2</div>
<div class="border2">3</div>
</body>
# 2.1、 边框的三要素小属性
小属性 | 描述 |
---|---|
border-width | 线宽 |
border-style | 线型 |
border-color | 线颜色 |
注:
小属性是为了层叠大属性用的
<style>
div {
width: 50px;
height: 50px;
/* 2px 实线 灰色边框 */
border: 2px solid #666;
}
.box {
/* 单独定义边框颜色为红色 */
border-color: red;
}
</style>
<body>
<div>1</div>
<div class="box">2</div>
<div>3</div>
</body>
# 2.2、 四个方向的边框
属性 | 描述 |
---|---|
border-top | 上边框 |
border-right | 右边框 |
border-bottom | 下边框 |
border-left | 左边框 |
border-left: 1px solid red;
...
使用方法
<style>
div {
width: 100px;
height: 100px;
/* 上边框 */
border-top: 5px solid red;
/* 右边框 */
border-right: 6px double blue;
/* 下边框 */
border-bottom: 6px dotted orange;
/* 左边框 */
border-left: 5px dashed skyblue;
}
</style>
<body>
<div></div>
</body>
单独去掉某一边框线 border-top、border-bottom、border-right、border-left 的属性值设为 none
/* 去掉上边框线 */
border-top: none;
....
# 2.3、 四个方向的边框的三要素小属性
属性 | 描述 |
---|---|
border-top-width | 上边框宽度 |
border-top-style | 上边框线型 |
border-top-color | 上边框颜色 |
border-right-width | 右边框宽度 |
border-right-style | 右边框线型 |
border-right-color | 右边框颜色 |
border-bottom-width | 下边框宽度 |
border-bottom-style | 下边框线型 |
border-bottom-color | 下边框颜色 |
border-left-width | 左边框宽度 |
border-left-style | 左边框线型 |
border-left-color | 左边框颜色 |
<style type="text/css">
.box {
width: 200px;
height: 200px;
border: 20px solid red; /*20px 实线 红色 边框线*/
border-bottom-color: turquoise; /*底边框背景色为 天蓝色*/
border-top-style: dotted; /*上边框风格为点状*/
border-left-width: 30px; /*左边框宽 30px*/
/*写在后面的样式会覆盖前面的对应属性样式*/
}
</style>
<body>
<div class="box"></div>
</body>
# 3、padding 属性 - 内边距
TIP
- padding 是盒子的内边距,即边框内壁到内容之间的距离
- padding 有四个方向,可以分别设置
属性 | 描述 |
---|---|
padding-top | 上内边距 |
padding-right | 右内边距 |
padding-bottom | 下内边距 |
padding-left | 左内边距 |
<style>
.box1 {
width: 200px;
height: 100px;
background-color: skyblue;
/* 上内边距 */
padding-top: 10px;
/* 右内边距 */
padding-right: 20px;
/* 下内边距 */
padding-bottom: 30px;
/* 左内边距 */
padding-left: 40px;
}
</style>
<body>
<div class="box1">
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
</div>
</body>
# 3.1、padding 的不同数值写法
1 个值
/* padding:上下左右; */ padding: 20px; /* 四个方向的内边距大小都是20px; */
2 个值
/* padding:上下 左右; */ padding: 20px 30px; /*第一个值代表上下内边距20px,第二个值是左右内边距30px */
3 个值
/* padding:上 左右 下; */ padding: 20px 10px 30px; /*值1代表上内边距20px 值2代表左右内边距 10px 值3 代表下内边距30px */
4 个值
/* padding:上 右 下 左; */ padding: 10px 20px 30px 40px; /*padding:上 右 下 左 ; 四个方向值*/
注:
- 应用场景: 如果设置父子间间距,可以给父元素添加内边距来实现
- 快速记忆:左右是一对,上下是一对,缺下时和上一样,缺左时和右一样。
# 3.2、 快速灵活设置 padding 属性
TIP
padding 大小属性的最佳实践:
- 小属性 padding-top/padding-right/padding-bottom/padding-left 用来层叠大属性 padding 来组合使用
- 更推荐(小属性层叠大属性)写法
/*
小属性层叠大属性
padding: 上右下左为40px 大属性
padding-bottom: 下为0 小属性
*/
padding: 40px;
padding-bottom: 0;
案例
<style>
.box {
width: 50px;
border: 1px solid red;
/* 四个方向内边距都为10px */
padding: 10px;
}
.box1 {
/* 单独控制下内边距为0 */
padding-bottom: 0;
}
</style>
<body>
<div class="box">文字内容文字</div>
<div class="box">文字内容文字</div>
<div class="box box1">文字内容文字</div>
</body>
# 4、margin 属性 - 外边距
TIP
- margin 是盒子的外边距
- 即:盒子和其他盒子之间的距离
# 4.1、margin 四个方向属性
属性 | 描述 |
---|---|
margin-top | 上外边距 |
margin-right | 右外边距 |
margin-bottom | 下外边距 |
margin-left | 左外边距 |
<style>
.box {
width: 50px;
height: 50px;
background-color: skyblue;
}
.box1 {
/* 上外边距 20px */
margin-top: 20px;
/* 左外边距 50px */
margin-left: 50px;
/* 下外边距 30px */
margin-bottom: 30px;
}
</style>
<body>
<div class="box box1">box1</div>
<div class="box box2">box2</div>
</body>
# 4.2、margin 属性值
1 个值
margin: 20px; /*四个方向的外边距大小都是20px;*/
2 个值
margin: 20px 30px; /*第一个值代表上下内边距20px,第二个值是左右内边距30px padding:上下 左右*/
3 个值
margin: 20px 10px 30px; /*值1代表上内边距20px 值2代表左右内边距 10px 值3 代表下内边距30px */
4 个值
margin: 10px 20px 30px 40px; /*padding:上 右 下 左 ; 四个方向值*/
# 4.3、margin 设置盒子(div)块级 水平居中
TIP
我们只需要给当前元素的margin左右
值同时设置为auto
就可以
margin: 20px auto; /*上下外边距20px 水平居中显示*/
margin: 10px auto 20px; /*上20px 水平居中 下20px*/
案例
<style type="text/css">
.box1 {
width: 100px;
height: 100px;
border: 5px solid red;
}
.box2 {
width: 50px;
height: 50px;
background-color: skyblue;
margin: 10px auto; /*上下外边距10px 水平方向居中*/
/* margin:20px auto 10px; */
}
</style>
<body>
<div class="box1">
<div class="box2">1</div>
</div>
</body>
提示:
- div 块级元素水平居中,是给元素自身加上
margin:0 auto;
margin:auto 20px;
这样写,并不会垂直居中- 文字水平、图片水平居中:
text-align:center
# 4.4、margin 的塌陷
TIP
margin 塌陷也叫:外间距重叠 或 外边距合并 或 外边距穿透
# ① 兄弟元素之间 ,垂直方向:上下外边距出现塌陷
TIP
- 垂直方向的 margin 有塌陷现象,第一个元素的下外边距与第二个元素的上外边距会发生合并
- 小的 margin 会塌陷到大的 margin 中,从而 margin 不叠加,只以大值为准
- 以下两盒子之间间距为 100px ,垂直方向的 margin 不叠加,以大数为准
<style>
.box {
width: 200px;
height: 100px;
}
.box1 {
background-color: skyblue;
/*下外边距 100px */
margin-bottom: 100px;
}
.box2 {
background-color: gold;
/* 上外边距 50px */
margin-top: 50px;
}
</style>
<body>
<div class="box box1"></div>
<div class="box box2"></div>
</body>
解决办法:
- 方法一:任何一个元素加上
display:inline-block;
- 方法二:把外边距只加在其中一个元素上
- 方法三:任意一个元素外边距换成对应的
padding
# ② 父子元素之间,垂直方向:上外边距塌陷
TIP
当一个元素包含在另一个元素中时,如果父元素没有设置内边距或边框把外边距分隔开,它们的上外边距也会发生塌陷(合并)
<style>
.box {
width: 100px;
height: 100px;
background-color: gold;
/* 父元素的上外边距 */
margin-top: 20px;
}
.item {
width: 50px;
height: 50px;
background-color: skyblue;
/* 子元素的上外边距,此时父子元素的上边距发生塌陷(合并),最终上外边距的结果为 50px */
margin-top: 50px;
}
</style>
<body>
<div class="box">
<div class="item"></div>
</div>
</body>
TIP
.item
的 margin-top:50px;
发生了穿透现象(塌陷)
- 穿透了父元素,并与父元素上外边距发生合并,合并后以最大的值为主。
- 所以看到的间距并不
.item
与.box
的间距,而是.box
与浏览器上面产生了50px
的间距
解决方案
- 方法一:给父元素加上
overflow: hidden;
- 方法二:给父元素添加 透明的**
border
** 边框 - 方法三:将子元素的 margin 改成 padding
- 方法四:可以给父元添加对应的子元大小的 padding 值
还有更多方法,等我们后面学完浮动,定位之后再来讲解。
# 4.5、margin 负值
TIP
关于 margin 负值问题,我们留在 float 浮动 讲完后再学习。
# 5、去掉元素的默认样式
TIP
网页中的元素为了展示元素本身的用途和结构,都会给元素添加默认的样式。
- 一些元素都有默认的 margin,如下常见的默认样式
- h、body、ul、p 标签,都添加了默认的 margin。
- ul 添加了默认的 padding、list-style
- a 标签添中了默认的颜色、下划线
- 等等 ...... (后续在项目开发中还会深入所有标签的默认样式)
- 我们在实际的网页开发中,要将这些默认的样式清除掉,也称之为 "CSS 样式的初始化"
*
通配符选择器,表示选择所有元素 (通配符有效率问题,实际工作中不使用)
/* 通配符选择器,表示选择所有元素 - 不推荐使用 */
* {
margin: 0;
padding: 0;
}
/* 通配符有效率问题,应该使用并集选择器 */
body,
ul,
p {
margin: 0;
padding: 0;
}
a {
/* 去掉下划线 */
text-decoration: none;
/* 颜色为黑色 */
color: #000;
}
ul {
/* 去掉圆点 */
list-style: none;
}
# 6、盒子模型占位计算
TIP
盒模型的内容区大小,可视宽高,盒模型实际占位宽度
# 6.1、盒模型的内容区大小
在标准盒子模型中
content 内容区,也就是盒子里面能留给子元素的宽度和高度大小,也就意味着盒子里面的内容的最大面积就是 width 和 height 形成的矩形面积。
- 如果只有一个子元素,子元素的宽度超过父元素,就会溢出
- 如果有多个子元素(子元素为行内元素),子元素的宽度加起来超过了父元素,那么超过的那些子元就会换行显示
<style>
div {
/* 盒模型内容区大小 */
width: 200px;
height: 200px;
background-color: gold;
/* 边框 */
border: 20px solid skyblue;
/* 内边距 */
padding: 50px;
/* 外边距 */
margin: 30px;
}
</style>
<body>
<div class="box">
内容区,内容区内容区,内容区内容区,内容区内容区,内容区
</div>
</body>
# 6.2、盒模型可视宽高
TIP
- 可视区宽 = 宽度 + 左右内边距 + 左右边框宽
- 可视区高 = 高度 + 上下内边距 + 上下边框宽
# 6.3、盒模型实际占位宽度
TIP
- 实际占位宽 = 宽度 + 左右内边距 + 左右边框宽 + 左右外边距
- 实际占位高 = 高度 + 上下内边距 + 上下边框宽 + 上下外边距
<style>
.box {
/* 内容区宽 */
width: 100px;
/* 内容区高 */
height: 150px;
/* 边框线 */
border: 2px dashed #333;
/* 内边距 */
padding: 10px;
}
.box1 {
/* 内容区宽 */
width: 70px;
/* 内容区高 */
height: 120px;
/* 边框线 */
border: 5px solid skyblue;
/* 内边距 */
padding: 10px;
/* 背景色 */
background-color: gold;
}
</style>
<body>
<div class="box">
<div class="box1"></div>
</div>
</body>
如果 box1 计算得到的占位宽超过了 box 元素的内容区宽,就会达不到我们相要的布局效果
提示:
- 盒模型的内容区大小:决定了父元中的子元素能占据的最大的宽和高度
- 可视区占位:我们看到的这个元素在页面层现的效果的区域
- 实际占位宽度:决定了这个元素在父元素中的占据面积
# 三、box-sizing 怪异盒模型
TIP
在 CSS3 中新增了怪异盒子模型(IE 盒子模型)
# 1、标准盒模型与怪异盒模型区别
TIP
区别
标准盒模型和 怪异盒模型(也称:IE 盒模型)的区别在于设置 width
和 height
属性时,所对应的范围不同:
- 标准盒模型的 width 和 height 属性的范围只包含了
content
内容区 - IE 盒模型(怪异盒模型)的 width 和 height 属性的范围包含了
border、padding 和 content
- 尺寸计算公式:
- width = border + padding + 内容的宽度
- height = border + padding + 内容的高度
- button 标签,是典型的怪异盒模型
案例
<style>
/*button的可视宽高 为 100px*/
button {
width: 100px;
height: 100px;
padding: 10px;
border: 20px solid red;
}
/*div的可视宽高为 100+10*2+10*2=140px*/
div {
width: 100px;
height: 100px;
border: 10px solid red;
padding: 10px;
}
</style>
<body>
<button>button</button>
<hr />
<!--画了一水平线-->
<div>div</div>
</body>
同样的代码,在 Google 浏览中为什么显示却有差异
原因:
- button 按钮默认是 怪异盒模型
- 即:自带
box-sizing: box-border;
属性
# 2、盒模型转换
TIP
我们通过 box-sizing 属性来切换标准盒子模型与怪异盒子模型
box-sizing:content-box
是默认值,盒子以标准盒子模型特性来渲染box-sizing: border-box
盒子以怪异盒子模型特性来渲染
<style>
.box {
width: 100px;
height: 150px;
padding: 20px;
border: 10px;
margin: 50px;
/*box-sizing:borde-box;*/
}
</style>
<body>
<div class="box"></div>
</body>
以上代码,在两种盒子模型下渲染的效果如下
标准盒子模型 | 怪异盒子模型(box-sizing:borde-box;) |
---|---|
标准盒模型下的width:100px; height:150px; 只包含了 content 部分,所以 content 的宽高为 100px 和 150px; | 怪异盒子模型:width:100px; height:150px; 包含了 border、padding、content 三部分,则通过计算得出 content 内容区的 高为: 150px - 20px*2 - 10px*2 = 90px 宽为: 100px - 20px*2 - 10px*2 = 40px |
应用场景:
- 如果我们期望不管
内容区
,边框
、内边距
大小如何变化,元素的可视宽高始终不变时,就可以给元素添加 box-sizing:border-box;属性,以怪异盒模型来渲染。 - 不管元素的占位宽如何变化,始终保持边框和内边距不变,希望通过改变内容区大小来达到目的。
- 常见的响应式开发中、移动端开发等。
# 四、前端切图工具
TIP
接下来我们会用 4 种相关 psd 设计稿或图片测量和切图工具,不同的工具有不同的优点
软件名称 | 功能 | 描述 | 官网下载地址 |
---|---|---|---|
Snipaste1 | 截图+贴图 | 个人模仿他人效果选可用 | https://zh.snipaste.com/ (opens new window) |
PxCook | 标注+代码生成(psd) | 是一款连接设计师到开发者之间的协作工具 | https://www.fancynode.com.cn/pxcook/ (opens new window) |
Photoshop(简称 PS) | 专业的图片软件处理工具 | 实际企业开发设计软件 | https://www.adobe.com/cn/products/photoshop.html (opens new window) |
蓝湖 | 产品设计协作平台 | 实际企业团队开发协作 | https://lanhuapp.com/ (opens new window) |
# 1、Snipaste 截图 + 贴图
TIP
Snipaste 是一个简单但强大的截图工具,也可以让你将截图贴回到屏幕上!
- Snipaste 官网 : https://zh.snipaste.com/ (opens new window)
- 进入官网,下载 Snipaste 软件包,双击软件包,即可安装好。
Snipaste 的简单使用
- 按下
F1
来开始截图,再按F3
,截图就在桌面置顶显示了 - 详细的使用教程,看官方文档:https://docs.snipaste.com/zh-cn/ (opens new window)
# 2、PxCook 像素大厨
TIP
PxCook(像素大厨) 是一款连接设计师到开发者之间的协作工具。
- 使用 PxCook,设计师可以免去繁琐的标注功能,而前端工程师也可以更加直观的查看设计稿中的元素的内容,间距,尺寸和样式等。
- 同时, PxCook 可以为工程师直接呈现选中元素的多平台样式代码和素材切图。
# 2.1、工具的安装
TIP
- 进入 PxCook 像素大厨的官网
- 网址:https://www.fancynode.com.cn/pxcook/ (opens new window),点击立即下载
- 也可以在钉钉裙文件中下载即可(联系客服老师)
下载好的压缩包直接双击安装就可以了
# 2.2、工具的使用
TIP
工具的具体使用,看老师的讲解视频
# 3、Photoshop 和 蓝湖
TIP
Photoshop 和 蓝湖工具,前面 arry 老师视频有详细讲解,可以看前面的视频。
# 五、针对性案例训练
利用学过的知识来开发以下效果
要求:利用 PS 与 PxCook 结合,将以下 PSD 设计稿用代码以 1:1 还原成网页
# 1、商品卡片布局
点击查看源代码
<style>
a {
text-decoration: none;
}
h3,
p {
margin: 0;
}
.goods {
width: 150px;
height: 264px;
border: 1px solid #666;
padding: 0px 18px;
/* text-align: center; */
}
.goods img {
width: 150px;
height: 150px;
margin-top: 12px;
display: block; /* 去掉图片与下面文字间的空白间隙 */
/*
margin: 0px auto; */
}
.goods .title {
font-size: 12px;
color: #666;
line-height: 20px;
margin-top: 6px;
}
.goods p {
margin-top: 13px;
line-height: 1; /* 行高为1,与字体一样大小 */
font-size: 24px;
font-weight: bold;
color: #e12530;
}
.goods p i {
font-style: normal;
font-size: 18px;
font-weight: bold;
}
.goods p span {
font-size: 12px;
font-weight: 400;
}
</style>
<body>
<div class="goods">
<a href="">
<img src="./images/img1.png" alt="" />
<h3 class="title">iSeeJplus山茶花智能眼部按摩器护眼仪</h3>
<p><i>¥</i>679.<span>00</span></p>
</a>
</div>
</body>
# 2、 边框应用场景 - 制作三角形
<style>
.box1 {
width: 0;
height: 0;
/* transparent 是透明色 */
border: 30px solid transparent;
border-top-color: red;
}
.box2 {
width: 0;
height: 0;
/* transparent 是透明色 */
border: 30px solid transparent;
border-right-color: red;
}
.box3 {
width: 0;
height: 0;
/* transparent 是透明色 */
border: 30px solid transparent;
border-bottom-color: red;
}
.box4 {
width: 0;
height: 0;
/* transparent 是透明色 */
border: 30px solid transparent;
border-left-color: red;
}
</style>
<body>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
</body>
# 六、课后作业
TIP
深入浅出 CSS 盒子模型案例训练
# 1、利用 CSS 开发新闻列表(视频)
#
点击查看完整版视频讲解
大厂最新技术学习分享群
微信扫一扫进群,获取资料
X