CSS优先级特性

一般情况下,css遵循着后定义优先,越详细具体越优先的原则。不过在某些情况下,你却得不到你想要的样式。我在启用CodeColorer插件的时候,就被这一点烦恼了很久。

举个简单的例子,有以下html文本:

<ul id="summer-drinks">
  <li class="favorite">Whiskey and Ginger Ale </li>
  <li>Wheat Beer </li>
  <li>Mint Julip </li>
</ul>

然后定义了以下的CSS样式:

#summer-drinks li {
   font-weight: normal;
   font-size: 12px;
   color: black;
}
.favorite {
  color: red;
  font-weight: bold;
}

你期望带有类 favorite 的 `Whiskey and Ginger Ale` 能以红色粗体呈现,可结果却跟别的字体别无二样。

该如何让定义的样式起作用呢?很容易想到的就是更改一下后者的选择符,将其改为#summer-drinks .favorite,你会发现,啊,起作用了。如果不想更改选择符,可以使用!important这个金手指,即使用以下样式:

.favorite {
  color: red !important;
  font-weight: bold !important;
}

这里的问题是解决了,可是为什么?按理说,.favorite定义更具体更靠后,应该起作用才对,可是为什么?

这就需要CSS的优先级特性来解释了。关于这个,可以看一幅很直观的图。

css specifity base
css specifity base

从上图中可以看到采用style定义的内联CSS样式优先级最高,然后是ID,类,最后才是html元素。
然后我们可以根据这图来判断给定的样式的优先值为如何的了。方法很简单,找出各个优先级的个数,然后按照上图的位置填下去就可以了。至于优先级的比较,从优先级由高到低,大者优先,相等则比较下一个优先级,依此下去。

下面是一些例子

css specifity 1
css specifity 1
css specifity 2
css specifity 2
css specifity 3
css specifity 3
css specifity 4
css specifity 4
css specifity 5
css specifity 5

Notice

关于!important

这玩意是个金手指,优先级最高,有它时优先级可以看作是1,0,0,0,0。

Pseudo-elements (e.g. ::first-line) get 0,0,0,1 unlike their psuedo-class brethren which get 0,0,1,0

The pseudo-class :not() adds no specificity by itself, only what’s inside it’s parentheses.

我看过的国内的几篇关于CSS优先级的文章,其中原理都是这样的,不过常用的说法是ID的权值是100,class的是10,element的是1,统计好个数后,然后进行算术相加,最后比较大小。
严格来说,这种说法是错的,因为其实那个优先级的表示并不是十进制的,只是表示在前的优先而已。只是,我们为了读起来和表达起来容易,常当作十进制来表示了。

一个简单的反例,定义以下样式(11个类,1个ID)

.a.b.c.d.e.f.g.h.i.j.k { color:red; }
#myel {color:blue;}

和html

<span class="a b c d e f g h i j k" id="myel">would still be blue.</span> 

可以看到,如果采用10进制的话,11个class的权值是110,而1个ID只是100,应该字体是红色,但结果却是蓝色。

当然,这种极端的情况几乎不会出现,但应该对优先级有着正确的理解。

有了以上资料,就不难解决此文开始的问题了。

参考

