你知道你写的CSS让元素显示成什么样子吗?

背景

由于前端工程化的发展,很多同学因为借助“全家桶”能够很方便的使用一些Less/Sass/Stylus等CSS预处理器,于是就大谈模块化、组件库设计之类的概念。但是因为对基础知识的缺乏,导致自己写的CSS代码会表现成什么样子都不清楚。工程化、库、框架的存在是为了让工程师更方便的设计程序来满足业务需求。主要是为了“方便”,而不是说工程师可以“不懂”、“不了解”基础。因为不懂基础知识是无法设计出来基本的、合理的代码,或者至少会影响开发效率。

最近几年由于面试比较多,设计了一些题目来考察盒模型、闭包、面向对象等前端基础知识,很多同学都都挂在了基础上,于是想写一些文章分享一下这些知识点。这篇文章主要浅谈一下面试题目中的一个出问题最多的盒模型题目,希望能引出一些大家对于CSS方面的思考。

题目

页面上有一个div,样式如下:

div {
width: 200px;
height: 200px;
margin: 10px;
padding: 10px;
border: 10px solid #000;
background-color: red;
}

问:这个div的红色区域有多大?

分析过程

1、先看display(display的值类型:W3C定义MDN解释)

正常情况下,CSS布局首先要看的是display,display的值有很多种,通常一个元素的display的“外显值”(<display-outside>)会影响这个元素的展现外观,它父级元素的“内显值”(<display-inside>)也会影响子级元素展现的外观。这个题目的div没有提到父级元素,默认的div元素的display元素的“外显值”是block。因为是默认值,简单起见,我们先忽略这个属性的影响。(注:这里并不是display不重要,如果给这个元素加个父元素,给父元素加上display的内显值,会极大影响此题的结果)。

2、再看box-sizing(box-sizing的值类型:W3C定义MDN解释)

在display是block的情况下,影响题目中的css样式的第二个属性就是box-sizing属性,在标准浏览器中,这个属性的默认值是content-box。所以暂时我们先按照content-box来计算。

一个正常的盒模型是这样的:

参见:W3C盒模型定义

盒模型从内到外分为四层:content、padding、border、margin。content-box的情况下,width、height的值是作用域content上,其他的东西围在content外面的。

3、再看background-clip:(background-clip的值:W3C定义MDN解释

我们题目中的background是red,而答案问的也是红色区域到底有多大,那么background到底包含哪几个部分很关键。而background到底包含哪几个部分,是background-clip来决定的。默认的值是border-box,所以默认情况下,红色区域(即背景)包含content(200px)、padding(10px*2)、border(10px*)三部分。最终红色区域的值是:200+10*2+10*2=240px。但是,因为border是#000(即黑色),会遮盖红色区域,所以240还需要减去黑色边框的宽度,即240-10*2=220px。

答案

所以,经过上述分析过程,全默认值的情况下,上面题目的红色区域应该是220px。

仅此而已吗?那上面巴拉巴拉的1、2、3条是干什么的?

事实上,我们的题目只是为了看候选人的技术深度和广度,出题只出了一种默认情况,后续深聊的过程会去根据上述三个关键条件来扩展追问。比如:

  • 如果border: 1px solid transparent,红色区域多大?
  • 如果background-clip是padding-box和content-box,红色区域有多大?
  • 如果box-sizing是border-box,红色区域有多大?
  • 如果div外层的body加上display:flex;再加上兄弟元素flex:1,红色区域又是多大?
  • 等等

而上述变化的数量是共同作用影响的,所以总的问法和答案个数是,上述三条属性值个数的乘积。甚至还得再乘以2(即透明border和非透明border)。

总结

一些简单的代码,通常是伴随着一系列技术基础细节,那些基础的原理才是最根本解决问题的理论。了解基础原理,才能清楚的明白自己写出来的代码会被执行成什么样子,仅仅期待与靠背诵来记住的单个细节和案例,仅仅是头痛医头脚痛医脚而已。不管是CSS、JS,还是HTTP本身及其缓存和请求策略,以及它涉及到的DNS、CDN,甚至SSR涉及到的集群部署等都是有很多基础理论作为支撑,才是真的了解,才能做出最有效的选择和支撑。

发表评论