width:100%的问题

7,928 阅读6分钟

前言

本篇文章将研究一个CSS属性值width: 100%的问题。在CSS样式中,经常会见到有人将一个div的宽度设置为width: 100%。如下所示:

/* 已经清除过默认样式 */
.top_wrap {
    height30px;
    background-color#4285f4;
}

.top {
    width100%;
}

上面的样式中,很容易看出来,给.top设置width: 100%是希望.top的宽度和.top_wrap的宽度保持一致,如下图所示:

但是这样做,其实有一个潜在的问题,只是因为一些原因,容易被人忽略

width的百分比值

width的百分比值是相对于包含块的,也就是相对于父元素的宽度。但是这个宽度是指width宽度呢?还是指真实的宽度呢?

我们可以查看一下目前.top_wrap的宽度,如下图所示:是1080px

再来查看一下.top的宽度,如下图所示,也是1080px

但是,细心的你应该能发现,.top_wrap元素目前的真实宽度和width宽度是一致的,因为没有设置内外边距,也没有设置border

那么,我们给.top_wrap设置一下内外边距,

.top_wrap {
    height30px;
    padding0 10px;
    margin0 10px;
    background-color#4285f4;
}

来看一下父元素.top_wrap尺寸

width(内容宽度)已经变成了1040px,比原来的1080px少了40px。为何会少40px?你能猜出来吗?

这个问题,我们待会儿再说。

再来看一下子元素.top的尺寸,可以看到,也为1040px

由此,我们可以得出一个结论:当width设置为百分比时,它的值相对于父元素的width,而非真实宽度。

百分比值潜在的问题

弄懂了width百分比这个值相对于谁的问题之后,就要引入潜在的问题了

.top_wrap {
    height30px;
    background-color#4285f4;
}

.top {
    width100%;
}

我们知道,标准盒模型中,width的值默认是content-box的值,即内容区域的宽度,是不包含内边距和边框的。

我们还恢复.top_wrap原来的尺寸,取消内外边框,这个时候.top_wrap的宽度为1080px,那么.topwidth如果设置为100%,它将也是1080px

此时,我们给.top元素设置内边距,试一下:

.top_wrap {
    height30px;
    background-color#4285f4;
}

.top {
    padding0 10px;
    width100%;
}

查看一下.top的尺寸,如下图所示:width的值依旧为1080px了,但真实占据的宽度已经变成了1100px

潜在的问题出现了:子元素已经超出父元素区域了,页面已经出现滚动条了,我们的页面显示出问题了

原因就在于,父元素的width属性值并不是真实的宽度,子元素的width的百分比值1080px也不是真实宽度,一旦设置了内外边距及边框等属性,真实宽度必然超出父容器。

那么有人说,既然我知道子元素的真实宽度需要是1080px,这其中包括了内外边距和边框,那么将这些值从中减去,不就是width值了吗?

于是:

.top_wrap {
    height30px;
    background-color#4285f4;
}

.top {
    padding0 10px;
    /* 1080px - 10px *2 = 1060px */
    width1060px;
}

这样的话,子元素的真实宽度就和父元素的真实宽度(父元素没有设置内外边距和边框)一致了,都为1080px,就刚好放下

但是,width的值就必须手动进行计算了,非常麻烦

神奇的width:auto属性

你大可不必手动计算子元素的width的值为多少,因为浏览器可以帮你自动计算,只要你不设置width的值。对了,不设置!因为width的默认值为auto

这个值将会自动帮你计算子元素的width属性值

尝试做如下设置:

.top_wrap {
    height30px;
    padding0 10px;
    background-color#4285f4;
}

.top {
    margin0 10px;
    padding0 10px;
}

父元素的真实宽度为1080px,我们为其设置了左保内边距各10px,则其剩余可用宽度为1060px,这个值就是父元素的width值。如下图所示:

那么子元素的真实可用宽度就只剩1060px了,我们又为其设置了左右内外边框各10px,则子元素的剩余可用宽度为1020px。如下图所示:

这样设置以后,width的值就和我们自己计算的值一致了,子元素也不会超出父元素,不会影响页面。好处就在于,浏览器会为我们自动计算,不需要我们管。即使你后期调整了浏览器,width的值也会自动调整,仍然不需要我们操心。

说到这里,不知道前面的那个子元素width少了40px问题的答案你想明白了没?

因为父元素的可用宽度为1080px,这将是子元素能占据的最大的真实宽度,因为没有给子元素设置width,其值将是auto,由浏览器自动计算。

之后我们给子元素设置了左右内外边距各10px,一共40px,由此,width的值就是1080px - 40px = 1040px了。少去的40px,就是浏览器自动判断出来,减去的。

总结

  1. 如果想让子元素占据父元素的剩余可用空间,不应设置100%,而应该不设置,使其保持默认值
  2. width: 100%不是针对父元素的真实宽度而言的,而是相对于width属性。如果父元素和子元素都没有设置内外边距、边框等属性时,子元素设置width: 100%时,此时,才和父元素的“真实”宽度相等(其实是和父元素的width值相等)。