盒子模型简介
所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:margin,border,padding,和content。
盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
下面的图片说明了盒子模型(Box Model):
盒子类型的定义方式
盒子类型通过display属性进行定义。
常见的盒子类型
- inline:内联型
- block:块型
- inline-block:具有块型部分属性的内联型
- inline-table:可以让table具有inline的属性,即原table上下的元素可以排列在table的左右两侧
- list-item:将元素设置为列表类型,具有block型元素的属性;该类型的元素可以使用li元素相关的属性,如list-style。
盒子的总宽与总高的计算方式
显式声明的宽度与高度
元素的总宽度计算公式是这样的:
总元素的宽度=设置的宽度+左填充+右填充+左边框+右边框+左边距+右边距
元素的总高度最终计算公式是这样的:
总元素的高度=设置的高度+顶部填充+底部填充+上边框+下边框+上边距+下边距
隐式(即没有设置)与显式的区别
显式声明的情况下,元素的总宽度总高度会随着margin、padding、border变化;
隐式声明的情况下,元素的内容宽度内容高度会随着margin、padding、border变化
代码示例
<head>
<meta charset="UTF-8">
<title>宽度与高度的显式与隐式</title>
<style>
* {
margin: 0;
padding: 0;
}
section {
margin: 10px auto;
border: 1px solid;
width: 500px;
}
section div {
margin: 10px;
padding: 10px;
background-color: #8A2BE2;
}
section p {
margin: 10px;
padding: 10px;
background-color: #00ffcc;
}
section p span {
margin: 10px;
padding: 10px;
background-color: #007F0E;
}
#explicit div {
/*显式声明之后,margin、padding、border都会影响box的总宽度*/
width: 500px;
}
#explicit span {
/*inline元素,宽高无效;*/
width: 500px;
/*因为inline元素的宽高是由内容决定的,所以padding的多少不会影响正常的文档流
所以就出现了超出父元素高度的效果.*/
padding: 20px;
}
</style>
</head>
<body>
<section id="explicit">
<h2>显式的宽高:section设置了width为500px</h2>
<div>块级元素的父元素:显式宽度width:500px,总width=width+margin+border+padding,可超出父元素
<p>隐式宽度,自适应父元素;块级元素的子元素<span>内联元素</span></p>
</div>
</section>
</body>
box-sizing属性规定盒子的宽高计算方法
- 属性值为content-box(默认值):width与height的属性值表示内容的宽高,padding、border都会改变盒子的总宽高
- 属性值为border-box:width与height的属性值表示盒子总宽高,padding、border的设置不会改变盒子的总宽高,只会影响内容的宽高。
content-box和border-box属性值的区别就像隐式和显式设置宽高的区别一样,但是通过设置box-sizing:border-box,即使是显式设置height、width,padding、border的改变也不会影响盒子的总宽高。
<head>
<meta charset="UTF-8">
<title>设置盒子宽高针对的对象</title>
<style>
div{
height:100px;
width:100px;
}
.border_box{
/*设置box-sizing为border-box,则该元素的width、height包含border,padding,content的宽度*/
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
border:1em solid #ff0000;
padding:1em;
background-color: #ff0;
}
.content_box{
/*设置box-sizing为content-box,则该元素的width、height只包含内容区域的width、height,
增加border、padding属性会增加该元素的width、height*/
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border: 1em solid #ff0000;
padding: 1em;
background-color: #ff0;
}
</style>
</head>
<body>
<h2>整个div宽高分别为100px*100px;内容区域width=div.width-border.width-padding.width</h2>
<div class="border_box">border-box</div>
<h2>内容区域width=div.width;若给div添加border、padding属性,则div.width会增加</h2>
<div class="content_box">content-box内容区域宽高分别为100px*100px</div>
</body>
超出盒子范围的内容如何显示
通过overflow属性,可以设置当内容超出盒子宽高时的显式方式
overflow的属性值
- hidden:超出盒子范围隐藏内容
- scroll:出现超出盒子范围时,给盒子添加x,y轴上的滚动条;即使某方向上没有超出范围,也会出现灰条。
- auto:根据内容x,y轴方向的超出情况,自动添加滚动条;若自有x轴超出,则只添加x轴滚动条;常见的情况只出现y轴方向滚动条,因为浏览器对元素的换行处理是超出盒子范围自动换行,若white-space设置为nowrap,那么超出盒子宽度则出现x轴方向的滚动条。
- visible(默认):超出盒子范围的内容也正常显示
overflow的分开设置方式
- overflow-x:宽度超出范围的处理方式
- overflow-y:高度超出范围的处理方式
代码示例
<head>
<meta charset="UTF-8">
<title>超出盒子范围的内容如何显示?overflow</title>
<style>
*{
margin:0px;
padding:0px;
}
section{
/*将section设置为内联块元素,并于不影响block元素的作用的同时同行显示*/
display: inline-block;
}
h2{
font-size:12px;
margin: 5px 10px;
}
.box {
height: 100px;
width: 300px;
background-color: red;
margin-left: 10px;
}
#overflow_hidden{
overflow: hidden;
}
#overflow_auto{
/*因为浏览器默认会让超出范围的内容自动换行,故只有y轴出现滚动条*/
overflow: auto;
}
#overflow_scroll{
overflow: scroll;
}
#overflow_x{
/*设置为不换行*/
white-space: nowrap;
overflow-x: scroll;
}
#overflow_y{
overflow-y: scroll;
}
</style>
</head>
<body>
<section>
<h2>超出内容设置为隐藏,overflow:hidden</h2>
<div class="box" id="overflow_hidden">
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>根据内容情况自动设置scroll,overflow:auto</h2>
<div class="box" id="overflow_auto">
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>设置水平垂直方向都有滚动条,overflow:scroll</h2>
<div class="box" id="overflow_scroll">
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>单独设置水平方向为滚动,overflow-x:scroll</h2>
<div class="box" id="overflow_x">
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
</div>
</section>
<section>
<h2>单独设置垂直方向为滚动,overflow-y:scroll</h2>
<div class="box" id="overflow_y">
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
这是盒子里的内容,是很长一段重复的话;
</div>
</section>
</body>
外边距margin
常用属性
- margin:上 右 下 左 下方属性的简写方式;省略其中一个值的情况下,省略的值对于对角的值,如省略最后的左,那么左的值会和右相等。
- margin-top:上外边距
- margin-right:右外边距
- margin-bottom:下外边距
- margin-left:左外边距
上下外边距的折叠
- 兄弟元素之间的margin合并:
- 现象:若上下两个元素都有margin属性,则会发生合并,合并后间距等于外边距较大的值;即上元素margin-bottom:10px; 下元素margin-top:20px; 那么上下元素之间的间距为20px,并非30px。
- 解决:可以在不想被折叠的元素中添加display:inline-block属性值(ie7及以下会出现bug,但天猫都已经宣布放弃IE8了,那这里就不扯ie7的事了)或者float属性值防止兄弟元素之间的margin合并现象。
- 父子元素之间的margin合并:
- 现象:若父元素的第一个子元素或最后一个子元素分别有margin-top、margin-bottom属性,那么父元素的margin-top与第一个子元素的margin-top会出现合并现象,父元素的margin-bottom与最后一个子元素的margin-bottom也会出现合并现象。
- 解决:
1.子元素的margin-top改成padding-top,margin-bottom改成padding-bottom;
2.给父元素折叠方向上添加对应的padding或者border属性值,大小不能为0;
3.给父元素添加overflow:auto或者overflow:hidden的属性值同样可以解决
代码示例
<head>
<meta charset="UTF-8">
<title>margin的折叠问题</title>
<style>
* {
padding: 0px;
margin: 0px;
}
.parent {
background-color: #ffff00;
}
.sub {
margin: 10px;
background-color: #00ffcc;
}
.none {
/*inline-block元素设置的margin不会折叠,但元素变为内联元素,
故width默认为实际内容的宽度,可自行设置width值*/
display: inline-block;
background-color: #8A2BE2;
}
.two{
background-color: #8A2BE2;
}
.three {
/*父元素设置border或者padding或者overflow都可以组织子元素与父元素的折叠*/
/*border: 1px solid; 这种方式会增加盒子的宽高*/
/*padding:1px; 这种方式同样会增加盒子的宽高*/
overflow: auto; /*这种方式最理想,不会改变盒子的大小*/
}
</style>
</head>
<body>
<div class="parent">
<div class="sub">第一个子元素,子元素与父元素的margin折叠; 子元素margin-top:10px 父元素margin-top:0px; 所以折叠后的上外边距为10px;</div>
<div class="sub">第二个子元素,第一个子元素margin-bottom:10px; 该子元素margin-top:10px; 所以折叠后两元素的边距为10px</div>
<div class="sub none">第三个子元素,如果元素中使用display:inline-block或者float,那么兄弟元素之间的上下margin不会折叠</div>
<div class="sub">第四个子元素,第三个子元素设置了display:inline-block属性值,故两元素之间不会出现margin折叠;该元素的margin-bottom:10px与父元素的margin-bottom:0px折叠,故该元素与父元素之间没有外边距</div>
</div>
<div class="parent two">
<div class="sub">第二个父元素的第一个子元素margin-top:10px与第一个父元素的最后一个子元素margin-bottom:10px折叠,故两个父元素之间的间距为10px</div>
</div>
<div class="parent three">
<div class="sub">第三个父元素的第一个子元素margin-top:10px与第一个父元素的最后一个子元素margin-bottom:10px折叠,故两个父元素之间的间距为10px</div>
</div>
内边距padding
常用属性
- padding:上 右 下 左 下方属性的简写方式;省略其中一个值的情况下,省略的值对于对角的值,如省略最后的左,那么左的值会和右相等。
- padding-top:上内边距
- padding-right:右内边距
- padding-bottom:下内边距
- padding-left:左内边距
利用padding与inline元素突破父元素的高度
#explicit span {
/*inline元素,宽高无效;*/
width: 500px;
/*因为inline元素的宽高是由内容决定的,所以padding的多少不会影响正常的文档流;
只要内容height+上下padding高于父元素height就出现了超出父元素高度的效果.*/
padding: 20px;
}
边框border
border的四条边由四个倒梯形组成,若元素的总宽高由border决定时(即元素没有内容、没有padding、width与height都为0),那么border的四条边分别是四个倒三角形。
常用属性
- border-style:边框样式 如solid dotted等,是一种简写方式
- border-top-style:上边框样式
- border-right-style:右边框样式
- border-bottom-style:下边框样式
- border-left-style:左边框样式
- border-width:边框的宽度,是一种简写方式
- border-top-width:上边框宽度
- border-right-width:右边框宽度
- border-bottom-width:下边框宽度
- border-left-width:左边框宽度
- border-color:边框的颜色,是一种简写方式
- border-top-color:上边框颜色
- border-right-color:右边框颜色
- border-bottom-color:下边框颜色
- border-left-color:左边框颜色
代码示例
<head>
<meta charset="UTF-8">
<title>纯CSS画尖角</title>
<style>
* {
margin: 0px;
padding: 0px;
}
/*元素宽度和高度都为20px*/
.test {
width: 0;
height: 0;
border: 10px solid;
/*border上右下左的颜色*/
border-color: red yellow blue green;
}
.chat {
margin-top: 10px;
margin-left: 10px;
position: relative;
}
.sharp {
width: 0;
height: 0;
border: 10px solid;
/*除了左边与聊天内容背景有相同的背景颜色外,其他颜色都为透明,造成一个三角的形状*/
border-color: transparent #cceeff transparent transparent;
position: absolute;
left: -10px;
top: 9px;
}
.content {
background-color: #cceeff;
padding: 10px;
margin-left: 10px;
width: 100px;
}
</style>
</head>
<body>
<div class="test"></div>
<div class="chat">
<div class="sharp"></div>
<div class="content">QQ聊天内容</div>
</div>
</body>
CSS3中引入的border属性,同样有上述中的top、right、bottom、left属性
- border-radius:图像边框,数字值或%表示
- box-shadow:边框阴影
- h-shadow:必需。水平阴影的位置。允许负值。
- v-shadow:必需。垂直阴影的位置。允许负值。
- blur:可选。模糊距离。
- spread:可选。阴影的尺寸。
- color:可选。阴影的颜色。
- inset:可选。将外部阴影 (outset) 改为内部阴影。
- border-image:边框图片 后面有文章专门讲解