4.1. 语法基础

如我们所知,C、Java 等被称为编程语言,我们在提到它们的时候通常可以在它们的名称后加上“语言”二字,如 C语言Java语言HTML、XHTML、XML 也是语言,标记语言,它们的名称里本身就带有“语言”(Language)的字眼。

CSS 这个名称中找不到它属于语言的证据,它不是标记语言,也和 C、Java 等语言的形式不同。

CSS 确实是一种编程语言,从编程范式(programming paradigm)来看,它和标记语言同属于声明式编程(declarative programming)的范畴[[1]](http://blog.thinkful.com/post/71644244908/thoughts-on-declarative-and-imperative-languages)[[2]](http://programmers.stackexchange.com/questions/129141/is-css-a-programming-language)CSS 直接告诉浏览器应该以什么样的形式格式化元素,而无需像[命令式编程(imperative programming)](http://zh.wikipedia.org/wiki/%E6%8C%87%E4%BB%A4%E5%BC%8F%E7%B7%A8%E7%A8%8B)语言(如 C)那样以具体的指令告诉计算机如何做到这一点[[3]](http://developer.51cto.com/art/201306/400908.htm),它是如此特殊,可以被认为是一种[领域专属语言]((http://baike.baidu.com/view/1616623.htm))([Domain Specific Language](http://en.wikipedia.org/wiki/Domain-specific_language),DSL)[[4]](http://www.php100.com/html/itnews/PHPxinwen/2010/0831/5359.html)[[5]](http://www.martinfowler.com/bliki/DomainSpecificLanguage.html)[[6]](http://programmers.stackexchange.com/questions/80389/can-css-be-considered-a-dsl)

作为一种编程语言,CSS 有着非常简单的语法。

4.1.1. 语法构成

以下代码演示了 CSS 的语法构成:

/* 使得文档中的 p 元素包含的内容以红色字体居中显示 */
p { text-align: center; color: red; }

该代码将使得文档中所有段落(p 元素)包含的文本以红色字体(color: red)居中(text-align: center)显示。

代码的第一行为 CSS 注释,注释可以是单行的也可以是多行的,且 CSS 中的注释只有这一种写法。

代码中的 p 被称为选择器(selector),选择器定义了将针对 HTML 文档中的哪些元素进行样式定义,如本例将针对文档中的所有段落(p 元素)进行样式定义。

text-align: center 被称为一组 CSS 属性,冒号(:)前面的部分被称为 CSS 属性名,冒号后面的部分被称为 CSS 属性值。如果样式定义中存在不止一组 CSS 属性,那么多组 CSS 属性之间需要使用分号(;)隔开。

4.1.2. 引入方式

按照 CSS 代码出现的位置,通常可以将样式分为三类:内联样式、内嵌样式和外部样式。

如果希望针对 HTML 中的某个元素指定专属于该元素的样式,此时,需要为该元素增加一个 style 属性。style 属性是 HTML 元素的全局属性之一,其属性值是一组或多组 CSS 属性的形式,这种情境下不需要额外指定 CSS 选择器,且作用范围仅局限于 style 属性所属的 HTML 元素,如:

<p style="color: red; text-align: center;">文本内容</p>

这种形式被称为内联inline)样式。

第二种方式,通常需要在 HTML 文档 head 元素的开始和结束标签之间增加 style 元素,其形式如下所示:

<html>
    <head>
        <title>文档标题</title>
        <style type="text/css">
            p { text-align: center; color: red; }
        </style>
    </head>
    <body>
        <p>段落 1</p>
        <p>段落 2</p>
    </body>
</html>

这是所谓的内嵌embedded)样式,它的作用范围是当前 HTML 文档,本例两个段落包含的文本均会以红色字体居中显示。

style 元素用于为 HTML 文档定义内嵌样式,除了 type 属性指定其MIME类型为唯一属性值 text/css 这种固定用法外,还可以通过使用其 media 属性指定在不同设备上使用的不同样式,media 属性的属性值有:

  • screen:计算机屏幕
  • print:打印预览模式或打印页
  • tty:电传打字机以及使用等宽字符网格的类似设备
  • tv:电视类型设备(低分辨率、有限的屏幕翻滚能力)
  • projection:放映机
  • handheld:手持设备(小屏幕、有限的带宽)
  • braille:盲人用点字法反馈设备
  • aural:语音合成器
  • all:适合所有设备

其中,screen 是默认值,print 也是常见的选项,它们和 all 一起是所有浏览器都支持的设备选项。

在第三种形式中,CSS 代码被放在一个和 HTML 文档独立的扩展名是 .css 的样式表文件中,如样式表 style.css 文件中存在如下代码:

p { text-align: center; color: red; }

使用该样式表定义样式的 HTML 文件中通常在 head 元素的开始和结束标签之间增加如下所示的 link 元素(假设 .html 文件和 style.css 文件位于同一文件夹):

<html>
    <head>
        <title>文档标题</title>
        <link type="text/css" rel="stylesheet" href="style.css" />
    </head>
    <body>
        <p>段落 1</p>
        <p>段落 2</p>
    </body>
</html>

