54

背景

想想自己为什么要写这个,难道不是因为这篇《50道CSS基础面试题(附答案)》文章最近被转载的多,比较多而凑热闹蹭热点?显然,肯定是因为这样我才打算写的。而且还有就是,我的公众号也很久没有更新了,微信说长期不更新会关掉公众号的,怕……

对于 CSS 方面的工作以及跟 CSS 有关的东西,我已经有一些时间没有接触了,自从离开上家公司到了目前所在的公司,处理小程序方面的事情以后,有关 CSS 的内容我都只是大概瞄一下,没去过多思考。看了这篇文章后,发觉自己再不思考,真的是要废了。

根据这篇文章的题目以及答案,再结合自己的一些经历以及想法,稍微理一理,不对的请喷,毕竟我所考虑的点还是很有限的。

正文部分

问题直接复制过来,那篇文章的答案引用部分,在引用的答案下面附带我个人的一些看法。

1、介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的?

标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin
低版本IE盒子模型:宽度=内容宽度(content+border+padding)+ margin

首先抛开所谓的标准不说,因为这个标准是 W3C 那边制定后跟各大厂商沟通去做统一的。在这个答案中,如果按照严格来说,首先会问基本怎么计算,就像上面这个答案,不过需要注意一下顺序。

  • 标准盒模型的宽度 = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right,这样写可能会显得比较长,按照上面的答案来说的话,或许 width + padding + border + margin 就好了,附带说一下除了 width 以外是有左右两边的。
  • 怪异模式的盒模型宽度 = (width + padding + border) + margin 整体来说跟标准盒模型是相类似的,主要是 width + padding + border 这三者算在一起了。

标准的盒模型是基于 doctype 正确书写的情况下,并且是高于 IE6 的浏览器才会有的,如果是低于 IE6 的浏览器,就算是正确的 doctype 的书写情况下也是进入怪异模式的;在 IE 浏览器中如果写错了 doctype 或者是 doctype 之前有其他字符,那么可能就让 IE 进入怪异模式,从而导致浏览器解析元素盒模型出现问题,比如:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

这种情况下就会让低版本的 IE 进入怪异模式,导致的可能不仅仅只是盒模型计算问题,还有可能是其他的一些情况,早年之前有不少公司直接利用这种方式对低版本和高版本的浏览器做样式上的区别操作对待。

附带一条 URL:DOCTYPE 与浏览器模式分析 http://www.w3help.org/zh-cn/casestudies/002 供参考学习。

拓展问题

  • 根据以上可以再问一下,当 width: 0; padding: 0 100px; border: 10px solid red; margin: 0 50px; 的时候,这个盒子里有内容跟没内容,在标准盒模型和怪异模式的盒模型中有什么区别?
  • 根据 box-sizng 改变的盒模型的计算方式,跟这个标准盒模型以及怪异模式的盒模型的计算方式有什么区别?

2、box-sizing属性?

用来控制元素的盒子模型的解析模式,默认为content-box
context-box:W3C的标准盒子模型,设置元素的 height/width 属性指的是content部分的高/宽
border-box:IE传统盒子模型。设置元素的height/width属性指的是border + padding + content部分的高/宽

box-sizing 主要是用来计算一个元素中的宽度和高度的总和的值,而具体的计算方式将会根据 box-sizing 的属性值来决定,共有两个属性值:content-boxborder-box

当我们了解一个元素的盒模型之后,其实对于这个的理解就简单很多了,比如我们可以这样理解,然后延伸来说明:

  • content-box:一个标准模式下的盒模型的计算方式
  • border-box:一个怪异模式下的盒模型的计算方式

附带说明

目前来说,低版本的 IE 已经逐渐淡出了大家的视线了,所以,怪异模式和标准模式已经不再有太多人去关注,而且 doctype 也基本上会在各种编辑器中自动添加为 <!doctype html> 了,但这不代表我们不会在意盒模型的计算,只是不在意怪异模式和标准模式的浏览器解析方式。

在现在移动端中,很多时候为了便于盒子的计算,我们会使用 box-sizing: border-box; 来操作,把 paddingborder 的值计算在一个整体的宽度内,当然了,如果有 margin 的话,还是会额外去考虑的。

