记一次糟心的前端笔试(2)

  接下来讲说糟心的另外一题,第一题:css选择器有哪些?它们的优先级如何计算?css

  怎么说呢,这题目一看,考css选择器还不简单。立刻就要开始写,可刚要下笔的时候才发现,本身居然不知道要怎么去回答这个问题。平时本身写代码的时候根据本身的需求很天然就能够写出那些选择器,然而本身不清楚的是:这些选择器有没有分类?若是没有分类,要如何在这么窄的空间里写下那么多选择器?想到一个写一个?  如今就像是,每天吃着某些菜,真到要说出它们学名的时候,才发现本身对这些菜其实一点也不了解;就像是,游戏角色中每天都使用的技能,本身对它的效果了如指掌,却忽然想不起它的技能名是啥。 这算什么。。。html

  我我的可能有一个很大的缺点,总喜欢对事情有一个宏观的把握,对于那些没法得出自认为满意的答案,一般我都会持有否认态度。这让我想起曾经一个朋友问我一个问题,一个农民给一个地主打工七天,天天薪酬是一块金条的1/7,而地主只有那么一整块金条。若是只能切两次,要怎么切,才能保证地主天天能付给农民报酬。 我说不知道。他当时给个人答案是1,2,4分,而后跟农民换,就能实现天天给相应的薪酬给他。其实这也是我当时考虑的解法之一,可是我以为既然是日结,没法保证这个农民不会把第一天的工资花掉。并且这样子支付,这七天这个农民都不能使用它每日的酬劳。 这不是我理想中的答案,因此我否认了它,而后说不知道。而这道笔试题之因此答得很差,可能也是受我这种思惟影响。 后来我想通了,这确实是个人一大缺点。我应当是去作一名提供解决建议的人,而不是去作一名只知道否认建议的人。给出建议比否认难太多了。一样的,若是没法当即给出一个更好的建议,就应当正视别人的想法。css3

  好了,听我讲了那么多废话,下面进入正题。如今总算有充足的时间来组织语言了,为了肯定信息来源的可靠性,特地去看了官方文档。如下信息参考自 https://www.w3.org/TR/css3-selectors/   。有兴趣的人能够去看看。ide

  上面确实仍是有分类的,并且还挺详细。根据个人渣英语理解上面的内容,css选择器大概分为如下几类:spa

1. 类型选择器(type selectors)code

  话很少说,直接上代码:orm

p /*文档内的全部p元素*/

2. 通配选择器(universal selectors)htm

* /*文档内的全部元素*/

3. 属性选择器(attribute selectors)blog

[attr] /*全部带有属性attr的元素*/ [attr=val] /*全部属性attr等于val的元素*/ [attr~=val] /*全部属性attr中包含单词 "val" 的元素。为了更深刻理解或者避免本身理解有误,这里上官网原话:Represents an element with the att attribute whose value is a whitespace-separated list of words, one of which is exactly "val". If "val" contains whitespace, it will never represent anything (since the words are separated by spaces). Also if "val" is the empty string,it will never represent anything. 大概意思就是,会以空格对attr的值进行分割,而后与val进行对比匹配。若是val中含有空格或者为空字符串,这个选择器将匹配不到任何元素*/ [attr|=val] /*全部属性attr等于val或者attr的值以val开头(后面必须跟有"-")的元素 。这里仍是上官网原话:Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D).因此在w3School中对于这个选择器的描述是有问题的,还请注意*/ [attr^=val] /*全部属性attr中以val开头的元素*/ [attr$=val] /*全部属性attr中以val结尾的元素*/ [attr*=val] /*全部属性attr中含有val的元素*/

4. 类选择器(class selectors)游戏

div.test /*全部类名为test的div元素*/

5. ID选择器(ID selectors)

div#test /*全部id名为test的div元素*/

 6. 伪类选择器(pseudo classes)