这种外部样式表文件引用的方式被称为外部(external)样式。一个外部样式表文件可以被多个 HTML 文件所引用,它的作用范围是所有引用该样式表文件的 HTML 文档。

这种方式用到的 link 元素,可以看做是不可见的 a 元素(证据是它们重叠的属性),用于定义文档与外部资源的关系,最常见的用途就是在 HTML 文档中链接 CSS 样式表文件。它和上面介绍的 style 元素一样具有相同含义的 type 和 media 属性,并使用 href 属性指定被引用的 .css 文件的路径。

稍微介绍一下 link 元素的 rel 属性,它用于定义当前文档与被链接文档之间的关系relationship),这是一个空元素,它的一些常见的属性值有:

  • stylesheet:文档的外部样式表
  • alternate:文档的替代版本(比如打印页、翻译或镜像)
  • icon:文档的收藏夹图标
  • 文档结构相关:
    • contents:文档的目录
    • index:文档的索引
    • glossary:文档的术语表
    • copyright:文档的版权信息
    • chapter:文档的章
    • section:文档的节
    • subsection:文档的小节
    • appendix:文档的附录
    • help:文档的帮助文档
    • bookmark:文档的相关文档(位于同一书签中)
  • 集合相关:
    • start:集合中的第一个文档
    • next:集合中的下一个文档
    • prev:集合中的上一个文档

以及一些其它和微格式(microformat)[[7]](http://www.xml.com/lpt/a/2005/03/23/deviant.html)[[8]](http://ablognotlimited.com/index.php/articles/getting-semantic-with-microformats-introduction/)[[9]](http://ablognotlimited.com/index.php/articles/getting-semantic-with-microformats-part-1-rel/)[[10]](http://ablognotlimited.com/index.php/articles/getting-semantic-with-microformats-part-2-xfn/)相关的值[[11]](http://microformats.org/wiki/Main_Page)[[12]](http://www.lao8.org/article_1250/rel_noflow)

如:

<link type="text/css" rel="stylesheet" href="style.css" />

说明 style.css 是使用该元素的 HTML 文件的外部样式表。

<link type="text/css" rel="help" href="help.htm" />

说明 default.htm 是使用该元素的 HTML 文件的帮助文档。

<link type="images/png" rel="icon" href="favicon.png" />

说明 favicon.png 是当前页面的收藏夹图标[[13]](http://www.cnblogs.com/fsjohnhuang/p/4149793.html)

link 元素的另外一个属性 rev 和 rel 是类似的,只不过它表示的关系的方向和 rel 属性相反reverse),即被链接文档和 HTML 文档之间的关系。

还有一种在 HTML 中使用 CSS 的方式:使用 @import 指令的导入import)方式,如:

<html>
    <head>
        <title>文档标题</title>
        <style type="text/css">
            @import "import.css";
            p { text-align: center; color: red; }
        </style>
    </head>
    <body>
        <p>段落 1</p>
        <p>段落 2</p>
    </body>
</html>

