CSS面试题 - 盒模型宽度计算

172 阅读1分钟

内容来源于双越老师课程(一天时间迅速准备前端面试 快速构建初级前端知识体系)。而我,只是按照自己的理解与思维习惯,在这做一个记录,希望自己能够时时温故而知新。

问题

请问如下代码中,div1 的 offsetWidth 是多大?

<style>
    #div1 {
        width: 100px;
        padding: 10px;
        border: 1px solid #ccc;
        margin: 10px;
    }
</style>

<div id="div1"></div>

答案:122

盒子模型

盒模型从内到外,包含内容(content)、内边距(padding)、边框(border)、外边距(margin)四个部分,内容又分为高(height)、宽(width)。

标准盒子模型

width 只包含内容宽度,不包含 paddingbordermarginheight 同理。

image.png

IE怪异盒子模型

width 包含内容宽度、paddingborder,仅不包含 marginheight 同理。

image.png

box-sizing 属性

CSS 中的 box-sizing 属性定义了 user agent 应该如何计算一个元素的总宽度和总高度。

语法:box-sizing: content-box|border-box|inherit; 默认值 content-box

  • content-box:与标准盒子模型表现一致
  • border-box:与IE怪异盒子模型表现一致
  • inherit:规定应从父元素继承 box-sizing 属性的值

width、clientWidth、offsetWidth、scrollWidth 区别

  • style.width:内容宽度,不包含内边距、边框、外边距。获取到的值是有单位的。
  • clientWidth:内容宽度 + 内边距,不包括边框、外边距。
  • offsetWidth:内容宽度 + 内边距 + 边框,不包括外边距。
  • scrollWidth:内容宽度 + 内边距 + 溢出尺寸,不包括边框、外边距。无溢出的情况下,与 clientWidth 相同。

上述问题中,这4项值分别为:

<style>
    #div1 {
        padding: 10px;
        border: 1px solid #ccc;
        margin: 10px;
    }
</style>

<div id="div1" style="width: 100px;"></div>

<script>
    console.log(document.getElementById("div1").style.width); // 100px 只有行内样式/内嵌样式才能获取到,或者使用 style.width 设置的
    console.log(document.getElementById("div1").clientWidth); // 100 + 10 + 10 = 120
    console.log(document.getElementById("div1").offsetWidth); // 100 + 10 + 10 + 1 + 1 = 122
    console.log(document.getElementById("div1").scrollWidth); // 100 + 10 + 10 = 120 无子元素,无溢出情况
</script>

问题补充

上述问题中,在不修改 width、padding、border、margin 前提下,如果想让 offsetWidth 等于100,该怎么做?

答案:设置 css 样式:box-sizing: border-box;

此时,width 包含内容宽度、paddingborder,内容宽度即 100 - 1 - 1 - 10 - 10 = 78

image.png