Skip to content

精通 CSS - 高级 Web 标准解决方案 2. 为样式找到应用目标

🏷️ 《精通 CSS - 高级 Web 标准解决方案》

要想使用 CSS 样式应用于特定的 HTML 元素,需要想办法找到这个元素。在 CSS 中,执行这一任务的样式规则部分称为 选择器(selector)

常用选择器

  1. 类型选择器(也称 元素选择器 或 简单选择器)

    寻找特定类型的元素;

    css
    p { color: black; }
    h1 { font-weight: bold; }
  2. 后代选择器

    寻找特定元素或元素组的后代;

    css
    blockquote p { padding-left: 2em; }
  3. ID 选择器

    寻找具有指定 ID 的元素;

    css
    #intro { font-weight: bold; }
    html
    <p id="intro">Happy Birthday Andy</p>
  4. 类选择器

    css
    .date-posted { color: #ccc; }
    html
    <p class="date-posted">24/3/2009</p>
  5. 伪类

    根据文档结构之外的其他条件对元素应用样式;

    css
    /* makes all unvisited links blue */
    a:link { color: blud; }
    
    /* makes all visited links green */
    a:visited { color: green; }
    
    /* makes links red when hovered or activated.
    focus is added for keyborad support */
    a:hover, a:focus, a:active { color: red; }
    
    /* makes table rows red when hovered over */
    tr:hover { backgrounp-color: red; }
    
    /* makes input elements yellow when focus is applied */
    input:focus { background-color: yellow; }

    :link:visited 称为 链接伪类,只能用于锚元素。
    :hover:active:focus 称为 动态伪类,理论上可以用于任何元素。

    可以把伪类连接在一起,创建更复杂的行为。

    css
    /* makes all visited linkes olive on hover */
    a:visited:hover { color: olive; }
  6. 通用选择器

    作用就像通配符,匹配所有可用元素;
    通用选择器一般用来对页面上的所有元素应用样式;
    与其他选择器结合使用时,用来对某个元素的所有后代应用样式;

    css
    * {
        padding: 0;
        margin: 0;
    }
  7. 子选择器

    选择元素的直接后代,即 子元素
    IE7 和更高版本都支持子选择器;

    css
    #nav>li {
        background: url(folder.png) no-repeat left top;
        padding-left: 20px;
    }
  8. 相邻同胞选择器

    用于定位同一个父元素下某个元素之后的元素。

    css
    h2 + p {
        font-size: 1.4em;
        font-weight: bold;
        color: #777;
    }
  9. 属性选择器

    属性选择器可以根据某个属性是否存在或属性的值来寻找元素;

    css
    /* 选择具有 title 属性的 acronym 元素 */
    acronym[title] {
        border-bottom: 1px dotted #999;
    }
    /* 鼠标悬停时指针改为问号 */
    acronym[title]:hover, acronym[title]:focus {
        cursor: help;
    }
    /* 选择 rel 属性为 nofollow 的链接 */
    a[rel="nofollow"] {
        background: url(nofollow.gif) no-repeat right center;
        padding-right: 20px;
    }
    /* 选择 rel 属性值之一为 co-worker 的链接 */
    a[rel~="co-workder"] {
        background: url(co-worker.gif) no-repeat left center;
    }
  10. 结合使用选择器

    css
    #main-content h2 { font-size: 1.8em; }
    #secondary-content h2 { font-size: 1.2em; }
    html
    <div id="main-content">
        <h2>Articles</h2>
        ...
    </div>
    <div id="secondary-content">
        <h2>Latest news</h2>
        ...
    </div>

层叠

要寻找同一个元素可能有两个或多个规则。CSS 通过一个成为 层叠 的过程处理这种冲突。层叠给每个规则分配一个重要度。

  • 重要度次序

    1. 标有 !important 的用户样式
    2. 标有 !important 的作者样式
    3. 作者样式
    4. 用户样式
    5. 浏览器/用户代理应用的样式

然后根据 选择器的特殊性 决定规则的次序。
具有更特殊选择器的规则优先于具有一般选择器的规则。
如果两个规则的特殊性相同,那么后定义的规则优先。

  • 选择器的特殊性

    为了计算规则的特殊性,给每个选择器都分配了一个数值。然后将规则的每个选择器的值加在一起,计算出规则的特殊性。

    选择器的特殊性分成 4 个成分等级: abcd

    • 如果样式是行内样式,那么 a=1
    • b 等于 ID 选择器的总和
    • c 等于类、伪类和属性选择器的总和
    • d 等于类型选择器和伪元素选择器的数量

    每一级的数值为 该成分等级的值(即 abcd 的值)乘以 基数n 次方;
    其中 基数 不是 10,而是一个更高的未指定的数;
    n当前成分等级 - 1,即 计算 a 成分等级时为 3,计算 d 成分等级时为 0;

    下面是一个假设基数为 10 时的选择器及其特殊性。