这是方法在很多资料中被认为是不推荐使用的[[14]](http://browserdiet.com/zh/#prefer-link-over-import)[[15]](http://segmentfault.com/blog/laopopo/1190000000369549)[[16]](http://www.qianduan.net/high-performance-web-site-do-not-use-import.html)[[17]](http://www.dreamdu.com/blog/2007/05/11/css_link_import/),不再过多描述。

4.1.3. “层叠”的含义

在学习 HTML 的时候,我们已经注意到,有一些元素本身具有自己的默认样式,如 em 元素包含的文本会被显示为斜体,blockquote 元素包含的内容会在左右存在一定缩进。即使我们不为 em、blockquote 元素指定任何样式,它们也将默认具有下例所示的样式:

cite, em, var, address { font-style: italic; }
blockquote { margin-left: 40px; margin-right: 40px; }

无论元素是否具有默认样式,我们都可以借助上述三种 CSS 引用方式中的一种或几种来更改它的样式,也就是说,元素最终呈现的外观是由它的默认样式以及其所属 HTML 文档中引入的所有可能作用到该元素上的 CSS 代码共同决定的,这也就是 CSS 这个名称中“层叠”的含义。

需要注意的是,一旦使用 CSS 对元素的默认样式进行了更改,我们将无法根据页面中元素的实际表现形式来大致判断页面中到底使用了哪些元素,一个显示为斜体的元素可能是一个 strong,一个显示为粗体的元素却可能是一个 em。

样式在“层叠”时具有优先级次序,CSS 的作用即用于更改元素的样式,因此默认样式的优先级最低,三种不同 CSS 引用方式中 CSS 代码距离指定元素越远(出现得越早)的样式设定的优先级越低(影响力较小),同一种引用 CSS 的方式中针对同一个 CSS 属性进行的重复设定也以后出现的优先级为高。针对同一元素的同一样式在三种不同引用方式中都进行了设定,最终元素的表现将由优先级最高的 CSS 代码来最终决定。

假设,我们有包含如下 HTML 代码的文件 page.htm:

<!-- page.htm -->
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>CSS Priority Test</title>
    <link href="style_ro.css" rel="stylesheet" type="text/css" />
    <link href="style_yg.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <p>This is a paragraph.</p>
</body>
</html>

其中,引用的两个外部样式表文件的 CSS 代码分别为:

/* style_ro.css */
p { color: red; }
p { color: orange; }
/* style_yg.css */
p { color: yellow; }
p { color: green; }

按照上述“层叠”的原则,网页上段落中的文本将显示为绿色(green)。因为对于同一 CSS 属性 color 的设置,style_yg.css 的引用较晚(距离元素 p 更近),style_yg.css 中 green 比 yellow 出现较晚(也被认为距离元素 p 更近),优先级也较高。

在本例中,调整 page.htm 中引用 .css 文件的顺序,更改两个 .css 文件中代码的顺序,都将直接影响文本的颜色。

接下来,我们在 page.htm 中增加几行代码,使其代码变为:

<!-- page.htm -->
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>CSS Priority Test</title>
    <style type="text/css">
        p { color: cyan; }
        p { color: blue; }
    </style>
    <link href="style_ro.css" rel="stylesheet" type="text/css" />
    <link href="style_yg.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <p>This is a paragraph.</p>
</body>
</html>

此时,网页中的文本将显示仍将显示为绿色(green)。

如果将 style 元素移至第二个 link 元素之后,段落文本显示为蓝色(blue)。内嵌样式和外部样式都被认为是 HTML 以外的相对完整、独立的 CSS 代码,两个方式之间并无优先级顺序之分,仍以出现较晚(更靠近元素)影响元素表现。但是,我们在同时使用这两种样式时习惯将 link 元素写在 style 元素之前,所以,一般认为优先级上内嵌样式大于外部样式。

如果我们为 p 元素增加 style 属性置:

<!-- page.htm -->
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>CSS Priority Test</title>
    <link href="style_ro.css" rel="stylesheet" type="text/css" />
    <link href="style_yg.css" rel="stylesheet" type="text/css" />
    <style type="text/css">
        p { color: cyan; }
    </style>
</head>
<body>
    <p style="color: purple;">This is a paragraph.</p>
</body>
</html>

此时,段落文本最终将显示为紫色(purple),因为很明显,这种方式是只针对该元素的样式定义,距离最近,优先级最高。

4.1.4. 选择器与伪类

上面的示例中,我们均以 p 元素作为选择器,这种选择器被称为元素选择器,HTML 中的任何可见元素的名称均可作为 CSS 中的元素选择器。

em { font-style: normal; font-weight: bold; }
strong { font-weight: normal; font-style: italic; }

这个例子使得文档中的 em 和 strong 元素交换了它们的默认样式,即 em 显示为粗体,strong 显示为斜体。

除了最基本的元素选择器外,在 CSS 还有另外一些基本选择器。

如果 HTML 文档中某个课件元素具有 id 属性,可以使用 id 选择器ID Selector)为该元素指定不同于其它元素的(id 属性唯一标识了一个特定元素)特定样式。

<div id="container">text in div</div>
#container { color: blue; }

id 选择器的形式是“#”紧跟着元素的 id 属性值。

如果希望都页面中部分不同元素应用相同样式,可以在 CSS 定义类选择器Class Selector),其形式是“.”紧跟着一个开发人员自定义的类选择器的名称,需要为这些元素指定 class 属性值为类选择器的类名。

<h1 class="ca">heading</h1>
<p class="ca">paragraph</p>
<p>不应用类选择器的段落</p>
.ca { text-align: center; }

CSS 中针对一些元素的动态状态(如超级链接的四种状态)定义了一些伪类选择器(Pseudo-classes)。常见的伪类请参考以下示例。

a:link { color: #FF0000; }         /* 未访问的链接 */
a:visited { color: #00FF00; }      /* 已访问的链接 */
a:hover { color: #FF00FF; }        /* 鼠标移动到链接上 */
a:active { color: #0000FF; }       /* 选定的链接 */

以上伪类用于将文档中超级链接的四种状态分别呈现为不同的颜色(注意:顺序很重要)。

p:first-letter { font-size: 36px; }
p:first-line { color: red; }

以上伪类将段落中的首字符和首行分别定义为不同的样式。

以上介绍的选择器都是单一选择器,CSS 中还定义了如下复合选择器:

  • 群选择器Grouping Selector):多个选择器组成,每个选择器使用“,”分隔,表示多个选择器共同使用相同的样式设置
  • 派生选择器Contextual Selector):多个选择器组成,每个选择器使用空格分隔,表示一种元素嵌套关系,最终样式会作用在最后的选择器上
p, #container, .ca { text-decoration: underline; }

上例是一个群选择器,表示文档中的所有段落、id 属性值是 container 以及 class 属性值是 ca 的元素中的文本都将加上下划线。

p .ca { font-style: italic; }

上例是一个派生选择器,表示文档中只有那些包含在 p 元素中的 class 属性值时 ca 的元素才显示为斜体。

选择器之间也是有优先级的,CSS 内部存在着一个非常复杂的机制来确定这种优先级,实际应用中,应当以尽量简单的方式来实现样式定义,而不是过于强调那些技巧性的东西。