3、CSS选择器有哪些?哪些属性可以继承?

注:省略部分原文的答案

CSS选择符:id选择器(#myid)、类选择器(.myclassname)、标签选择器(div, h1, p)、相邻选择器(h1 + p)、子选择器(ul > li)、后代选择器(li a)、通配符选择器(*)、属性选择器(a[rel="external"])、伪类选择器(a:hover, li:nth-child)...

这个问题应该来说是两个问题,分别是选择器和属性的问题,或许可能是考核一个人对 CSS 选择器的了解程序以及对 CSS 属性的掌握程度吧。对于这个问题,个人觉得并不会要求把所有的都回答出来,要真都回答出来了,那就可能是背课文了。

这是早之前我整理的一份有关选择符的图,大家可以感受一下。

CSS选择符

这图已经好久没有更新了,可能有一些新的草案没增加,不过无所谓拉,这么多东西,目前我们能使用到也就那么几个,也就是原文中所提供的答案。

那么对于哪些属性可以继承这个问题,这又是一个很大的话题了,可能需要对 CSS 的所有属性都进行一次归整才会有一个相对比较完整的结果。这里我就提一个在原文答案中提到的可继承属性中的 font-size 这个属性。

font-size 的确是可继承的,但并不是所有的 HTML 元素都会在 body 定义了 font-size 后,把这个文字大小作用在自身标签上,比如 h1h2 等一系列标题元素的标签,还有 input 以及 button 之类的控件元素。

  • h1 系列的标题元素标签在浏览器默认样式中是使用了 em 作为单位的,会根据父级的 font-size 而改变(讲真,这到底算不算继承呢,?)
  • input 系列的控件元素,是直接有浏览器默认文字大小,并且是 px 作为单位的(这个又是因为已经被定义过了属性,但实际上应该算是继承了吧,只是权重值不够高,无法覆盖了 bodyfont-size

在这个问题中,提到了一个优先级:

优先级(就近原则):!important > [ id > class > tag ]

不知道是不是跟下一个问题搞混了,但是这里应该是少了一个 style 属性吧。

!important > style 属性 > id > class > tag

并且我没看懂为什么原文的答案这里有一个中括号,是想说代表这个是可选的呢,还是怎么样呢。

4、CSS优先级算法如何计算?

元素选择符: 1
class选择符: 10
id选择符:100
元素标签:1000

这个我觉得吧,并没有任何问题,不过在面试的时候,提到了这个之后,可能会被问其他相关的问题。

选择符优先级的拓展问题:

  • 有 11 个元素选择符的优先级跟 1 个 class 选择符优先级哪个高呢?
  • 如果有 256 个 class 选择符,比如 .class001.......class256 {} 那么这个时候是否会大于 一个 id 选择符呢?
  1. !important声明的样式优先级最高,如果冲突再进行计算。
  2. 如果优先级相同,则选择最后出现的样式。
  3. 继承得到的样式的优先级最低。

这三点概括的并不是十分全面吧,在面试的过程中,如果面试官提到了有关选择符优先级的问题,那么可能会给几个 demo 来让你想一下哪个文字是什么颜色之类的,最后再问原理。

众所周知,!important 的优先级是最高,那么如果可能会延伸的问题会有:<div style="width: 100px !important;"></div> 这里的这个 width 样式如何去覆盖。

5、CSS3新增伪类有那些?

p:first-of-type 选择属于其父元素的首个元素
p:last-of-type 选择属于其父元素的最后元素
p:only-of-type 选择属于其父元素唯一的元素
p:only-child 选择属于其父元素的唯一子元素
p:nth-child(2) 选择属于其父元素的第二个子元素
:enabled :disabled 表单控件的禁用状态。
:checked 单选框或复选框被选中。

这个可以说的内容其实也挺多的,还是可以参考之前那张图,具体的哪些是伪元素选择符哪些是伪类选择符,根据图中的所列的情况可以一目了然看到。

CSS选择符

拓展出来的问题;

  • 隔行换色的实现方式;
  • :nth-child(an+b) 可以做的 XXX 事情,我们应该怎么实现(具体可能会根据不同面试官给出不同的题目而定);
  • ::after:after 一个冒号和两个冒号有什么区别;

诸如此类的问题很多,在 CSS3 中对于选择符可以玩的情况太多了,就看怎么去想这个问题,但只要掌握了原理,无论面试官怎么去改变,最终原理是差不多的,万变不离其宗嘛,对吧。

6、如何居中div?如何居中一个浮动元素?如何让绝对定位的div居中?

看到这个问题,我能想到的是,果然水平垂直居中的题目会出现啊。

如何居中div?

一个 div 元素的居中,这里并没有提到说这个 div 标签使用的是什么类型的 display 值,那么对于我们来说可以拓展的方式就非常非常多了。

在原文答案中提到了:

border: 1px solid red;
margin: 0 auto; 
height: 50px;
width: 80px;

这里的关键点是 widthmargin,当一个 display: block 的块级元素有了宽度之后,就可以使用 margin: 0 auto; 的方式让其水平居中。

那么这里提到的是块级元素,那么我们可以假设一下,如果我们把 display: block; 换成了:

  • display: inline;
  • display: inline-block;
  • display: table-cell;

在不同的 display 属性存在的时候,我们还是用 margin: 0 auto; 的方式来居中吗?

接着就可以通过这个问题延伸出第二个问题:如何居中一个浮动元素

如何居中一个浮动元素

这里提到的一个点是,居中一个浮动元素,并没有说是水平居中还是垂直居中,或者是两者并存,也并没有说这个浮动元素是否有子元素或者是父元素,那么可操作的方式又有很多了。

如果只是水平居中的话,前提是浮动了,当设置了 float 之后,使用 margin: 0 auto; 方式居中是不可能的了,如果只有一个元素的话,那就只能通过原文答案中提到的通过 position: absolutemargin 的结合来处理,当然,这里的 margin 可以换成 transform,当如果换成 transform 的话,可能又会被面试官提到另外一个问题了——性能的问题。

不过呢,仅仅只是水平居中的一个浮动元素的话,如果存在父级元素,可以考虑使用“float: center;”,嗯,这里是加引号的,并不是真的有这个属性值。

.float_center {
  float: right;

  position: relative;
  left: -50%; /* or right 50% */
  text-align: left;
}
.float_center > .child {
  position: relative;
  left: 50%;
}

部分代码是这样的,具体的可以看 https://codepen.io/alexandred... 这里,这个方法在几年前还是用的比较多的,尤其是在水平居中的一个分页数控件。

反正不管怎么样,这个是带有浮动属性的元素,进行了居中的操作了。如果有垂直居中的话,就按照原文答案的方式来操作就可以了,毕竟浮动了之后 display 的属性值是 block,不会改变的。

如何让绝对定位的div居中?

这个问题我就没看明白跟上面那个浮动元素中使用了绝对定位方式居中有什么区别了。无非就是 margin 或者 transform 的方式来操作。

额外想法

对于水平垂直居中的方法,网络上有很多很多的文章了,不同的方式会带来不同的效果情况。在日常使用的过程中,我们是会根据页面的实际需求情况而采用不同的居中方式,原理都差不多,只是实现的方式不同。对于这个题目,总而言之一句话就是:如何做好一个元素的居中

-----------============ 我是分割线 ============-----------

小结

小小的结束一下,嗯,不是小小的总结,是小小的结束,写这些东西真累,偷懒花一点时间写一下,回头一看,原来才写 7 点,后面还有那么多,先这样吧,后面看情况再说了。

而且说实在的,目前这个写的的内容其实也很笼统,并不全面。

你可能感兴趣的

toBeTheLight · 2018年03月20日

贴个水平垂直居中的库。水平垂直居中,这是一道面试必考题

回复

范捷琦Jackie · 2018年03月21日

写得很好,解决了很多疑惑,谢谢。

回复

刘宁Leo · 2018年06月14日

感谢对我的文章的关注,当初写这篇文章只是个人的整理分享给大家,没想到被这么多人看到。谢谢~

回复

载入中...