CSS将页面中的所有元素都设置成一个矩形盒子,所谓的网页布局本质上就是将不同的盒子放在合适的位置。
盒子模型的四大要素
content 内容区,元素中的所有子元素和文本内容在内容区中排列,内容区默认是由width和height两个属性设置的。
border 边框,是盒子的边缘,用于分割内容区和外部区的,一般至少设置三个属性,border-width(宽度)、bordr-color(颜色)、border-style(样式),同时这三个属性都可以根据上下左右四个位置设置不同值呈现不同效果。
padding 内边距,是内容区和边框之间的距离,它可以设置上下左右四个位置,并且内边距的设置会影响盒子的大小。
margin 外边距,不会影响盒子大小,但是会影响盒子的位置。因为元素在页面中是按照自左向右的顺序排列的,所以默认情况下如果设置左和上外边距时会移动元素自身,设置下和右外边距时会移动其它元素。
- 以下代码是一个标准的盒子模型设置,border、padding、margin都可采用简写形式。
.box1 {
width: 200px;
height: 200px;
padding: 5px;
margin: 3px;
border: 3px solid red;
background-color: antiquewhite;
}
盒子尺寸
默认情况下,盒子可见框的大小是由content,padding和border共同决定的,计算盒子大小时要将三个区域加到一起计算。
box-sizing 属性 用于设置盒子尺寸的计算方式,默认值是content-box:
content-boxwidth和height设置的是content的大小,padding和border的修改会影响盒子大小。border-boxwidth和height设置的是整个盒子可见框大小,即content + padding + boder,该状态下修改padding和border,content会跟着改动,不会影响盒子可见框大小。
盒子水平布局
元素在其父元素中水平方向的位置由以下几个属性共同决定margin-left、border-left、padding-left、width、padding-right、border-right、margin-right,并且它们的值总和 = 其父元素内容区的宽度(必须满足)。
如果等式不成立,则称为过度约束,浏览器会自动调整等式。
- 如果这七个属性都没有设置
auto,则会调整margin-right的值以使等式成立。如果有属性设置了auto,则会调整设置auto的属性的值以使等式成立。 - 如果将
width和margin都设置为auto,margin会自动为0,width变成最大值。 - 如果
width为固定值,margin为auto,则两个外边距为相同值,也就是居中。 - 如果子元素的宽度值超过父元素内容区宽度,则会调整
margin-right的值为负值。
盒子垂直方向布局
子元素是在父元素的内容区中排列的,默认情况下父元素的高度会被子元素撑开。
如果子元素的大小超过了父元素,子元素会从父元素中溢出。遇到这种情况时,可以给父元素添加overflow属性处理溢出的子元素,overflow可以设置以下值:
visible默认值,子元素会从元素中溢出,在父元素外显示。hidden溢出内容被裁剪,不会显示。scroll同时生成水平和垂直方向的滚动条,以便查看完整的内容。auto根据需要生成滚动条。
外边距的折叠
两个盒子相邻的垂直方向外边距会发生重叠现象。
兄弟元素的相邻垂直外边距会取两者之间的较大值(正值),比如以下代码中最终的外边距取值是150px。注意如果取值是一正一负则取两者之和。如果两者都是负值,则取绝对值较大值。
不过兄弟元素的外边距折叠问题一般无需处理。
.box1, .box2 {
width: 200px;
height: 200px;
}
.box1 {
margin-bottom: 150px;
background-color: #bfa;
}
.box2 {
margin-top: 100px;
background-color: orange;
}
父子元素的相邻垂直外边距,子元素的上外边距会传递给父元素,父元素自身也会发生偏移,这样会影响页面布局,比如以下代码会导致父盒子box1的上外边距也是100px。
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
}
.box2 {
width: 100px;
height: 100px;
margin-top: 100px;
background-color: orange;
}
第一种解决方案是父元素设置padding值,但要注意因为padding会影响盒子大小,所以同时要调整盒子的宽高属性以达平衡。比如以下代码padding-top设置了100px,则height要减去100px。
.box1 {
width: 200px;
height: 100px;
padding-top: 100px;
background-color: #bfa;
}
第二种解决方案是父元素设置border值,原理是用border隔离父元素和子元素的上外边距,使它们不再重叠。但是和padding一样,会影响盒子大小,需要调整其它属性配合使用。
行内元素的盒子模型
行内元素不支持设置宽高属性,它的内容区大小是由其内部文本或者子元素决定的。
行内元素可以设置boder、padding,margin,但是垂直方向的设置不会影响页面的布局,比如以下代码中span元素虽然设置了padding和margin,但是div仍然是参照span元素的内容决定自身位置。
span {
padding: 100px;
margin-bottom: 100px;
background-color: orange;
}
div {
width: 200px;
height: 200px;
background-color: #bfa;
}
如果需要给行内元素设置宽高,则需要通过display属性设置元素类型,display可以设置以下值:
inline将元素设置为行内元素。block将元素设置为块元素。inline-block将元素设置为行内块元素。table将元素设置为一个表格。none元素不在页面中显示,完全隐藏。
注意行内块元素和行内元素换行/空格都有文本分隔符问题 比如多个图片之间有间隙,多个a标签之间有间隙。
另外说一下visbility属性,它用于设置元素的显示状态,它可以设置以下值:
visible默认值,元素在页面中正常显示。hidden元素不在页面中显示,隐藏但是依旧占据页面的位置。