CSS学习笔记:选择器

要将CSS样式应用于特定的HTML元素,需要想办法找到这个元素。在CSS中,执行这一任务的样式规则成为样式选择器(selector)。本文将介绍CSS常用选择器、高级选择器,层叠与特殊性计算,以及如何组织和维护样式表等内容。

1. CSS选择器

1.1 常用选择器

  • 类型(元素)选择器:寻找特定类型的元素,如段落或标题元素。例如:p {color: black;}
  • ID和类选择器:寻找具有指定ID或类名的元素,前者以井号#为前缀,后者以点号.为前缀。例如:#intro {front-weight: bold;}.date-posted {color: #ccc;}
  • 后代选择器:寻找特定元素的后代,由两个选择器之间的空格表示。结合使用类、后代、类型选择器可以减少对ID或类选择器的过度依赖。例如:#main-content h2 {font-size: 1.8em;}
  • 通用选择器:匹配所有可用元素,由星号*表示。比较少用,通常用于重置全局样式。例如:* {padding: 0; margin: 0;}(删除浏览器默认的内外边距)

1.2 伪类选择器

  • 链接伪类:可以改变超链接默认及访问后的样式,只能应用于a标签。例如:a:link {color: blue;}a:visited {text-decoration: none;}
  • 动态伪类::hover:activefocus分别向鼠标悬停元素、激活的元素和拥有键盘输入焦点的元素提供样式。例如:.btn:hover {color: blue;}

1.3 高级选择器

  • 子选择器:选择一个元素的所有孩子,由两个选择器之间>分隔。后代选择器选择的是所有后代,子选择器选择的是直接后代。例如:#nav>li {padding-left: 20px;}
  • 属性选择器:根据某个属性是否存在或属性的值来寻找元素。例如:input[type=text] {font-size: 1.6em;}
  • 毗邻元素选择器:选择一个紧跟在元素之后的第一个同胞元素,由两个选择器之间+分隔。例如:h2+p {font-weight: bold;}

还有很多其他的选择器在此不赘述,详细可以参考W3School CSS选择器

2. 层叠与特殊性计算

CSS的选择器有这么多,要寻找同一元素可能有两个或更多的规则。CSS通过层叠(cascade)的过程来处理这种冲突。层叠给每种规则分配一个特殊性值,更特殊的选择器规则将优先被使用。如果两个规则的特殊性相同,则后定义的规则更优先。

特殊性的计算采用的是比10更高的未指定的基数,这能确保非常特殊的选择器(如ID选择器)不会被大量一般选择器(如类选择器)所超越。但是为了简化,如果选择器数量少于10个,可以以10为基数计算特殊性,这在日常使用中已经够用了。选择器的特殊性分4个成份等级a、b、c、d:

  1. 如果样式是行内样式(即写在HTML代码中,如<div style="display:none;"></div>),则a等于1
  2. b等于ID选择器的总数
  3. c等于类、伪类、属性选择器的数量
  4. d等于元素(如HTML标签)和伪元素选择器的数量

下表给出了一些特殊性的示例以加深理解。

CSS特殊性计算示例

通过熟记以上4条规则,可以很快地计算出复杂CSS的特殊性。例如#content div#main-content h2的特殊性是0,2,0,2=202,body #content div[id="main-content"] h2的特殊性是0,1,1,3=113。如果遇到了似乎没有起作用的CSS规则,很可能是出现了特殊性冲突,此时你可能需要重构CSS代码。

3. 关于继承

人们常常将CSS中的继承和层叠混为一谈,实际上这两个概念很不一样。应用样式的元素后代会继承样式的某些属性,如颜色和字号。比如在body上设置文本颜色为黑色,则所有元素会显示黑色的文本。当然有时可能页面上一些标题没有采用继承字号,实际上是浏览器的默认样式表设置了标题的字号,直接应用于元素的样式总会覆盖继承来的样式,因为继承而来的样式特殊性为空

4. 组织和维护样式表

站点越大、越复杂,CSS就越难管理。正如使用模板引擎可以将HTML拆解成多个文件,使用模块化规范可以将Javascript划分为多个模块一样,CSS也可以从一个样式表中通过@import url('my_css.css');这样的语句来导入其他样式表,从而HTML中只需要链接一个主样式表文件。这样虽然也可以让CSS“模块化”,但是使用import语句会使加载更慢,多个文件会导致发起更多的HTTP请求,从而影响页面的加载速度。所以还是推荐在一个页面使用尽量少的CSS文件。

如果CSS文件非常长,那么寻找特定的样式就会很困难。一种改进方法对单个CSS文件分块进行必要的注释,如使用/* @group typography */这样带有@group标记的注释,并以/* @group end */作为结束。此外为了便于维护,最好把样式表划分为几大块,通常是把最一般的规则放在最前面,接着可能是全局重置央视,然后是链接、标题和其他元素。最后是一些特殊性样式,最后整个样式表可能像以下的结构:

  • 一般性样式
    • 主体样式
    • reset样式
    • 链接、标题、其他元素
  • 辅助样式
    • 表单
    • 通知和错误
    • 按钮、其他
  • 页面结构
    • 标题、页脚、导航
    • 布局
    • 其他页面结构元素
  • 页面组件
  • 覆盖

当站点变得特别复杂时,往往一个页面一个CSS的方式会导致这个CSS文件特别庞大(几千行甚至上万行),当有多个开发人员同时编辑这个CSS文件时,经常会产生各种冲突而降低生产力。所幸现在有一种技术方案——CSS预处理器,可以完美解决以上各种问题。其中LESSSass是用得最多的两款。具体什么是CSS预处理器以及如何使用请自行搜索。CSS预处理器的出现无疑大大提高了前端开发人员的生产效率,它可以让开发人员编辑多个文件,最后合并成一个CSS文件发布,既实现“模块化”,提高可维护性,又满足性能要求。同时CSS预处理器还提供许多极其方便的语法,大大简化样式文件的编写。

参考资料:精通CSS:高级Web标准解决方案(第2版)第二章

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器