小tip: CSS后代选择器可能的错误认识

这篇文章发布于 2012年03月19日,星期一,17:15,归类于 CSS相关。 阅读 79922 次, 今日 2 次 21 条评论

 

一、关于类选择器的一个问题

假设有下面一个面试题,CSS代码如下:

.red { color: red; }
.green { color: green; }

HTML如下:

<div class="red"><div class="green"><p>1. 颜色是?</p></div></div>
<div class="green"><div class="red"><p>2. 颜色是?</p></div></div>

问:第一行和第二行文字颜色分别是?

这个例子很简单,我估计基本上都能回答正确:DOM越深的类名权重越高,因此,第一行文字红色,第二行文字绿色第一行文字绿色,第二行文字红色!因此,上一题答案为C.

您可以狠狠地点击这里:CSS类名选择器顺序和层级的权重

类选择器顺序与深度权重测试截图 张鑫旭-鑫空间-鑫生活

二、稍作修改:类选择器→后代选择器

再来一个题目,如果我们把上例的类选择器改成后代选择器会如何呢?

.red p { color: red; }
.green p { color: green; }

HTML维持不变:

<div class="red"><div class="green"><p>1. 颜色是?</p></div></div>
<div class="green"><div class="red"><p>2. 颜色是?</p></div></div>

问:第一行和第二行文字颜色分别是?

经验会转化为具象化的认识以帮助我们记忆,然而,这又容易形成固定思维,对一些类似情形造成错误认识。

如果我们按照一开始类选择器的例子来隐射这个类似的例子,您可能就会得到错误的答案——这个例子正确选项不是C.

那正确的选项应该是?

您可以狠狠地点击这里:CSS后代选择器顺序和层级的权重demo

您可以在各个浏览器下看到,第一行和第二行的文字都是绿色的,如下截图所示:
CSS后代选择器顺序和层级的权重demo效果截图 张鑫旭-鑫空间-鑫生活

也就是说正确选项应该是A.

为何?

貌似这种后代选择器情形,祖先选择器对应DOM无论多深多浅都是同一级别的,而最终起作用的是选择器声明在CSS样式中的顺序,即优先显示后面的CSS声明。

本例中,.green p { color: green; }.red p { color: red; }的后面显示,因此,两行文字都是绿色的。要是我们改成下面:

.green p { color: green; }     /* 我在上,酱油命 */
.red p { color: red; }     /* 我在下,显示我 */

那么,两行文字就变身为红色了。

如果您目前手头上的是现代浏览器,可以点击这里,编辑下CSS代码顺序(FireFox下剪切粘贴有些问题,手动输入),会看到右侧文字果不其然红色了~~

三、再留个问题

改下CSS代码:

:not(.green)  p { color: red; }
.green p { color: green; }

HTML代码维持不变:

<div class="red"><div class="green"><p>1. 颜色是?</p></div></div>
<div class="green"><div class="red"><p>2. 颜色是?</p></div></div>

问:第一行和第二行文字颜色分别是?

您可以通过评论的形式写下您认为的答案~~

(本篇完)

分享到:


发表评论(目前21 条评论)

  1. Evelyn说道:

    请教大神个问题:
    如今css预处理器sass,less中的选择器支持嵌套形式书写,那么到底是嵌套层级越多越好,还是不要过多为好?

  2. 张家小曼说道:

    刚刚试了一下,哪个写在后面就显示哪个颜色
    原因嘛,应该是伪类选择器和类选择器权重一样

  3. 一路说道:

    1、如果子元素没有指定样式,则直接继承父容器的样式——(赞同5楼赵弟栋所说的)
    2、如果子元素指定样式,则对css进行“位”的权重对比,如果权重一样,则进行解析先后顺序对比;
    3、:not(.green)(伪选择器) 的“位”权重与.green是一样的,所以最后进行解析顺序先后对比了
    不知道理解的对否~请指教~~~

  4. DS说道:

    额,纠结了

  5. zjx说道:

    看到这里,有点困惑。
    各种引擎(CSS引擎、JS引擎)是不是按照W3C的规范自行设计渲染、解释程序?
    但貌似他们并非都遵循规范,要不也不可能有诸多差异?
    既然如此渲染机制是不是都不一样?
    渲染机制不同我们怎么可以按照固有的套路理解某种样式规则?
    要是真有考官出这种东西,我只能说:您拿台笔记本儿来试试吧,我真不懂。

  6. 美格印象说道:

    都是绿哈

  7. 陈清华说道:

    都是绿色的,主要看样式谁在谁的后面。对p标签来讲至上而下读取。

  8. 沈大云说道:

    是绿红吧 伪类选择器的权重跟class应该是一样重的吧

  9. 王柯说道:

    都是红色

  10. vbyzc说道:

    泥玛的这个太难了。

  11. cyin15288说道:

    两行文字都是绿色!

  12. riophae说道:

    都是绿色..

  13. 葵中剑说道:

    猜想这篇的灵感来自于 Eric 的 Negative Proximity

  14. 赵弟栋说道:

    第一个例子p的样式未指定 样式继承于父级元素div 他的父级元素是指定了的
    第二个例子p的样式指定了 两行html和两个css规则都是匹配的 css权重相同的情况下后出现的起作用
    第三个 第一个css规则匹配的是类名不是green的元素的后代p 例子中p都是green的后代

  15. chjund说道:

    这个上面讲的很详细,可以参考下:http://w3help.org/zh-cn/kb/005/

  16. 司晨说道:

    两行都是绿的,我觉得:not(.green) p { color: red; }可以直接理解成:p { color: red; },所以P应该是一个全局定义,而.green p是后代选择器,这样就出现了两行都是绿色文字!

  17. akasuna说道:

    因此,第一行文字红色,第二行文字绿色!

    这算是笔误吗?