CSS规则简介
每个 HTML 元素都有一组样式属性,可以通过 CSS 来设定。这些属性涉及元素在屏 幕上显示时的不同方面,比如在屏幕上位置、边框的宽度,文本内容的字体、字号和颜色,等等。CSS 就是一种先选择 HTML 元素,然后设定选中元素 CSS 属性的机制。CSS 选择符和要应用的样式构成了一条 CSS 规则。
剖析 CSS 规则
规则实际上就是一条完整的 CSS 指令。规则声明了要修改的元素和要应用给该元素的样式。
下面就是一条 CSS 规则,它可以把段落的文本设置为红色。
p {color:red;}
把它应用给以下 HTML 标记
<p>This text is very important!</p>
这个段落的文本就会显示为红色。
上下文选择符
**规则:**标签 1 标签 2 {声明}
上下文选择符,严格来讲(也就是 CSS 规范里),叫后代组合式选择符(descendant combinator selector),就是一组以空格分隔的标签名。用于选择作为指定祖先元素后代的标签。
p em {color:green;}
特殊的上下文选择符
子选择符>
**规则:**标签 1 > 标签 2
标签 2 必须是标签 1 的子元素,或者反过来说,标签 1 必须是标签 2 的父元素。与常 规的上下文选择符不同,这个选择符中的标签 1 不能是标签 2 的父元素之外的其他祖先元素。
section > h2 {font-style:italic;}
紧邻同胞选择符+
规则: 标签 1 + 标签 2
标签 2 必须紧跟在其同胞标签 1 的后面。
h2 + p {font-variant:small-caps;}
一般同胞选择符~
规则: 标签 1 ~ 标签 2
标签 2 必须跟(不一定紧跟)在其同胞标签 1 后面。
h2 ~ a {color:red;}
通用选择符*
规则: *
通用选择符*(常被称为星号选择符)是一个通配符,它匹配任何元素,因此这条规则
* {color:green;}
会导致所有元素(的文本和边框)都变成绿色。不过,一般在使用*选择符时,都会同时使用另一个选择符,比如
p * {color:red;}
这样只会把 p 包含的所有元素的文本变成红色。
这个选择符有一个非常有意思的用法,即用它构成非子选择符,比如:
section * a {font-size:1.3em;}
任何是 section 孙子元素,而非子元素的 a 标签都会被选中。至于 a 的父元素是什么,没有关系。
ID和类选择符
ID 和类为我们选择元素提供了另一套手段,利用它们可以不用考虑文档的层次结构。 只要你在 HTML 标记中为元素添加了 id 和 class 属性,就可以在 CSS 选择符中使用 ID 和类名,直接选中文档中特定的区域。
可以给 id 和 class 属性设定任何值,但不能以数字或特殊符号开头。
类属性
类属性就是 HTML 元素的 class 属性,body 标签中包含的任何 HTML 元素都可以添 加这个属性。下面这段代码展示了 HTML class 属性的用法。
(1) 类选择符
.类名
注意,类选择符前面是点(.),紧跟着类名,两者之间没有空格。
p {font-family:helvetica, sans-serif; font-size:1.2em;}
.specialtext {font-style:italic;}
(2) 标签带类选择符
如果你只想瞄准带有这个类的段落,可以把标签名和类选择符写在一块
p {font-family:helvetica, sans-serif; font-size:1.2em;}
.specialtext {font-style:italic;}
p.specialtext {color:red;}
第三条 CSS 规则只选择带 specialtext 类的段落。
(3) 多类选择符
可以给元素添加多个类,比如:
<p class="specialtext featured">Here the span tag
<span>may or may not</span>
be styled.
</p>
选择同时存在这两个类名的元素,可以这样写:
.specialtext.featured {font-size:120%;}
注意,CSS 选择符的两个类名之间没有空格,因为我们只想选择同时具有这两个类名的那个元素。如果你加了空格,那就变成了“祖先/后代”关系的上下文选择符了。
ID属性
如果有一个段落像下面这样设定了 ID 属性
<p id="specialtext">This is the special text.</p>
那么,相应的 ID 选择符就是这样的:
#specialtext {CSS样式声明}
或者这样的:
p#specialtext {CSS样式声明}
用于页内导航的 ID
ID 也可以用在页内导航链接中。下面就是一个链接,其目标是同一页的另一个位置。
<a href="#bio">Biography</a>
href 属性值开头的#表示这个链接的目标在当前页面中,因而不会触发浏览器加载页面(如果没有#,浏览器就会尝试加载 bio 目录下的默认页面了)。使用与 CSS 选择符里相同的 #ID 名语法,可以把链接导航到同一页面中的目标 ID。在这个页面的下方,应该有对应的目标元素。
<h3 id="bio">Biography</h3>
<p>I was born when I was very young...</p>
同样要注意,作为目标的 ID 值前面是没有#的,就是一个普通的 ID 值。 用户单击前面的链接时,页面会向下滚动到 ID 值为 bio 的 h3 元素的位置。如果链接的 href
属性里只有一个#,那么点击该链接会返回页面顶部。
<a href="#">Back to Top</a>
换句话说,要写一个“返回顶部”链接,根本不需要 ID 为#的目标元素。
另外,如果你暂时不知道某个 href 应该放什么 URL,也可以用#作为占位符,但不能把该属性 留空。因为 href 属性值为空的链接的行为跟正常链接不一样。这样,团队中的其他人将来可以用中间层(比如 PHP)变量替换#,以便动态接收来自数据库的 URL。
什么时候用ID,什么时候用类
(1) 什么时候使用 ID
ID 的用途是在页面中唯一地标识一个元素。同一个页面中的每一个 ID 属性,都必须有独一无二的值(名字)。换一个角度讲,每个 ID 名在页面中都只能用一次。
<nav id="mainmenu">
<ul>
<li><a href="#">Yin</a></li>
<li><a href="#">Yang</a></li>
</ul>
</nav>
#mainmenu a {color:orange;}
(2) 什么时候使用类
类的目的是为了标识一组具有相同特征的元素。
<nav>
<ul>
<li class="boy"><a href="#">Alan</a></li>
<li class="boy"><a href="#">Andrew</a></li>
<li class="girl"><a href="#">Angela</a></li>
<li class="boy"><a href="#">Angus</a></li>
<li class="girl"><a href="#">Anne</a></li>
<li class="girl"><a href="#">Annette</a></li>
</ul>
</nav>
.boy a {color:#6CF;}/*蓝色*/
.girl a {color:#F9C;}/*粉红色*/
第一条规则选择所有类名为 boy 的祖先元素包含的 a 元素,第二条规则选择所有类名为 girl 的祖先元素包含的 a 元素。这两种情况下的祖先元素,都是作为相应链接父元素的 li 元素。
ID和类的小结
ID 的用途是在页面标记中唯一地标识一个特定的元素。它能够为我们编写 CSS 规则提供必要的上下文,排除无关的标记,而只选择该上下文中的标签。
相对来说,类是可以应用给任意多个页面中的任意多个 HTML 元素的公共标识符, 以便我们为这些元素应用相同的 CSS 样式。而且,使用类也让为不同标签名的元素应用相同的样式成为可能。
属性选择符
学习了使用上下文选择符、ID 和类选择 HTML 元素。再有一种选择元素的方法是属性选择符,它基于 HTML 标签的属性选择元素。
属性名选择符
标签名[属性名]
选择任何带有属性名的标签名。
比如,下面的 CSS
img[title] {border:2px solid blue;}
会导致像下面这个带有 title 属性的 HTML img 元素显示 2 像素宽的蓝色边框,至于title 属性有什么值,无关紧要,只要有这个属性在就行啦。
<img src="images/yellow_flower.jpg" title="yellow flower" alt="yellow flower" />
什么情况下会用到这个属性选择符呢?比如,可以在用户鼠标移动到这些图片上时, 此时浏览器会显示一个(利用 title 属性中的文本生成的)提示条。一般来说,人 们经常给 alt 和 title 属性设定相同的值。alt 属性中的文本会在图片因故未能加载时显示,或者由屏幕阅读器朗读出来。而 title 属性会在用户鼠标移动到图片上时, 显示一个包含相应文本的提示。
属性值选择符
标签名[属性名="属性值"]
选择任何带有值为属性值的属性名的标签名。
这个选择符可以让你控制到属性的值是什么。例如,这条规则
img[title="red flower"] {border:4px solid green;}
在图片的 title 属性值为 red flower的情况下,才会为图片添加边框。换句话说,下面这个 img 元素就会被加上边框。
<img src="images/red_flower.jpg" title="red flower" alt="red flower" />
属性选择符的小结
基于属性名和属性的其他特征选择元素,为我们提供了另一种区别对待相同标签的机会。只要事先规划好,就可以编写出适合属性选择符的标记来。
到现在为止,我们介绍的选择符都有一个共同点,即它们针对的都是标记中的某个部分,比如标签名、类名、ID、属性或属性值。然而,使用 CSS 还可以在某些事件发生时,改变某些元素的样式,比如用户鼠标悬停在一个链接上。而这就要靠伪类来实现了。
伪类
伪类与类相似,但实际上并没有类会附加到标记中的标签上。伪类分两种。
(1) UI(User Interface,用户界面)伪类会在 HTML 元素处于某个状态时(比如鼠标指针位于链接上),为该元素应用 CSS 样式。
(2) 结构化伪类会在标记中存在某种结构上的关系时(如某个元素是一组元素中的第一个或最后一个),为相应元素应用 CSS 样式。
UI伪类
UI 伪类会基于特定 HTML 元素的状态应用样式。最常使用 UI 伪类的元素是链接(a 元素),利用 UI 伪类,链接可以在用户鼠标悬停时改变文本颜色,或者去掉文本的下划线。
(1) 链接伪类
针对链接的伪类一共有 4 个,因为链接始终会处于如下 4 种状态之一。
- Link。此时,链接就在那儿等着用户点击。
- Visited。用户此前点击过这个链接。
- Hover。鼠标指针正悬停在链接上。
- Active。链接正在被点击(鼠标在元素上按下,还没有释放)。
a:link {color:black;}
a:visited {color:gray;}
a:hover {text-decoration:none;}
a:active {color:red;}
(2) :focus 伪类
表单中的文本字段在用户单击它时会获得焦点,然后用户才能在其中输入字符。下面的规则
input:focus {border:1px solid blue;}
会在光标位于 input 字段中时,为该字段添加一个蓝色边框。这样可以让用户明确地知道输入的字符会出现在哪里。
(3) :target 伪类
如果用户点击一个指向页面中其他元素的链接,则那个元素就是目标(target),可以 用:target 伪类选中它。
对于下面这个链接
<a href="#more_info">More Information</a>
位于页面其他地方、ID 为 more_info 的那个元素就是目标。该元素可能是这样的:
<h2 id="more_info">This is the information you are looking for.</h2>
那么,如下 CSS 规则
#more_info:target {background:#eee;}
会在用户单击链接转向 ID 为 more_info 的元素时,为该元素添加浅灰色背景。
结构化伪类
结构化伪类可以根据标记的结构应用样式,比如根据某元素的父元素或前面的同胞元素是什么。
(1) :first-child 和:last-child
e:first-child
e:last-child
:first-child 代表一组同胞元素中的第一个元素,而:last-child 则代表最后一个。
比如,把下面的规则
ol.results li:first-child {color:blue;}
应用给以下标记:
<ol class="results">
<li>My Fast Pony</li>
<li>Steady Trotter</li>
<li>Slow Ol' Nag</li>
</ol>
文本“My Fast Pony”就会变成蓝色。
(2) :nth-child
e:nth-child(n)
e 表示元素名,n 表示一个数值(也可以使用 odd 或 even)。
例如,
li:nth-child(3)
会选择一组列表项中的每个第三项。
伪元素
顾名思义,伪元素就是你的文档中若有实无的元素。
(1) ::first-letter 伪元素
e::first-letter
比如,以下 CSS 规则:
p::first-letter {font-size:300%;}
可以得到段落首字符放大的效果。
(2) ::first-line 伪元素
e::first-line
可以选中文本段落(一般情况下是段落)的第一行。
p::first-line {font-variant:small-caps;}
可以把第一行以小型大写字母显示。
(3) ::before 和::after 伪元素
以下两个伪元素
e::before
e::after
可用于在特定元素前面或后面添加特殊内容。
以下标记
<p class="age">25</p>
和如下样式
p.age::before {content:"Age: ";}
p.age::after {content:" years.";}
能得到以下结果:
Age: 25 years.
继承
body 是所有元素的老祖宗,所有标签都是它的后代。那么由于 CSS 继承的约定,如果我们为 body 像下面一样写一条规则
body {font-family:helvetica, arial, sans-serif;}
那么,文档中的所有元素,无论它在层次结构中多么靠下,都将继承这些样式,以 Helvetica 字体(或者在 Helvetica 字体无效时以其他字体代替)显示各自包含的文本。继承给我们带来的效率是显而易见的,全站的主字体只要在某个上层元素上指定即可,无须在每一个标签上分别指定。而对于个别想使用不同字体的元素,只要个别设定 font-family 属性就好了。
CSS 中有很多属性是可以继承的,其中相当一部分都跟文本有关,比如颜色、字体、字号。然而,也有很多 CSS 属性不能继承,因为继承这些属性没有意义。这些不能继承的属性主要涉及元素盒子的定位和显示方式,比如边框、外边距、内边距。
层叠
层叠,就是层叠样式表中的层叠, 是一种样式在文档层次中逐层叠加的过程,目的是让浏览器面对某个标签特定属性 值的多个来源,确定最终使用哪个值。
样式来源
浏览器层叠各个来源样式的顺序:
- 浏览器默认样式表
- 用户样式表
- 作者链接样式表(按照它们链接到页面的先后顺序)
- 作者嵌入样式
- 作者行内样式
浏览器会按照上述顺序依次检查每个来源的样式,并在有定义的情况下,更新对每个标签属性值的设定。整个检查更新过程结束后,再将每个标签以最终设定的样式显示出来。
层叠规则
- 层叠规则一:找到应用给每个元素和属性的所有声明。浏览器在加载每个页面时,
都会据此查到每一条 CSS 规则,标识出所有受到影响的 HTML 元素。
- 层叠规则二:按照顺序和权重排序。浏览器依次检查 5 个来源,并设定匹配的属性。 如果匹配的属性在下一个来源也有定义,则更新该属性的值,如此循环,直到检查完页面中所有标签受影响属性的全部 5 个来源为止。最终某个属性被设定成什么值, 就用什么值来显示。声明也可以有权重。可以像下面这样为单独的声明增加权重:
p {color:green !important; font-size:12pt;}
空格!important 分号(;)用于加重声明的权重。
- 层叠规则三:按特指度排序。除了有点拗口之外,特指度(specificity)其实表示一条规则有多明确。
如果某个样式表中包含如下规则:
p {font-size:12px;}
p.largetext {font-size:16px;}
那么下面的段落
<p class="largetext">A bit of text</p>
将显示 16 像素高的文本,因为第二条规则的选择符既包含标签名,也包含类名,所以意义更明确(特指度更高),结果第二条规则会覆盖第一条规则中的同名属性。
类名选择符比普通的标签选择符具有更高的特指度。
简单层叠要点
- 规则一:包含 ID 的选择符胜过包含类的选择符,包含类的选择符胜过包含标签名的选择符。
- 规则二:如果几个不同来源都为同一个标签的同一个属性定义了样式,行内样式胜过嵌入样 式,嵌入样式胜过链接样式。在链接的样式表中,具有相同特指度的样式,后声明的胜过先声明的。
规则一胜过规则二。换句话说,如果选择符更明确(特指度更高),无论它在哪里,都会胜出。
- 规则三:设定的样式胜过继承的样式,此时不用考虑特指度(即显式设定优先)。
规则声明
CSS 属性值主要分以下三类。
文本值。例如,font-weight:bold 声明中的 bold 就一个文本值。文本值也叫做关键字。
数字值。数字值后面都有一个单位,例如英寸或点。在声明 font-size:12px 中,12 是数字值,而 px 是单位(像素)。如果数字值为 0,那么就不用带单位了。
颜色值。颜色值可以用几种不同的格式来写,包括 RGB(Red, Green, Blue,红绿蓝)、 HSL(Hue, Saturation, Luminance,色相,饱和度,亮度)和十六进制值(例如 color:#336699)。
文本值
所有 CSS 属性都有文本值。例如,visibility 属性有 visible 和 hidden 值, border-style 属性有 solid、 dashed 以及 inset 值。
除了上面两个属性外,还有很多属性可以使用文本值,但那些值都是特定于属性的。
数字值
数字值用于描述元素的各种长度(在 CSS 里,“长度”的含义比较广,还包括高度、 宽度、粗细,等等)。数字值主要分两类:绝对值和相对值。
绝对值描述的是一个真实的长度(比如,6 英寸),而相对值则是相对于其他基准的描述(比如“是某某的两倍长”)。
百分比非常适合设定被包含元素的宽度,此时的百分比就是相对于宽度而言的。把 HTML 结构元素的宽度设定为 body 宽度的百分比,是“流式”设计的 关键所在。这种布局设计可以随着用户调整浏览器窗口大小而成比例地伸缩。
颜色值
指定颜色值可以有几种方式。这些方式可以在同一个样式表中混合使用。
(1) 颜色名(如 red)
设定颜色属性时可以直接使用颜色名,或者用官方术语就是颜色关键字。一般来说,颜色关键字最常用于指定白色和黑色。对于其他颜色真的很较真儿的场合,还得使用以下几种格式的颜色值。
(2) 十六进制颜色(#RRGGBB 或#RGB)
十六进制颜色的值的格式如下:
#rrggbb
例如橙色是:
#ff8800
这个 6 位数的前两位定义红色,中间两位定义绿色,后两位定义蓝色。