a:visited /*全部被用户访问过一次的a元素*/ a:link /*全部尚未被用户访问过的a元素*/ a:hover a:active a:focuse /**/ :target :lang() /*元素的lang属性是用来标记该元素(及其子元素)所用语言的。注意假如只有html元素中有lang="en"属性的话,用:lang(en)匹配到的将是html元素下的全部元素,由于其子元素也是用英文写的。*/ :enabled :disabled :checked
div:nth-child() div:nth-last-child() img:nth-of-type() img:nth-last-of-type() div:first-child
/*the same as div:nth-child(1) represents an element that is the first child of some other element. 我以为理解这一句话很重要,我一开始就对这几个伪类有些误解。这里匹配的是 是父元素第一个子元素的全部div元素*/ :last-child /*全部是父元素最后一个子元素的元素*/ :first-of-type /*same as :nth-of-type(1)*/ :last-of-type /*same as :nth-last-of-type(1)*/ :only-child /*same as :first-child:last-child*/ :only-of-type /*same as :first-of-type:last-of-type*/

:empty /*全部没有子元素的元素*/

7. 伪元素选择器(pseudo elements)

p::first-line
p::first-letter
div::before
div::after

  事实上,根据原文的文档结构,我以为第7条是不在选择器之列的,但我没法肯定,因此仍是把它放进来了;我也不知道像 div>p 这样的“子代选择器”(child combinators)到底是单选择器(simple selector)的组合语法,仍是它自己就是一种类型的选择器,因此在最后面单独给出一个小节来介绍。

*. 关系选择器(combinators)

div p /*全部 祖先元素中有div元素的p元素。 由于css是从右往左解析的,因此这样解释比较符合个人逻辑*/ div>p /*全部父元素为div元素的p元素*/ div+p /*全部前一个同辈元素为div的p元素(不是最近,而是要挨着,隔着一个元素都不行)*/ h1~pre /*全部在同辈元素h1以后的pre元素*/

不知不觉已经这么多,这样子一分类果真清楚多了。如今想来,真的很遗憾错过这家公司。虽然自认为去笔试前仍是作了一些准备工做的,说到底本身水平仍是不够,才会这样碰壁吧。继续,下一个问题,这些选择器的优先级是怎么算的

  关于选择器的优先级问题,本身确实研究不深,只是粗略知道一些简单的,至于具体的细节还真没有去了解过。正好趁此机会好好啃一啃。还有啊,网上对于选择器优先级的计算方法真的是五花八门,贻害不浅。先不说别人,我本身就是深受其害的受害者之一,因此懂得以质疑的眼光看待事物是颇有必要的。固然我不能保证我这篇文章不害人,我尽可能,有什么错误的地方,欢迎指正。如下信息参考自 https://www.w3.org/TR/CSS22/cascade.html#cascade ,应该是目前最新定稿的css规范(2017.9.18),有兴趣的能够本身去看一看。下面我直接copy其中的核心片断,不想跳去看的能够直接看下面这些:

Calculating a selector's specificity

A selector's specificity is calculated as follows:

  • count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
  • count the number of ID attributes in the selector (= b)
  • count the number of other attributes and pseudo-classes in the selector (= c)
  • count the number of element names and pseudo-elements in the selector (= d)

The specificity is based only on the form of the selector. In particular, a selector of the form "[id=p33]" is counted as an attribute selector (a=0, b=0, c=1, d=0), even if the id attribute is defined as an "ID" in the source document's DTD.

Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.

 文中还给出了一些例子,结合例子相信能够很快明白这种规则:

 /* Some examples: */ * {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ li {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul li {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul ol+li {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ ul ol li.red {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ li.red.level {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ #x34y {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ style="" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

  大概意思就是,有a,b,c,d 这样四个计数器。这四个计数器分别按照下面的规则计数:

  1. 当样式声明来自内联样式时,a=1;
  2. 计算选择器中有多少个id选择器,每出现一个,b+=1;
  3. 计算选择器中有多少个其它属性的选择器和伪类选择器,每出现一个,c+=1(注意class也属于这里所说的“其它属性的选择器”);
  4. 计算选择器中有多少个元素名或者伪元素,每出现一个,d+=1(注意 * 并不在元素名之列,因此上面第一个例子才会全为0);

  像上面这样计算以后,把 a,b,c,d 按一个规则计算其特征值(具体怎样我不清楚,我这里理解为按顺序拼成一个数字字符串再将其拿来比较),值较大选择器的样式声明会覆盖掉较小的(more specific selectors will override more general ones.)

 

  好了,这样这道题就终于告一段落。但愿这样能帮到本身,更但愿能帮到有须要的人。

相关文章
相关标签/搜索