一、盒子模型-外边距 margin
CSS 的 margin
属性用于设置盒子的外边距,通常用于设置元素和元素之间的间距,和 padding
类似 margin
也有四个方向的间距值,分别是:
margin-top
:上内边距
margin-right
:有内边距
margin-bottom
:下内边距
margin-left
:左内边距
margin
是以上四个方向外边距的一个缩写属性,margin
缩写属性是从零点开始,顺时针转动,缩写属性对应的值分别是上右下左。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1 {
height: 100px;
background-color: #f00;
margin-bottom: 30px;
}
.box2 {
height: 100px;
background-color: #0f0;
margin-top: 30px;
}
</style>
</head>
<body>
<div class="box1">box1</div>
<div class="box2">box2</div>
</body>
</html>
在浏览器中打开该 HTML 页面,效果如下:
上述的代码中我们设置了 box1 的下外边距为 30px,设置了 box2 的上外边距为 30px,也就说是 box1 和 box2 之间的间距应该为 60px,但实际并不是 60px,而是 30px;这是因为两个元素之间上下 margin 边距会出现折叠的情况;但是左右 margin 的边距不出出现折叠的情况。
修改 CSS 样式
.box1 {
/*设置元素类型*/
display: inline-block;
width: 100px;
height: 100px;
background-color: #f00;
margin-bottom: 30px;
/*设置右外边距*/
margin-right: 30px;
}
.box2 {
/*设置元素类型*/
display: inline-block;
width: 100px;
height: 100px;
background-color: #0f0;
margin-top: 30px;
/*设置左外边距*/
margin-left: 30px;
}
二、内边距 padding 和外边距 margin 的对比
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 300px;
height: 300px;
background-color: #f00;
}
.container {
width: 100px;
height: 100px;
background-color: #0f0;
}
</style>
</head>
<body>
<div class="box">
<div class="container"></div>
</div>
</body>
</html>
添加一个padding
.box {
width: 300px;
height: 300px;
background-color: #f00;
padding-left: 20px;
box-sizing: border-box;
}
.container {
width: 100px;
height: 100px;
background-color: #0f0;
}
与下面的代码效果一致
.box {
width: 300px;
height: 300px;
background-color: #f00;
/* padding-left: 20px;
box-sizing: border-box; */
}
.container {
width: 100px;
height: 100px;
background-color: #0f0;
margin-left: 20px;
}
padding 和 margin 的使用场景,padding 更多的是内容与边框之间的距离,margin 是兄弟元素之间的距离,如果像这个例子中,里面的 box 距离外面的 box 在左边和上边都有一定距离的话,使用 margin 和 padding 都可以实现,但是推荐使用 padding,更加语义化。
三、盒子模型-margin 的上下传递问题
margin-top
传递即如果块级元素的顶部线和父元素的顶部线重叠,那么这个块级元素的 margin-top
值会传递给父元素。
margin-bottom
传递即如果块级元素的底部线与父元素的底部线重叠,并且父元素的高度是 auto,那么这个块级元素的 margin-bottom
会传递给父元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 300px;
height: 300px;
background-color: #f00;
}
.container {
width: 100px;
height: 100px;
background-color: #0f0;
/*上下会传递,margin-bottom 值会传递给父元素*/
margin-top: 100px;
/*左右不会传递*/
margin-left: 100px;
}
</style>
</head>
<body>
<div class="box">
<div class="container"></div>
</div>
</body>
</html>
原本应该是绿色的盒子与红色的盒子会根据绿色盒子的顶部有一定的间距,但是实际情况是绿色盒子和红色盒子之间没有间距,反而是绿色盒子的父元素即红色盒子的上外边距为设置的外边距。
也就是说绿色盒子这个子元素的 margin-top
传递给了父元素,但是 margin-left
并没有传递,并且是生效的。
那么实际开发中我们想让子元素的顶部距离父元素的顶部有一定的距离或者是说如何防止 margin-top
的传递问题呢?有以下几种解决方案:
- 给父元素设置
border
- 触发
BFC
,设置overflow
为auto
- 给父元素设置
padding-top\padding-bottom
.box {
width: 300px;
height: 300px;
background-color: #f00;
/*解决margin-top传递的问题,设置 border,颜色也可以设置为非透明*/
border: 1px solid rgba(0, 0, 0, 0);
/*与下面一行代码的效果一致*/
}
.container {
width: 100px;
height: 100px;
background-color: #0f0;
/*上下会传递,margin-bottom 值会传递给父元素*/
margin-top: 100px;
/*左右不会传递*/
margin-left: 100px;
}
通过设置父元素的 border 属性就可以解决 margin-top 传递的问题,修改 CSS 代码,在浏览器中打开 HTML 页面,效果如下:
除了设置边框,我们还可以触发盒子的 BFC 来解决 margin-top 传递的问题,将 CSS 代码修改为如下形式:
.box {
width: 300px;
height: 300px;
background-color: #f00;
/*方式一:解决margin-top传递的问题,设置 border,颜色也可以设置为非透明*/
/*border: 1px solid rgba(0, 0, 0, 0);*/
/*也可以吧边框设置为透明*/
/* border: 1px solid transparent; */
/*方式二:触发 BFC*/
overflow: auto;
}
.container {
width: 100px;
height: 100px;
background-color: #0f0;
/*上下会传递,margin-bottom 值会传递给父元素*/
margin-top: 100px;
/*左右不会传递*/
margin-left: 100px;
}
在浏览器中打开该 HTML 页面,效果如下:
前面演示了 margin-top
的值传递现象,margin-bottom
也会出现值传递现象,并且 margin-bottom
值传递现象要指定父元素的 height
为 auto
才会出现。
创建一个 HTML 页面,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 300px;
height: 300px;
background-color: #f00;
}
.container {
width: 100px;
height: 100px;
background-color: #0f0;
/*上下会传递,margin-bottom 值会传递给父元素*/
margin-bottom: 100px;
/* padding-bottom: 100px; */
}
</style>
</head>
<body>
<div class="box">
<div class="container"></div>
</div>
<div class="box2">我是box2</div>
</body>
</html>
在浏览器中打开该 HTML 页面,此时并不会出现值传递现象:
我们需要将父元素的 height 设置为 auto,就会发生 margin-bottom 传递的现象,修改 CSS 代码为如下形式:
.box {
width: 300px;
height: auto;
background-color: #f00;
}
在浏览器中打开该 HTML 页面,效果如下:
设置成 auto 后,就会发生 margin-bottom
的传递,此时盒子 的 height 就是由 container 的高度决定的,初始值就是 auto。
为了解决 margin
值传递的问题,除了上述两种方式之外,还有第三种方式,也是最为推荐的一种方式,就是当需要子元素和父元素之间有间隙时,不要子元素的使用 margin
来实现,而更推荐使用父元素的 padding
来实现。
margin
一般是用来设置 兄弟元素之间
的间距;padding
一般是用来设置 父子元素之间
的间距。