为了方便理解,在这里定义一些值的名称:
个人感觉这种复杂盒中盒的练习题更能锻炼自己对padding、margin的运用和理解,方法有很多,我先写写自己的几种方法和思路:
这是边做边写的思路与过程
效果图:(这里应该做两条虚线的,我以为是双线)
思路:(由内及外)
✅准备工作:
①首先分析一下需要几个盒子:这里我是分了5个盒子,两个有背景色的盒子绿色和粉色,剩下三个都是没背景色,只为了加边框的盒子。
【绿色部分和黄色边为一个盒子】【双虚线为一个没背景色的盒子】【粉色背景为一个盒子,没有边】【蓝色实线为一个没有背景色的盒子】【虚线为一个没有背景色的盒子】
(当然,你再分多几个盒子都没事,能达到效果就行,不过写代码还是以简约为主,少一些无用代码)
②因为没有规定的宽高和粗细,所以自己定了一下值,代码中注释部分就是定义的值,然后边的大小统一2px(后来发现太粗了)。
💦 关于定值:
绿色盒子宽高为50px(整数对写代码友好),边为2px;
双线盒子宽高为100px,边为2px;
粉色盒子宽高为150px,无边;
蓝色实线盒子宽高为170px,无背景色;(这里和粉色盒子间的间距比其他间距小)
黑色虚线盒子宽高为200px,无背景色;
💥💥💥注意:这里有个关于边的粗细带来的错误例子!!!💥💥💥
比如,绿色盒子部分,实际定义的宽高(面积)并不是50×50,而是加上了边的宽度后的(50+2×2)×(50+2×2)=54×54。如果要定义50×50,则该盒子的宽高应该是 50-边粗细×2=46px(第二个方法会改正)。
✅开始写代码:
我这里是由内及外的写法,从最里面的盒子开始逐渐完成效果,然后完成外层盒子的效果。
③使用div或p或span(或混用,不过最外层最好用div,还有记得行内元素块状化就行了)完成盒子嵌入的结构,我这里是div{ div{ div{ p{ span{}} } } },只有span是行内元素,用display: block;
块状化。别忘了给body和p元素去默认样式内外边距:body,p{padding:0px; margin:0px;}
④完成结构部分,就来为这些盒子分别添加可以看见的属性:背景色、边框,并且给每个盒子width、height赋值上定义的值(在后面值会修改,且可用来对比参考)。
(剩下的就是调整位置的步骤了)
🉑绿色盒子在双线盒子居中部分
⑤ 首先调整绿色盒子在双线盒子间的居中(使用margin,不影响面积)
∵绿色盒子实际宽度=内宽+边宽×2=50+2×2=54px(外宽),
又∵绿色盒子是在双虚线盒子内部居中,
∴这里只用内宽和内高(内面积)的值。
∴margin-left=margin-right=(双线盒子内宽-绿色盒子外宽)/2=(100-54)/2=23;
又∵是在正方形盒子内居中,
∴margin各方向的值都相等,
∴给绿色盒子添加的CSS属性为margin: 23px;
【到这里就已经完成了绿色盒子在双线盒子里的居中】
🉑双线盒子在粉色盒子居中部分
⑥以上个步骤为例,按道理,在该子级元素——双线盒子内直接加入margin:23px;(因为间距x我这里是当作相等的)就可以了,但是这里问题就来了,明明在双线盒子内设置margin,但它的父元素(粉盒子)却跟着跑了 【两个父子元素,内部的盒子给margin-top,其父级也会受到影响,同时产生上边距,父子元素会进行粘连。✅外边距塌陷现象✅】
🔺🔺🔺在这里,又分化出两种解决的方法:🔺🔺🔺
🅰不用margin,改用padding(用padding就麻烦点了,因为还得减去相应的宽高值):
(无论是内边距padding还是外边距margin都是边距,所以都是同样计算方式,且我上面就写了,除了蓝色实线盒子那里的间距,其他盒子的间距都是一样的,23px)
/*CSS部分*/
body,p{
padding: 0px;
margin: 0px;
}
.dotted{
border:2px dotted #000000;
width: 200px; /*200*/
height: 200px;
}
.blue-solid{
border:2px solid #0000ff;
width: 170px; /*170*/
height: 170px;
}
.pink-box{
background-color: #ffa0df;
width: 104px; /*150*/
height: 104px; /*原值 - (padding-top + padding-bottom) = 150-23×2 = 104px*/
padding: 23px; /*增加padding填充*/
}
.double{
border: 2px double #ffffff;
width: 100px; /*100*/
height: 100px;
}
.box-green{
display: block;
background-color: #adff2f;
border: 2px solid #ffff00;
width: 50px; /*50*/
height: 50px;
margin: 23px;/*这里是第5步的*/
}
🅱还是用margin,利用overflow: hidden;
来解决外边距塌陷现象。
/*CSS部分*/
body,p{
padding: 0px;
margin: 0px;
}
.dotted{
border:2px dotted #000000;
width: 200px; /*200*/
height: 200px;
}
.blue-solid{
border:2px solid #0000ff;
width: 170px; /*170*/
height: 170px;
}
.pink-box{
background-color: #ffa0df;
width: 150px; /*150*/
height: 150px;
overflow: hidden; /*overflow: hidden;消除外边距塌陷现象*/
}
.double{
border: 2px double #ffffff;
width: 100px; /*100*/
height: 100px;
margin: 23px; /*两盒子间的边与边的间距,这里我是设置一样的*/
}
.box-green{
display: block;
background-color: #adff2f;
border: 2px solid #ffff00;
width: 50px; /*50*/
height: 50px;
margin: 23px;/*这里是第5步的*/
}
------------------------------------------------------------------分割线------------------------------------------------------------------
写到这里,我放弃了分步解释,直接丢代码了,原因:padding和margin都是可以调整内容位置的,除了相互配合混合使用,还能单纯用padding或单纯用margin都能达到效果,我这里就上传这三种(纯padding、纯margin、两者混用)的代码吧。
-
padding、margin混用(我这里以margin为主,padding为辅)
至于怎么混用又分很多种,比如在哪个元素放padding,哪个元素放margin,哎,多敲代码做练习题就会了
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>盒子和边练习</title>
<style type="text/css">
body,p{
padding: 0px;
margin: 0px;
}
/*204×204*/
.dotted{
border:2px dotted #000000;
width: 200px; /*200*/ /*实际盒子宽高为 200+2×2=204*/
height: 200px;
}
/*174×174*/
.blue-solid{
border:2px solid #0000ff;
width: 170px; /*170*/ /*实际盒子宽高为 170+2×2=174*/
height: 170px;
margin: 13px; /*给此元素居中设置外边距,你不喜欢也可以换成padding,但是又得计算宽高怎么修改*/
/*上面这步,是第 8 步的步骤,令该盒子在父元素盒子里面居中*/
}
/*150×150*/
.pink-box{
background-color: #ffa0df;
width: 104px; /*150*/
height: 104px;
/*这里才是精髓部分*/
padding: 23px;
/*上面这步,是上面第 6 步中的 A 方法,目的是通过减去该盒子的宽和高,再填充,来使子元素盒子居中*/
margin: 10px;
/*上面这步,其实是第 7 步的步骤,使用外边距,令该盒子在父元素盒子里面居中*/
}
/*104×104*/
.double{
border: 2px double #ffffff;
width: 100px; /*100*/ /*实际盒子宽高为 100+2×2=104*/
height: 100px;
}
/*54×54*/
.box-green{
display: block;
background-color: #adff2f;
border: 2px solid #ffff00;
width: 50px; /*50*/ /*实际盒子宽高为 50+2×2=54*/
height: 50px;
margin: 23px; /*给此元素居中设置外边距*/
}
</style>
</head>
<body>
<div class="dotted">
<div class="blue-solid">
<div class="pink-box">
<p class="double">
<span class="box-green"></span>
</p>
</div>
</div>
</div>
</body>
</html>
-
纯margin(这个超简洁超方便)
👉👉👉请问为什么父元素一定要设overflow: hidden; 子元素的margin才有效? 不设置的话 父元素也会跟着margin跑
👉👉👉为什么"overflow:hidden"能清除浮动的影响
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>盒子和边练习</title>
<style type="text/css">
body,p{
padding: 0px;
margin: 0px;
}
.dotted{
border:2px dotted #000000;
width: 200px;
height: 200px;
}
.blue-solid{
border:2px solid #0000ff;
width: 170px;
height: 170px;
margin: 13px;
}
.pink-box{
background-color: #ffa0df;
width: 150px;
height: 150px;
margin: 10px;
/*下面的overflow: hidden;是跟子级的margin一个步骤的*/
overflow: hidden;
}
.double{
border: 2px double #ffffff;
width: 100px;
height: 100px;
/*在这里加margin,如果出现外边距塌陷,就要在父级加overflow: hidden;*/
margin: 23px;
}
.box-green{
display: block;
background-color: #adff2f;
border: 2px solid #ffff00;
width: 50px;
height: 50px;
margin: 23px;
}
</style>
</head>
<body>
<div class="dotted">
<div class="blue-solid">
<div class="pink-box">
<p class="double">
<span class="box-green"></span>
</p>
</div>
</div>
</div>
</body>
</html>
-
纯padding(这个超复杂也麻烦,步骤多在了算每个元素需要减去的宽和高上)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>盒子和边练习</title>
<style type="text/css">
body,p{
padding: 0px;
margin: 0px;
}
/*204×204*/
.dotted{
border:2px dotted #000000;
width: 174px;
height: 174px;
padding: 13px;
}
/*174×174*/
.blue-solid{
border:2px solid #0000ff;
width: 150px;
height: 150px;
padding: 10px;
}
/*150×150*/
.pink-box{
background-color: #ffa0df;
width: 104px;
height: 104px;
padding: 23px;
}
/*104×104*/
.double{
border: 2px double #ffffff;
width: 54px;
height: 54px;
padding: 23px;
}
/*54×54*/
.box-green{
display: block;
background-color: #adff2f;
border: 2px solid #ffff00;
width: 50px;
height: 50px;
}
</style>
</head>
<body>
<div class="dotted">
<div class="blue-solid">
<div class="pink-box">
<p class="double">
<span class="box-green"></span>
</p>
</div>
</div>
</div>
</body>
</html>
最后的改良:
①双虚线用成双线了,这次多做一个盒子,形成双虚线;
②修改了实际盒子的值,上面没有考虑到内容+边,所以最后得出的值算上了边;
③直接采用纯margin的思路,更为方便快捷。
改良版的思路(更为简洁清晰)
- 首先观察图片,然后自己定一下值:(至于颜色的值…打开图用ps吸管工具吸啊)
宽×高部分:
box1:500×500
box2:440×440
box3:400×400
box4:300×300
box5:280×280
box6:150×150
边的部分:
box1-border-size:5px
box2-border-size:5px
box3-border-size:none
box4-border-size:3px
box5-border-size:3px
box6-border-size:5px
至于边距,则是
∵(父元素内宽 - 子元素外宽)/2,
又∵内宽=外宽-边大小;
∴边距=(父元素外宽-父元素边大小-子元素外宽)/2。 - 然后开始敲代码
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>盒子练习改良版</title>
<style type="text/css">
body{
padding: 0px;
margin: 0px;
}
/*500×500*/
/*这里写上定义好盒子的宽高,然后样式里的 widht + padding-right + padding-left = 500
height + padding-top + padding-bottom = 500 即可*/
.box1{
border: 5px dotted #000000;
width: 490px;
height: 490px;
margin: 50px; /*这里只是为了好看,位移到浏览器中间(非居中,随便挪一下的),突出盒子而已*/
}
/*440×440*/
.box2{
border: 5px solid #0000ff;
width: 430px;
height: 430px;
margin: 25px;
}
/*400×400*/
.box3{
background-color: #ffa0df;
width: 400px;
height: 400px;
margin: 15px;
/*因为在box4处加上margin就会出现外边距塌陷,所以在box4父级,即此处加overflow: hidden;处理塌陷*/
overflow: hidden;
}
/*300×300*/
.box4{
border: 3px dotted #ffffff;
width: 294px;
height: 294px;
margin: 50px;
}
/*280×280*/
.box5{
border: 3px dotted #ffffff;
width: 274px;
height: 274px;
margin: 7px;
}
/*150×150*/
.box6{
border: 5px solid #ffff00;
background-color: #adff2f;
width: 140px;
height: 140px;
margin: 62px;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">
<div class="box3">
<div class="box4">
<div class="box5">
<div class="box6"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
其他思路(这里有两个)
👉利用父元素大小被子元素撑开的特性,来完成该效果:
原答案传送门:https://www.cnblogs.com/TCB-Java/p/6857930.html
(下面是我自己运用该思路来完成的过程以及一些思路解析)
①关于宽高部分,因为要利用父元素被子元素内容撑开的特性,所以只需设置最里面元素的宽高,以及最外层元素的宽,至于其他元素的宽、高则会通过padding来填充撑开;
②给每个盒子设置好基本样式属性后,就开始用padding来填充了,这里随便任意值,可大可小,这步不需要计算;
③到这里才需要计算,不过却很简单,这里计算最外层盒子的宽值,因为最外层是块级元素,会占一行,所以宽=body,所以通过赋值来挤压子元素(这里的子元素都是块级元素div,都会在父元素内独占一行)的宽达到真正的居中效果。
④关于最外层盒子box1的宽有两种计算方式,但都一个思路:
设box1的内宽为X(不要连box1的padding和边也算进去,因为需要被box2撑开,所以box1内宽=box2外宽,中间加上padding: Npx;填充就能达到居中)
A:X=box6[内宽+边宽×2]+box5[(填充+边宽)×2]+box4[(填充+边宽)×2]+box3[填充×2]+box2[(填充+边宽)×2]
=[90+10]+[28×2]+[13×2]+[25×2]+[20×2]
=100+56+26+50+40
=272px;
B:X=2×(box6[内宽/2+边宽]+box5[填充+边宽]+box4[填充+边宽]+box3[填充]+box2[填充+边宽])
=2×([45+5]+[25+3]+[10+3]+[25]+[15+5])
=2×136
=272px;
附上代码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>盒子模型练习</title>
<style type="text/css">
body,p{
padding: 0px;
margin: 0px;
}
.box1{
border: 5px dotted #000000;
padding: 20px;
width: 272px;
}
.box2{
border: 5px solid #0000ff;
padding: 15px;
}
.box3{
background-color: #ffa0df;
padding: 25px;
}
.box4{
border: 3px dotted #ffffff;
padding: 10px;
}
.box5{
border: 3px dotted #ffffff;
padding: 25px;
}
.box6{
border: 5px solid #ffff00;
background-color: #adff2f;
width: 90px;
height: 90px;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">
<div class="box3">
<div class="box4">
<div class="box5">
<div class="box6"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
👉👉运用绝对定位position:absolute;
和相对定位position:relative;
的方法
(这个方法在下篇写关于position的博文时,我再写过程和思路)
原答案传送门:https://zhidao.baidu.com/question/1736920567003087267.html