在标准盒模型中,width和height给定的是元素内容区域的宽度和高度,而实际的盒子宽度和高度会加上设置的边框border和内边距padding值。当我们设置响应式布局等,需要注意这个特性,否则会导致元素看起来溢出了。下面从width属性入口来探索下如何解决这样的问题。
width定义
width 属性用于设置元素的宽度。width 默认设置内容区域的宽度,但如果 box-sizing 属性被设置为 border-box,就转而设置边框区域的宽度。
其实MDN上这句话已经非常准确了,但是我们常常忽视这些定义。毕竟纸上得来终觉浅,但是定义的总结非常精炼,反而应该是我们理解后所要掌握的。下面我们解析一下这句话。
width基础用法
width属性值可以设置为:
/* <length> values */
width: 300px;
width: 25em;
/* <percentage> value */
width: 75%;
/* Keyword values */
width: max-content;
width: min-content;
width: fit-content(20em);
width: auto;
/* Global values */
width: inherit;
width: initial;
width: unset;
重点要看一下 width:100% 这个百分比设置,一般来说,当我们对子元素设置 width:100% 的时候,意味着子元素的宽度就等于父元素的宽度。
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
.parent {
width: 100px;
height: 100px;
background-color: rebeccapurple;
}
.child {
width: 70%;
height: 100%;
background-color: lightgray;
}
最简单的使用就是这样,子元素的宽度等于父元素宽度的70%。
问题出在哪
上面的说法并不准确,因为如果给子元素加上padding/border后,在标准模型中,如果你给盒设置width和 height,实际设置的是 content box。padding 和 border 再加上设置的宽高一起决定整个盒子的大小。那这样不就有问题了,如果子元素设置了border/padding,看起来就会溢出父元素了。
- 设置
padding后
- 设置
border后
由此可知,子元素设置宽度的百分比是指子元素内容区域相对于父元素内容区域,所以造成了子元素溢出了父元素。
使用box-sizing解决
box-sizing规定了如何计算一个元素的总宽度和总高度。
- content-box 是默认值。如果设置一个元素的宽为 100px,那么这个元素的内容区会有 100px 宽,并且任何border和padding的宽度都会被增加到最后绘制出来的元素宽度中,也就是溢出的问题;
- border-box 告诉浏览器要设置的边框和内边距的值是包含在 width 内的。也就是说,如果你将一个元素的 width 设为 100px,那么这 100px 会包含它的 border 和 padding,内容区的实际宽度是 width 减去 (border + padding) 的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。
由此可知,当设置box-sizing:border-box时,子元素设置宽度的百分比是指子元素整个盒子区域相对于父元素内容区域。
.child {
...
border: 5px solid darkgoldenrod;
box-sizing: border-box;
}