一 简述:CSS样式与HTML的关系
第 1 章我们了解了怎么通过 HTML 来创建文档结构。本章,我们来说一说 CSS 规则怎么为 HTML 添加样式,并解释层叠的工作机制——当元素的同一个样式属性有多4 种样式值的时候,CSS 就要靠层叠机制来决定最终应用哪种样式。
每个 HTML 元素都有一组样式属性,可以通过 CSS 来设定。这些属性涉及元素在屏幕上显示时的不同方面,比如在屏幕上位置、边框的宽度,文本内容的字体、字号和颜色,等等。CSS 就是一种先选择 HTML 元素,然后设定选中元素 CSS 属性的机5 制。CSS 选择符和要应用的样式构成了一条 CSS 规则。
好,我们就先聊一聊 CSS 规则,以及怎么把 CSS 规则应用到 HTML 元素。请读者跟着我做几个例子,这些例子都要用到下面这个简单的 HTML5 模板。这个模板的代码
也可以登录 http://www.stylinwithcss.com 下载。
1.
这段代码也展示了 CSS 注释与 HTML 注释在格式上的区别。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>HTML5 Template</title>
<style>
/* CSS 规则放在<style>标签中 */
</style>
</head>
<body>
<!-- HTML 元素放在<body>标签中 -->
</body>
</html>
代码里包含一个 HTML 的<style>标签。通过这个标签可以把 CSS 样式直接写在文档中(用专业说法,是把 CSS 样式嵌入到文档中)。浏览器会负责把<style>标签中 CSS 样式应用给<body>标签中的 HTML 元素(甚至包括<html>标签)。
二 剖析 CSS 规则
1.规则实际上就是一条完整的 CSS 指令。规则声明了要修改的元素和要应用给该元素的样式。
下面就是一条 CSS 规则,它可以把段落的文本设置为红色。
p {color:red;}
把它应用给以下 HTML 标记
<p>This text is very important!</p>
这个段落的文本就会显示为红色
这个HTML 模板以及本书所有代码示例,都可以到这里下载:http://www. stylin-withcss.com。
- 23 -
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" /> <title>HTML5 Template</title> <style>
/*CSS 样式要嵌入在页面 head 元素中的<style>标签里*/
p {color:red;}
</style>
</head>
<body>
<!-- HTML 元素放在<body>标签中 -->
<p>This text is very important!</p>
</body>
</html>
2.【为文档添加样式的三种方法】
有三种方法可以把 CSS 添加到网页中,分别是写在元素标签里(也叫行内样式)、写在<style>标签里(也叫嵌入样式)和写在单独的 CSS 样式表中(也叫链接样式)。
行内样式
行内样式是写在特定 HTML 标签的 style 属性里的,比如:
<p>This paragraph simply takes on the browser's default paragraph style.</p>
<p style="font-size: 12px; font-weight:bold; font-style:italic; color:red;">By adding inline CSS styling to this paragraph, you override the default styles.</p>
行内样式的作用范围非常有限。行内样式只能影响它所在的标签,而且总会覆盖嵌入样式和链接样式。
嵌入样式
嵌入的 CSS 样式是放在 HTML 文档的 head 元素中的,比如:
<head> <!-- 其他 head 元素(如 meta、title)放在这里 -->
<style type="text/css"> h1 {font-size:16px;} p {color:blue;}
</style>
</head>
嵌入样式的应用范围仅限于当前页面。页面样式会覆盖外部样式表中的样式,但会被行内样式覆盖。像本书前面例子中那样使用嵌入方式为某个组件(比如菜单)设计样式是很方便的,因为 HTML 和 CSS 同在一页,可以互相参照。但是,等到 CSS 样式设计完毕,组件功能齐备之后,还是应该把相应的样式转移到外部样式表,以便其他页面也能共用相同的样式。
链接样式
在创建包含多个页面的网站时,需要把样式集中在一个单独的文件里,这个文件就叫样式表。样式表其实就是一个扩展名为.css 的文本文件。可以在任意多个 HTML 页面中链接同一个样式表文件,每个页面中只需加入类似下面的这一行代码即可:
<link href="styles.css" rel="stylesheet" type="text/css" />
链接样式的作用范围可以是整个网站。只要使用<link>标签把样式表链接到每个页面,相应的页面就可以使用其中的样式。随后,只要修改了样式表中的样式,改动就会在所有被选中的元素上体现出来,无论这个元素在哪个页面里。这样,既可以做到全站页面外观统一,又便于整站样式更新。
除了以上三种为页面添加样式的方法,还有一种在样式表中链接其他样式表的方法,那就应用 @import 指令(是一种 at 规则):
@import url(css/styles2.css)
要注意的是,@import 指令必须出现在样式表中其他样式之前,否则@import 引用的样式表不会被加载。
有一点很重要,那就是 CSS 样式是通过<style>标签嵌入到页面里的。当浏览器遇到开标签<style>时,就会由解释 HTML 代码切换为解释 CSS 代码。等遇到闭标签</style>时,它会再切换回解释 HTML 代码。
注意:
对于写在样式表里的样式,就不需要<style>标签了。如果你在样式表里加上这个标签,样式表中的样式就不会被浏览器加载了。
本章后面的例子都将使用这个模板。读者可以把这个模板写到一个文本文件里,然后保存为扩展名是.html 的文件。之后,只要像前面那样,把每个例子的 CSS 和 HTML 代码复制粘贴到这个模板中就行了。粘贴后保存,再在浏览器中打开,就可以看到效果。
3.
CSS规则命名惯例 | |
| |
CSS 规则由选择符和声明两部分组成,其中选择符用于指出规则所要选择的元素 | |
(图 2-2 的示例选择符是要选择段落),声明则又由两部分组成:属性和值。属性指出 | |
要影响元素哪方面的样式(图 2-2 的示例属性影响的是文本颜色),值就是属性的一2 | |
个新状态(图 2-2 中是红色)。 |
p {color:red;}
4.对这个基本的结构,有三种方法可以进行扩展。
第一种方法:多个声明包含在一条规则里。
p {color:red; font-size:12px; font-weight:bold;}
这样,一条规则就可以把段落文本设置成红色,12 像素大,粗体。
注意三个声明末尾都有一个分号,以示分隔。其中,最后一个位于右花括号之前的分号是可选的,但我始终都会加上它。因为将来再添加声明时就不用再记着加了。
有读者可能会好奇地想,这些属性(比如 font-size 和 color)还有其他什么值呢?比如,指定颜色值的时候是不是可以不用颜色名,而用 RGB(red,green,blue)格式?当然,可以。不过,我想还是容我把选择符的工作机制讲完吧。本章后面,我们再详细讲规则的声明部分。
第二种方法:多个选择符组合在一起。如果想让<h1>、<h2>和<h3>的文本都变成蓝色,
粗体,可以这样分别写:
h1 {color:blue; font-weight:bold;}
h2 {color:blue; font-weight:bold;}
h3 {color:blue; font-weight:bold;}
但其实,把三个选择符组合在一起也可以,这样就能减少重复输入:
h1, h2, h3 {color:blue; font-weight:bold;}
千万注意每个选择符之间要用逗号分隔(最后一个后面不用加)。至于选择符之间的空格,随意,可加可不加,但加了好像看得更清楚。
第三种方法:多条规则应用给一个选择符。 假设,你在写完前面那条规则后,又想只把 h3 变成斜体,那可以再为 h3 写一条规则:
h1, h2, h3 {color:blue; font-weight:bold;}
h3 {font-style:italic;}
5.
以上这三种规则结构,是今后我们要写的更复杂的选择组合的基础。更复杂的选择组合是啥意思?比如说,你想写一条 CSS 规则,希望给位于附注栏(aside 元素)中的一个段落添加样式,让这个段落看起来与正文(比如 article 元素)中的段落不一样。但我们到目前为止看到的规则,会影响整个文档中同种类型的所有元素。下面我们就来讲一讲怎么随心所欲地选择在标记中位于特殊区域的元素。
所有用于选择特定元素的选择符又分三种。
瑨 上下文选择符。基于祖先或同胞元素选择一个元素。
瑨 ID 和类选择符。基于 id 和 class 属性的值(你自己设定)选择元素。
属性选择符。基于属性的有无和特征选择元素。
三 上下文选择符
1.简述:
下面,我们就来解决上一节提到的那个问题:你想分别给 article 和 aside 中的段落文本,分别设置不同的字号。像这种“基于位置”变换某个标签样式的问题,可以用上下文选择符来解决,本节我们就来讲一讲这种选择符。
定义:
上下文选择符的格式如下: | 1 |
标签 1 标签 2 {声明} |
|
其中,标签 2 就是我们想要选择目标,而且只有在标签 1 是其祖先元素(不一定是 |
|
父元素)的情况下才会被选中。 | 2 |
| |
上下文选择符,严格来讲(也就是 CSS 规范里),叫后代组合式选择符(descendant |
|
combinator selector),就是一组以空格分隔的标签名。用于选择作为指定祖先元素后 |
|
代的标签。 |
|
article p {font-weight:bold;} | 3 |
这个例子中的上下文选择符表明,只有是 article 后代的 p 元素才会应用后面的样式。换句话说,上面这条规则的目标是位于 article 上下文中的 p 元素。
<body>
<article>
<h1>Contextual selectors are <em>very</em> selective</h1>
<p>This example shows how to target a <em>specific</em> tag.</p>
</article>
<aside>
<p>Contextual selectors are <em>very</em> useful!</p> </aside>
</body>
以上标记在没有应用 CSS 的情况下,如图 2-3 所示。
2.
图中盒子的轮廓是通过在 Firefox 的 Web Developer 工具条中选择 Outline Block Level Elements 和 Outline Custom Elements(可以在弹出的窗口中输入行内元素的名字)生
成的。
在接下来我向大家展示那些瞄准标记中特定元素的 CSS 规则时,建议大家参照图 2-4 的 DOM 结构图。
我们就从最简单的一个标签的选择符开始。
em {color:green;}
这条规则选择页面中所有 em 元素,因此三个 em 元素中的文本都会变成绿色,如图 1 2-6 所示(图中为浅灰色)。
接下来修改这个上下文选择符,让它选择页面中特定区域中的标签。
p em {color:green;} | 4 |
万万牢记,上下文选择符以空格作为分隔符,而分组选择符则以逗号作为分隔符,不要弄混。
现在,前面的 p 元素是上下文,后面的 em 元素是要选择的目标。这里选择符的意思用白话说,就是:“选择以 p 元素为祖先的所有 em 元素。”好好,看看图 2-4 中的结构图,哪些标签会被这条规则选中?
没错,你说得对,会选中两个段落中的 em,而不会选中标题中的 em。因为标题中的 em 并没有作为祖先的段落,因此这条规则对它不适用。
◆ 进一步展示了单上下文选择符的可能性。下面的 CSS 规则
article em {color:green;}
这次,我们使用了 article 作为上下文,因此该元素中标题及段落下的 em 都变成了绿色(图中是浅灰色)。而位于 aside 中的 em 未受影响,因为它没有 article 这么个祖先元素。注意,至于 article 与 em 之间还隔着一个 p 元素(或 h1 元素),都不影响结果。只要 em 在整个层次结构中有一个叫 article 的祖先元素就可以了。
要是我只想选择标题中的 em 呢?那就需要更加具体的上下文。
article h1 em {color:green;}
这里选择符的意思就是说:“选中的 em 必须有一个祖先是 h1,后者进而还要有一个祖先是 article。”
3. 特殊的上下文选择符
刚才,我们学习的上下文选择符是以某个祖先标签作为上下文。只要有标签在它的层次结构“上游”存在这么一个祖先,那么就会选中该标签。无论从该标签到作为祖先的上下文之间隔着多少层次都没有关系。不过,有时候我们可能还会需要比“某些祖先”更加具体的上下文。比如说吧,要是你想根据父元素或者同胞元素的标签名来选择元素怎么办呢?
下面我们再用另一段标记来演示几种特殊的上下文选择符。
<section>
<h2>An H2 Heading</h2>
<p>This is paragraph 1</p>
<p>Paragraph 2 has <a href="#">a link</a> in it.</p>
<a href="#">Link</a>
</section>
子选择符>
标签 1 > 标签 2
标签 2 必须是标签 1 的子元素,或者反过来说,标签 1 必须是标签 2 的父元素。与常规的上下文选择符不同,这个选择符中的标签 1 不能是标签 2 的父元素之外的其他祖先元素。
section > h2 {font-style:italic;}
图 2-10 展示了以上规则的结果。
紧邻同胞选择符+
标签 1 + 标签 2
标签 2 必须紧跟在其同胞标签 1 的后面。
h2 + p {font-variant:small-caps;}
◆ 一般同胞选择符~
标签 1 ~ 标签 2
标签 2 必须跟(不一定紧跟)在其同胞标签 1 后面。
用 Shift+1 键左侧的键输入字符~(波浪号)。
h2 ~ a {color:red;}
◆ 通用选择符*
(按 Shift+8)
通用选择符*(常被称为星号选择符)是一个通配符,它匹配任何元素,因此下面这条规则
* {color:green;}
会导致所有元素(的文本和边框)都变成绿色。不过,一般在使用*选择符时,都会同时使用另一个选择符,比如:
color 属性设定的是前景色。前景色既影响文本也影响边框,但人们通常只用它设定文本颜色。
总之,只有一个标签名的选择符会选中页面中所有相同标签的实例。而通过上下文选择符,则可以指定标签必须具备相应的祖先或同胞。
p * {color:red;}
这样只会把 p 包含的所有元素的文本变成红色。
这个选择符有一个非常有意思的用法,即用它构成非子选择符,比如:
section * a {font-size:1.3em;}
如图 2-13 所示,任何是 section 孙子元素,而非子元素的 a 标签都会被选中。至于 a 的父元素是什么,没有关系。
4. ID 和类选择符
ID 和类为我们选择元素提供了另一套手段,利用它们可以不用考虑文档的层次结构。只要你在 HTML 标记中为元素添加了 id 和 class 属性,就可以在 CSS 选择符中使用 ID 和类名,直接选中文档中特定的区域。
可以给 id 和 class 属性设定任何值,但不能以数字或特殊符号开头。
◆ 类属性
类属性就是 HTML 元素的 class 属性,body 标签中包含的任何 HTML 元素都可以添加这个属性。下面这段代码展示了 HTML class 属性的用法。
<h1 class="specialtext">This is a heading with the <span>same class</span> as the second paragraph.</h1>
<p>This tag has no class.</p>
<p class="specialtext"> When a tag has a class attribute, you can target it <span>regardless</span> of its position in the hierarchy.</p>
图 2-14 展示了这段代码的显示结果。
注意,我已经给其中两个标签添加了 specialtext 类。
1. 类选择符
.类名
注意,类选择符前面是点(.),紧跟着类名,两者之间没有空格。
类选择符就是在 HTML 类名前面加一个点(英文句号)。 | 1 |
好,我们来为标签应用如下 CSS 样式。
p {font-family:helvetica, sans-serif; font-size:1.2em;}
.specialtext {font-style:italic;}
图 2-15 | 两个段落中文本的字体都变成了 Helvetica,而标题和第二个段落都有 specialtext 类, 4 |
| 所以都变成了斜体 |
应用这两条规则的结果,就是两个段落都以 Helvetica 字体(如果本地没有该字体则使用浏览器通用的无衬线字体)显示,而带有 specialtext 类的段落同时也变成了斜体。h1 中的文本仍然使用浏览器默认字体(一般是 Times),因为 Helvetica 字体只应用给段落,不过由于它也有 specialtext 类,所以也应用了斜体。 另外,没有默认样式的 span,由于我们没有明确为其添加样式,所以就继承了其父元素的样式。
2. 标签带类选择符
如果你只想瞄准带有这个类的段落,可以把标签名和类选择符写在一块,比如:
p {font-family:helvetica, sans-serif; font-size:1.2em;}
.specialtext {font-style:italic;}
p.specialtext {color:red;}
如图 2-16 所示,第三条 CSS 规则只选择带 specialtext 类的段落。像这样组合标签名和类选择符,可以让你更精确地选择特定的标签。
图 2-16通过组合标签名和类选择符,可以让选择符更具体
下面我们就把这个技巧进一步发挥一下。
p {font-family:helvetica, sans-serif; font-size:1.2em;}
.specialtext {font-style:italic;} p.specialtext {color:red;}
p.specialtext span {font-weight:bold;}
如图 2-17 所示,单词“regardless”变成了粗斜体,因为包含它的 span 位于一个带有 specialtext 类的段落中。这四条规则全都会对 span 产生影响,因为它从其父元素,那个带 specialtext 类的段落那里,继承了前三条规则的样式。我们已经两次提到了继承,关于继承我们放在本章后面再详细介绍。
图 2-17再添加一个选择符,可以把选择目标锁定为更特殊的元素
3. 多类选择符
可以给元素添加多个类,比如:
<p class="specialtext featured">Here the span tag <span>may or may not</span> be styled.</p>
多个类名,如这里的 specialtext 和 featured,放在同一对引号里,用空格分隔。实际上,更准确的说法,就应该是 HTML 的 class 属性可以有多个空格分隔的值。要
选择同时存在这两个类名的元素,可以这样写:
.specialtext.featured {font-size:120%;}
注意,CSS 选择符的两个类名之间没有空格,因为我们只想选择同时具有这两个类名的那个元素。如果你加了空格,那就变成了“祖先/后代”关系的上下文选择符了。
每个类名分别用一个 HTML class 属性的做法是常见的错误,正确的做法是像上面的代码那样,只用一个 class 属性,但给它设定多个值。本章后面还会讲到多类名的实际用法。