选择器特殊性以 10 为基数的特殊性
style=""1,0,0,01000
#wrapper #content {}0,2,0,0200
#content .datePosted {}0,1,1,0110
div#content {}0,1,0,1101
#content {}0,1,0,0100
p.comment .dateposted {}0,0,2,121
p.comment {}0,0,1,111
div p {}0,0,0,22
p {}0,0,0,11

基本上,用 style 属性编写的规则总是比其他任何规则特殊;
具有 ID 选择器的规则比没有 ID 选择器的规则特殊;
具有类选择器的规则比只有类型选择器的规则特殊;
如果两个规则的特殊性相同,那么后定义的规则优先;

为了避免过分混乱,应尽量保持一般性样式非常一般,特殊性样式尽可能特殊;

继承

人们常常将继承和层叠混为一谈,但其实两个概念是很不一样的。
应用样式的元素的后代会继承样式的某些属性(如颜色和字号),这个就叫继承。
继承非常有用,它使开发人员不必再元素的每个后代上添加相同的样式。

恰当地使用层叠可以简化 CSS;恰当地使用继承可以减少代码中选择的数量和复杂性。

规划、组织和维护样式表

站点越大、越复杂,图形越丰富,CSS 就越难管理。

对文档应用样式

最直接的是将样式放在页面上的 style 标签之间,但会导致样式无法复用且很难维护。
一般是将样式放在一个或多个外部样式表中,然后通过 link 标签或者 @import 指令将外部样式附加到页面上。

html
<link href="/css/basic.css" rel="stylesheet" type="text/css" />
<style>
<!--
@import url("/css/advanced.css")
-->
</style>

还可以从另一个样式表导入样式表。

css
@import url(/css/layout.css);
@import url(/css/typography.css);
@import url(/css/color.css);

把 CSS 分割为多个样式表是一种常见的做法。但是,最近的浏览器基准测试已经表明,导入样式表比链接样式慢。

在使用多个 CSS 文件时,还有两个与速度有关的问题。

  1. 多个文件会导致从服务器发送多个数据包,这些数据包的数量会影响下载时间;
  2. 浏览器只能从一个域同时下载数量有限的文件;
    对于老式浏览器,这个限制常常只是两个文件;
    现代浏览器把这个限制提高到了 8 个。

由于这些原因,使用结构良好的单一 CSS 文件可以显著提高下载速度。
使用单一 CSS 文件还能把代码集中在一个地方,便于维护。
当然,应该根据站点的实际情况作出决定,没有硬性规定。

对代码增加注释,以便于理解及维护。

css
/* style comment */

为了便于维护,最好把样式分为几大块;
常常把最一般的规则放在最前面;
之后处理更特殊的样式和辅助样式;
最后,在文档底部处理覆盖和例外情况;

整个文档的结构应该像下面这样:

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

使用一种风格同一的大注释块分隔每个部分;

css
/* @group general styles
-------------------------------------------------------------------------------- */

/* @group helper styles
-------------------------------------------------------------------------------- */

/* @group page structure
-------------------------------------------------------------------------------- */

/* @group page components
-------------------------------------------------------------------------------- */

/* @group overrides
-------------------------------------------------------------------------------- */

注释会使 CSS 文件显著增大。发布时需要删除注释。
减小文件的最好方法可能是启用服务器端压缩。所有现代浏览器都可以处理用 GZIP 压缩的文件并进行即时解压。
这样可以减少对带宽的占用,加快页面的下载速度。

样式指南

样式指南可以是一个文档、网页或小型网站,它解释代码和站点的视觉设计是如何组合在一起的。
好的样式指南还可以描述重复元素的处理方法,决定它们应该如何实现和不应该如何实现。
更详细的样式指南设置可以包含编码标准,比如使用的 XHTML/CSS 版本、选择可访问性级别、浏览器的支持细节和一般的编码最佳实践。

样式指南是帮助维护或实现站点的好方法,但及时更新样式指南需要花费大量精力。

组合模式 是一个页面或一系列页面,它们使用当前的样式表显示站点上可能出现的每种样式排列组合,从标题级别和文本样式知道特定的内容和布局类型。
这些页面为开发人员提供极有价值的资源,方便构建页面。
还可以使用它们进行回归测试,检查对 CSS 的修改是否导致了问题。

附 1. 引用

  1. 《精通 CSS - 高级 Web 标准解决方案(第 2 版)》 - Andy Budd, Simon Collison, Cameron Moll 著;陈剑瓯 译。