CSS第五篇:CSS属性-盒子模型
盒子模型
简介
- 盒子模型(Box Model)
-
HTML中的每一个元素都可以看做是一个盒子,如下图所示,可以具备这4个属性
- 内容(content)
- 盒子里面装的东西
- 内边距(padding)
- 怕盒子里装的东西损坏而添加的泡沫或者其他抗震的辅料
- 边框(border)
- 就是盒子的边框,比如木盒子四周的木板
- 外边距(margin)
- 为了方便取出,盒子之间保留一定的空隙
- 内容(content)
-
默认的盒子模型如下图所示
- 实际占用宽度 = 边框宽度(border-left+right)+内边距(padding-left+right)+内容宽度(weight)
- 实际占用高度 = 边框(border-top+bottom)+内边距(padding-top+bottom)+内容高度(weight)
-
盒子模型常用属性
-
内边距相关的属性(padding)
padding-left:左内边距 padding-right:右内边距 padding-top:上内边距 padding-bottom:下内边距 padding:上面四个属性的简写属性,上、右、下、左,顺时针方向
-
举例
/* 上、右、下、左 */ padding: 10px 20px 30px 40px; /* 上、右、下,左边等于右边 */ padding: 10px 20px 30px; /* 上下、左右 */ padding: 10px 20px;
-
padding的取值规律
- 按照顺时针方向设置:top、right、bottom、left
- 如果缺少left,那么left就使用right的值
- 如果缺少bottom,那么bottom就是用top的值
-
-
外边距相关的属性(margin)
margin-left:左外边距 margin-right:右外边距 margin-top:上外边距 margin-bottom:下外边距 margin:上面四个属性的简写属性,上、右、下、左,顺时针方向
- 设置特点跟padding一样
margin注意点
上下margin传递
- margin-top传递
- 如果块级元素的顶部线和块级父元素的顶部线重叠,那么这个块级元素的margin-top值会传递给父元素
-
代码举例:
<style> .div1 { width: 200px; height: 200px; background-color: #f00; /* 父元素也必须是块级,否则也不会传递 */ /* display: inline-block; */ } .div2 { width: 100px; height: 100px; background-color: #0f0; /* 子元素设置margin-top,父元素也会被传递 */ margin-top: 40px; /* 如果改成非块级,就不会传递了 */ /* display: inline-block; */ } </style> <body> <div class="div1"> <!-- 如果子元素跟父元素顶部不重叠,那么也不会传递 --> <!-- 123 --> <div class="div2"></div> </div> </body>
-
案例:
<style> div { background-color: #f00; width: 200px; height: 100px; } p { width: 50px; height: 50px; background-color: #ff0; } </style> <body> <div> <p></p> </div> </body>
-
效果图如下:
-
为何div标签顶部会出现间距?
- 因为p标签浏览器默认设置的有margin-top,然后对父元素div进行了margin-top传递
-
- margin-bottom传递
- 如果块级元素的底部线和块级父元素的底部线重叠,并且父元素的高度是auto,那么这个块级元素的margin-bottom值会传递给父元素
-
代码举例:
<style> .div1 { width: 200px; /* 不写height就相当于是auto */ /* height: 200px; */ background-color: #f00; /* 不是块级不会传递 */ /* display: inline-block; */ } .div2 { width: 100px; height: 100px; background-color: #0f0; margin-bottom: 40px; /* 不是块级不会传递 */ /* display: inline-block; */ } </style> <body> <div class="div1"> <div class="div2"></div> <!-- 底部不重叠,不会传递 --> <!-- 777 --> </div> 666 </body>
- 如何防止出现传递问题?
- 将父元素或者子元素设置为行内块级:
display: inline-block;
- 给父元素设置padding-top/padding-bottom,让顶部、底部不重叠.(这里的重叠指的是content重叠)
- 给父元素设置border
-
以后理解的更深入,还会学到其他解决办法
.div1 { width: 200px; height: 200px; background-color: #f00; /* 给父元素设置padding */ /* padding-top: 1px; */ /* 给父元素设置border */ border: 1px solid; }
- 将父元素或者子元素设置为行内块级:
- 建议
- margin一般是用来设置兄弟元素之间的间距
- padding一般是用来设置父元素之间的间距
-
比如上面的子元素与父元素之间的间距,就应该设置父元素的padding,而不是设置子元素的margin
.div1 { width: 200px; height: 200px; background-color: #f00; /* 父子元素,父元素用padding设置 */ padding-top: 40px; } .div2 { width: 100px; height: 100px; background-color: #0f0; /* 子元素设置margin-top,父元素也会被传递 */ /* margin-top: 40px; */ }
上下margin折叠
- 垂直方向相邻的2个margin(margin-top、margin-bottom),有可能会合并为1个margin,这种现象叫做collapse(折叠)
- 水平方向上的margin(margin-right、margin-left)永远不会collapse
- 折叠后最终的计算规则
- 如果都谁正数,最终值是:绝对值最大的那个正数值
- 如果都是负数,最终值是:绝对值最大的那个负数值
- 如果正数、负数都有,最终值是:最大正数和最小负数相加
- 如何防止margin collapse?
- 只设置其中一个元素的margin
- 条件允许的话,使用padding取代margin
- 以后理解的更深入,还会学到其他解决办法
- 折叠类型
-
两个兄弟块级元素之间上下margin的折叠
<style> div { width: 100px; height: 100px; background-color: #f00; } /* div1/div2同时设置,理论上应该是相加80,但是实际上合并在一起了,为40 */ .div1 { margin-bottom: 40px; } .div2 { /* margin-top: 40px; */ /* 正数,二者取最大值 */ margin-top: 60px; } </style> <body> <div class="div1"></div> <div class="div2"></div> </body>
- 父子块级元素之间margin的折叠
- 子元素将自己的margin-top传递给父元素,子元素就没有margin-top了
- 最终的结果为父元素的margin-top取这2个的计算值
<style> .div1 { width: 200px; height: 200px; background-color: #f00; margin-top: 40px; } .div2 { width: 100px; height: 100px; background-color: #0f0; margin-top: 60px; } </style> <body> <!-- div2的margin-top传递给div1,最后取最大值60px --> <div class="div1"> <div class="div2"></div> </div> </body>
-
无内容块级元素内部margin的折叠(折叠是可以连续的)
<style> .div1 { /* width: 200px; height: 200px; */ background-color: #f00; margin-top: 60px; margin-bottom: 40px; } </style> <body> 666 <!--有内容--> <!-- <div class="div1">div</div> --> <!--无只要删除内容,2个margin-top、bottom就会折叠在一起,最终是60 --> <div class="div1"></div> 777 </body>
-
- 总结:只要块级元素的上下(无论是父子还是兄弟)2个margin直接接触,就会出现折叠现象
border(边框)
- 边框相关的属性
- 边框宽度
border-top-width border-right-width border-bottom-width border-left-width
- border-width是上面4个属性的简写属性
-
边框的颜色
border-top-color border-right-color border-bottom-color border-left-color
- border-color是上面4个属性的简写属性
-
边框样式:
border-top-style border-right-style border-bottom-style border-left-style
- border-style是上面4个属性的简写属性
- 边框宽度
-
边框样式的取值
div { width: 100px; height: 100px; background-color: #f00; /* 设置边框这3个都不能少 */ /* 边框宽度 */ /* border-left-width: 5px; */ /* 边框颜色 */ /* border-left-color: #0f0; */ /* 边框样式 */ /* border-left-style: solid; */ /* 设置边框这3个都不能少 */ /* border-right-width: 5px; */ /* border-right-color: #00f; */ /* 边框样式 :虚线*/ /* border-right-style: dashed; */ /* 简写 */ /* 方式1: */ /* border-width: 5px 4px 3px 2px; border-color: purple green blue yellow; border-style: solid dashed dotted solid; */ /* 方式2: */ /* border-left: 5px solid yellow; border-right: 5px solid blue; border-bottom: 5px solid green; border-top: 5px solid purple; */ /* 同时设置4个方向的边框 */ border: 5px solid blue; /* 设置一个边框的颜色 */ border-right-color: green; border-bottom:none; }
- 边框的形状
- 边框的形状可能是
- 矩形、梯形、三角形等形状
- 本质:通过将内容的width、height为0,然后设置边框,显示不同的形状
/*梯形 */ div { width: 100px; height: 100px; background-color: #f00; /* 设置一个边框就是矩形,大于一个时就是梯形了 */ border-left: 5px solid yellow; border-right: 5px solid blue; border-bottom: 5px solid green; border-top: 5px solid purple; } /* 三角形:注意设置的2个边框必须相邻 */ div { width: 0; height: 0; /* 2个三角形 */ /* border-top: 50px solid yellow; */ /* 一个三角形 */ border-top: 50px solid transparent; border-left: 50px solid blue; transform: rotate(135deg); } /* 实现双色平分 */ div { background-color: #ddd; width: 100px; height: 50px; border-bottom: 50px solid #111; }
- 边框的形状可能是
行内级非替换元素注意点
-
以下属性对行内级非替换元素不起作用
width/height/margin-top/margin-bottom
-
举例
/* 行内非替换 */ span { background-color: #f00; /* 这4个属性都不行 */ width: 100px; height: 100px; margin-top: 100; margin-bottom: 100; /* 可以 */ margin-left: 40px; margin-right: 40px; } /* 行内替换 */ img { /* 都支持 */ width: 40px; height: 40px; margin-left: 40px; margin-bottom: 40px; } <body> <span>55555</span> <a>999</a> <br> 66666 <img src="./images/test.png" alt=""> </body>
-
-
以下属性对行内级非替换元素的效果比较特殊
- padding-top、padding-bottom、border-top、border-bottom
- 设置之后,占据空间不会向外部扩张,left、right没问题
-
代码举例
-
padding
/* 行内非替换 */ span { background-color: #f00; padding-bottom: 10px; padding-top: 20px; padding-left: 10px; padding-right: 20px; } div { background-color: #0f0; width: 100px; padding-top: 40px; padding-bottom: 40px; } <body> <span>55555</span> 8888 <br> 66666 <div>111</div> 777 </body>
-
border
/* 行内非替换 */ span { background-color: #f00; border: 10px solid yellow; } div { background-color: #0f0; width: 100px; border: 5px solid yellow; } <body> <span>55555</span> 8888 <br> 66666 <div>111</div> 777 </body>
-
- padding-top、padding-bottom、border-top、border-bottom
border-radius
-
圆角半径相关的属性有
border-top-left-radius border-top-right-radius border-bottom-left-radius border-bottom-right-radius
-
border-*-*-radius
定义的是四分之一椭圆的半径border-top-left-radius: 40px 20px;
- 第一个值是水平半径
- 第二个值是垂直半径(如果不设置,就跟随水平半径的值)
-
还可以设置百分比
border-top-left-radius: 50%;
- 参考的是border-box的宽度
- 一个盒子可以看成boder-box、content-box、padding-box
- 只要border-radius大于等于50%,就会变成一个圆
-
border-radius是一个缩写属性
border-radius: 10px 20px 30px 40px/15px 25px 35px 45px;
- 斜线前面是水平半径,后面是垂直半径
- 4个值的顺序是top-left、top-right、bottom-right、bottom-left(顺时针方向)
- 如果bottom-left没设置就跟随top-right
- 如果bottom-right没设置就跟随top-left
- 如果top-right没设置就跟随top-left
outline
- outline表示元素的外轮廓
- 不占用空间
- 默认显示在border的外面
- 每个部位都是完整连接的,不会像border那样有可能会断开(比如行内级非替换元素的换行)
- outline相关属性有
- outline-width
- outline-style:取值跟border的样式一样,比如solid、dotted等
- outline-color
- outline:outline-width、outline-sytle、outline-color的简写属性,跟border用法类似
- 应用实例
- 去除a元素,input元素的focus轮廓效果
- 举例使用:
-
例1:
div { width: 100px; height: 100px; background-color: #f00; border: 5px solid yellow; outline: 10px solid blue; } <body> <div></div> 666 </body>
-
例2:
div { width: 100px; height: 150px; background-color: #f00; } span { background-color: #0f0; /* border: 2px solid #ff0; */ outline: 2px solid #ff0; } <body> <div> 我是div我是div我是div我是div <span>我是span我是span我是span</span> </div> </body>
-
box-shadow
- box-shadow属性可以设置一个或者多个阴影
- 每个阴影用
<shadow>
表示 - 多个阴影之间用逗号
,
隔开,从前到后叠加 <shadow>
常见的格式如下
- 每个阴影用
<shadow>=inset? && <length>(2,4) && <color>?
- 第一个参数为inset,如果设置就代表内部阴影,一般不使用。
- 第二个可以设置4个length
- 第1个
<length>
:水平方向上的偏移,正数向右偏移 - 第2个
<length>
:垂直方向上的偏移,正数向下偏移 - 第3个
<length>
:模糊半径(blur radius),往四周扩散 - 第4个
<length>
: 延伸距离
- 第1个
- 第三个为color,阴影的颜色
-
代码举例:
body { background-color: #ddd; padding-left: 100px; padding-top: 100px; } div { width: 100px; height: 150px; background-color: #fff; /* 阴影向右边偏移10px 向下偏移20px 阴影颜色为红色 */ /* box-shadow: 10px 20px #f00; */ /* box-shadow: 0 0 30px 5px #f00; */ /* 半透明阴影 */ box-shadow: rgba(100, 100, 100, 0.3); }
text-shadow
- text-shadow用法类似于box-shadow,用于给文字添加阴影效果
-
text-shadow同样适用于
::first-line/::first-letter
div{ text-shadow: 0 0 15px #f00; }
box-sizing
- box-sizing用来设置盒子模型中宽高的行为
- content-box
- padding、border都布置在width、height外面
- border-box
- padding、border都布置在width、height里面
- content-box
- 图文解释
-
content-box
-
border-box
-
-
盒子模型
W3C发现IE8之前的方式有自己的优点,又来就出现了box-sizing属性,专门用于用户选择
-
代码举例
div{ width: 50px; height: 50px; background-color: #f00; padding: 20px; border: 5px solid #ff0; /* box-sizing用来控制width、heiht的行为 1. content-box:只包含width、height不包括padding和border 2. border-box:包括width、height、padding和border */ /* padding/border向内扩展向外扩展 */ box-sizing: content-box; /* padding/border向内扩展 */ box-sizing: border-box; }
width/height的百分比值
- 给width/height设置百分比值,那么这个百分比参考的是谁呢? 父元素的的widht/height吗?
- 查看W3C官方文档:
- width的百分比:
refer to wdith of containing block
,containing block
可以认为是父元素 - height: 也可以认为参考的是父元素的height
- width的百分比:
元素的水平居中显示
- 在一些需求中,需要元素(不是文字)在父元素中水平居中显示(父元素一般都是块级元素、inline-block)
- 子元素是:行内级元素、inline-block元素
- 水平居中:在父元素中设置
text-align:center
- 可以这么理解为什么text-align针对bolck元素无效
- text-align是为了让父元素内部的内容居中显示,居中的条件是父元素与子元素之间有空隙
- 行内、inline-block都符合
- 但是block尽管也可以设置width,表面看起来与父元素之间有了空隙,但是由于block的特性是占据父元素的整行,即时宽度设置有剩余也不允许其他元素占据,因此实际上还是占据了父元素整行,所以无法居中
- 水平居中:在父元素中设置
- 子元素是:块级元素
- 水平居中: 给自己(子元素)设置:
margin-left: auto; margin-right: auto;
- 理解:由于block占据父元素整行,那么从父元素无法设置,只能从当前子元素来设置
- 水平居中: 给自己(子元素)设置:
-
代码举例:
<style> div { background-color: #f00; width: 200px; height: 100px; /* 让元素的内容在元素里面水平居中 */ /* 文字、行内、行内块级 水平居中 */ /* text-align: center; */ } srong { display: inline-block; width: 50px; height: 50px; background-color: #ff0; } p { width: 50px; height: 50px; background-color: #ff0; /* 块级标签在父元素中居中 */ /* margin-left: auto; margin-right: auto; */ /*上下为0,左右为auto*/ margin: 0 auto; } </style> <body> <!-- 文字内容 --> <!-- <div>22222</div> --> <!-- 行内元素 --> <!-- <div> <span>我是span</span> </div> --> <!-- inline-block元素 --> <!-- <div> <srong></srong> </div> --> <!-- 块级 --> <div> <p></p> </div> </body>