92条评论

      1. @流年, 嘿嘿 我表示我那的CSS需要修改了 有好多地方都是直接用的.XX 而不是#ID .XX

        1. @mice, 没冲突的时候.XX就够了,加个ID进去反而多余

          1. @流年, 😆 加ID 看CSS明显点嘛 我也懒得折腾 嘿嘿 除非出错了

    1. @zwwooooo, 好像多余的选择器会导致解析时间的增加的吧

      1. @流年, 这个就不知道鸟,我不会在意那丁点儿的速度,而且高手们很多都是这样用的。

    1. @vastar, 嗯,咱们还需要继续学习啊!!

    1. @Leyond, 呵呵,莫怕,我也是菜鸟,硬着头皮啃了

        1. @流年, 这孩子在山寨苹果 首推第一款主题 我再过去顶2下

      1. @流年, 所噶 看得有点云云,里面的字体重新自定义会舒服很多,再来一个 你一天也太能整理图片了吧, 换我这几张图片就要弄近半个小时的说

        1. @7cbt, 字体?说我博客的字体还是图片的字体?图片都是原版的,没改动,所以……

          1. @流年, 🙄 原版… 晕… 我还以为是你画的 我想写英文注释会很累啊

              1. @流年, 粗心大意了 那一块和TAG 以及 插件之类(上一篇,下一篇)搞混淆了。

                1. @7cbt, 汗!我专门加了点背景颜色来区分标签跟正文,原来的恩男区分

                2. @7cbt, 你觉得现在浮动到右边如何?(需要刷新一下更新缓存)

  1. CSS渲染的优先级问题是一个比较复杂的东西,我博客之前翻译过一篇文章,算是写得比较深入了

    1. @dudo, 找到了,跟我的大同小异。嗯,我没提用户自定义样式。
      话说,你的网站地图归档不全啊,翻了一下没找到,直接用google搜了

    2. @dudo, 继续翻了一下,觉得刚才看的那篇优先级的应该不是你这里所指的,你指的是“细说CSS样式选择符”系列吧,我慢慢看看

  2. 这图片真漂亮。。要是所有的知识都这样呈现,人人都爱学了。。。 😆

    1. @QiQiBoY, 所以很多人看计算机的书一般都挑外国的

      1. @流年, 国外的好, 我就喜欢看国外的技术书,国内的没国外有质量。 很简单软件 和 代码都是人家看法的 思考也很正确,国内的就很死板。

        1. @7cbt, 嗯,国内的说参考说抄袭也好,关键是有时候代码都没经过测试。至于排版那些,基本是绝望的,前篇一律

          1. @流年, 呵呵 流年才在CDC看到你了,其实我相信你也在思考一个体验的问题,这里我就发现 你这一块排列过于紧凑导致的错觉。 所以是否需要修改 你思量一下

            1. @7cbt, 你是说正文跟分类、标签那里吗?嗯,目前加了点背景,不过依然不是很明显,考虑中

              1. @流年, 3种做法

                1. TAG 不要加背景
                2. TAG 位置放到相关文章下面,并TAG是做给搜索引擎看,用户很少用到TAG,把TAG之前的位置留空白,将正文和“相关文章,TAG” 有一个间隔分开
                3. TAG加到文章发表日期下方

                1. @7cbt, 原本是考虑到Tag没背景跟正文太相似了才加上去的;另两个做法,我看看那

  3. CSS啊,去年夏天给公司写很多。。。
    噢对了,现在是凌晨一点四十六,我起床嘘嘘,顺便偷菜,顺便来你这里逛逛。。。

    1. @Kupid, 高手以后不懂的就多多指教了 😉

  4. 看了之后,我表示我更晕了……嘛,无所谓,CSS怎么调能显示出我要的效果就怎么调了,我就喜欢折腾 😉

    1. @人好哇!, 可是有时候很郁闷,因为就是调不出,了解一下还是挺好的

    1. @煮茶老头, 这些大家都需要慢慢学习啊

  5. 不懂这个,不过我觉得人家设计的好漂亮呀,要是自己懂就好了,整天捣鼓博客
    我也更新了,有空过去看看给点意见哦

  6. 不好意思,来你这里测试一下网易是否屏蔽了google套件,如果我收到你的回复,那就没有问题! 🙂

      1. @流年, 我把邮局换成了google,但是网易新浪还是无法收到邮件回复,只有gmail收的到囧,你的回复收到了,难道网易把偶的域名还是ip给拉黑了。。

        1. @BoKeam, 很直观是对的,只是~~这玩意不是我画出来的

    1. @雅丹, 后原则?指的是后者优先吗?

  7. 我前段时间做了个东西,就是在优先级上出了点问题…… 😀

    1. @有点蓝, 模版是别人的,嗯,这个很出名

    2. @有点蓝, 弱弱地说一句,其实我这个博客不是技术型的,我的博客主题是没主题

  8. 上面这段的解决办法复杂了
    #summer-drinks li {
    font-weight: normal;
    font-size: 12px;
    color: black;
    }
    .favorite {
    color: red;
    font-weight: bold;
    }
    这里不用声明权重,把这段#summer-drinks li 的 li 代码去掉就会实现想要的效果,有时候不一定要声明权重,降低权重也是个办法。

评论已关闭。