CSS 的主要优势之一就是可以为同类型的所有元素应用一组样式,这是通过选择符实现的。

样式基本规则

元素选择符

元素选择符通常是 HTML 元素。而在 XML 中,什么都可以作为选择符。

  1. html { color: black; }
  2. h1 {color: gray;}
  3. h2 {color: sliver;}

声明和关键字

  • 声明块包含一个或多个声明
  • 声明形式:属性: 值;。冒号之后可以有零或多个空格
  • “值”几乎都是一个关键字或以空格分隔的多个关键字
  • 声明的属性和值无效,导致整个声明无效
  1. /I* 无效声明 */
  2. brain-size: 2cm; /* 属性无效 */
  3. color: ultraviolet; /* 值无效 */
  1. /* 用空格分隔的多个关键字 */
  2. p {font: medium Helvetica;}

当某个属性值是由多个关键字组成的,关键字之间通常以空格分隔。在 CSS 2.1 中有个特例,就是 font 属性,其值有一处要使用斜线(/)把两个关键字分开。

  1. h2 {font: large/150% sans-serif;}

此外,其他在属性值中可使用斜线的属性包括(不完整):

  • background
  • border-images
  • border-raduis
  • grid
  • grid-area
  • grid-column
  • grid-row
  • grid-template
  • mask-border

举例子:

  1. .box {box-shadow: inset -1px -1px white,
  2. 3px 3px 3px rgba(0, 0, 0, .2);
  3. background-image: url(myimage.png),
  4. line-gradient(180deg, #fff 0%, #000 100%);
  5. transform: translate(100px, 200px);
  6. }
  7. a:hover {transition: color, background-color 200ms ease-in 50ms;}

群组

接下里学习:如何把同一个样式应用到多元素上;如何同时为一个或多个元素应用多个样式。

群组选择符

如何把同一个样式应用到多元素上呢?就要使用群组选择符了——选择符部分,用逗号来分隔需要选择的多个元素。

  1. h2, p {color: gray;}
  2. /* 等效于 */
  3. h2 {color: gray;}
  4. p {color: gray;}

通用选择符

通用选择符(universal selector)用星号(*)标识,匹配所有元素,是 CSS2 引入的。

  1. * {color: red;}

群组声明

一个声明可以中可以包含多个选择符,同时,也可以有多个声明。也就是用 {} 括起来的声明块。

  1. h1 {font: 18px Helvetica; color: purple; background: blue;}
  2. /* 等价于 */
  3. h1 {font: 18px Helvetica;}
  4. h1 {color: purple;}
  5. h1 {background: blue;}

二者结合

将群组选择符与群组声明结合起来使用。

  1. h1, h2, h3, h4, h5, h6 {color: gray; background: white; padding: .5em;
  2. border: 1px solid black; font-family: Charcial, sanss-serif;}

在 IE8- 浏览器中使用新元素

在 IE9 之前的浏览器,无法选择 HTML5 规范中新加入的元素。因为浏览器在这些新元素出现之前就已存在,因此无法识别新的元素。

例如,IE8 不识别

元素,使用下面的 JS 可以让它知道 main 的存在:

  1. document.createElement('main');

类和 ID 选择符

类和 ID 选择符能以一种独立于元素的方式赋予样式。

类选择符

在元素上使用 class 属性,在 CSS 中,类选择符句法是在 class 属性值之前加点号(.)。

  1. <p class="warning">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  2. <style>.warning {font-weight: bold;}</style>

这里将 p 段落文字加粗。

同一个类名,为不同元素应用各自样式:

  1. p.warning {font-weight: bold;}
  2. span.warning {font-style: italic;}

用类选择符定义通用样式,再用元素选择符,指定特定样式:

  1. .warning {font-weight: bold;}
  2. span.warning {font-style: italic;}

多个类

根据 HTML 规范,class 属性值可以是多个词,词之间用空格分隔。这样就可以为元素同时应用多个类的样式了。

  1. <p class="warning urgent">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  2. <style>
  3. .warning {font-weight: bold;}
  4. .urgent {font-style: italic;}
  5. .warning.urgent {background: sliver;}
  6. </style>

.warning.urgent 表示如果一个元素同时包含 warning 和 urgent 类名时使用样式。与之前两个类中单独声明的样式合在一起,结果就会呈现出一个银色背景、粗斜体文字显示的段落了。

ID 选择符

ID 选择符与类选择符类似,不过是以井号(#)开头的。

  1. <p id="lead-para">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>
  2. <style>#lead-para {font-weight: bold;}</style>

在每个文档中,id 值是唯一的。如果同时出现多个使用同一 id 值的元素,是无法预知会匹配这些元素中的哪一个。

使用类还是 ID 选择符?

  • 元素个数:
    • 类选择符可以赋予任意个元素。即同一个类名可以在多个元素的 class 属性值中使用。
    • ID 选择符只能赋予一个元素。因为在一个 HTML 文档中,一个 ID 能且只能使用一次。
  • 是否可串在一起:
    • 类选择符能串在一起使用
    • ID 选择符不能串在一起使用
  • 权重
    • ID 选择符的权重更高。
  • 区分大小写
    • 这一点,类选择符与 ID 选择符一样,都是区分大小写的。即 class=”warning’ 和 class=”Warning”、id=”para” 和 id=”Para” 是不同的。

属性选择符

类和 ID 选择符,选择的都是属性的值。为了扩展到其它的标记语言,CSS2 引入了属性选择符(attribute selector)。分四类:

  • 简单属性选择符
  • 精准属性值选择符
  • 部分匹配属性值选择符
  • 起始值属性值选择符

下面一一来介绍。

简单属性选择符

即选择具有某个属性的元素,属性包含在方括号([])中。

  1. // 将所有具有 class 属性的 h1 标签的文本色设置为银色
  2. h1[class] {color: sliver;}

还可以基于多个属性选择。

  1. // 将具有 href 和 title 属性的所有 a 标签文本设置为粗体显示
  2. a[href][title] {font-weight: bold;}

精准属性值选择符

进一步缩写范围,只选择特定属性值的元素。

  1. a[href="http://www.w3.org"] {font-weight: bold;}

也可以基于属性值来选择元素。

  1. a[href="http://www.w3.org"][title="W3C Home"] {font-size: 200%;}

注意,属性值选择符是区分大小写的,匹配元素要与其完全一致才能选中。大小写不一致,或者词序不一致,都不会选中。

部分匹配属性值选择符

我们还可以根据属性值的一部分来选择元素。CSS 为我们提供了多种方式,见下表。

方式 说明
[foo|=”bar”] 具有 foo 属性,且属性值以 bar 或 bar- 开头
[foo~=”bar”] 具有 foo 属性,且属性值中包含 bar 这个词(以空格分隔)
[foo*=”bar”] 具有 foo 属性,且属性值中包含子串 bar
[foo^=”bar”] 具有 foo 属性,且属性值以 bar 开头
[foo$=”bar”] 具有 foo 属性,且属性值以 bar 结尾

下面举例:

  1. // 匹配属性值以 en 或 en- 开头的元素
  2. [land="en"] {color: white;}
  3. // 匹配以空格分隔的一组词中的一个
  4. p[class~="warning"] {font-weight: bold;}
  5. // 匹配属性值的子串
  6. span[class*="cloud"] {font-style: italic;}
  7. // 匹配以特定值开头的元素
  8. a[href^="https:"] {font-weight: bold;}
  9. // 匹配以特定值结束的元素
  10. a[href$=".pdf"] {font-weight: bold;}

忽略大小写标识符

之前有提到过,属性值匹配是区分大小写的,CSS Selector Level 4 为属性选择符引入了一个忽略大小写标识符 i,如此使用:

  1. a[href=".PDF" i] {...}

上面讲到的所有属性选择符都可以使用这个标识符。

不过需要注意的是,i 标识符针对的是属性选择符中的值,而不包括 CSS 规则中的元素和属性本身。比如,在 XML 或 XHTML 中就不会生效。

  1. <style>
  2. /* XML 下,元素和属性句法区分大小写,所以此样式不会被应用 */
  3. .planet[type*="rock" i] {font-weight: bold;}
  4. </style>
  5. <div class="planet" TYPE="dusty rock">Mars</div>

不过,因为 HTML5 是不区分元素和属性大小写的,没有这方面的顾虑,不过还是鼓励都是用小写。

  1. <style>
  2. /* HTML5 中,元素和属性句法不区分大小写,所以此样式会被应用 */
  3. .planet[type*="rock" i] {font-weight: bold;}
  4. </style>
  5. <div class="planet" TYPE="dusty rock">Mars</div>

根据文档结构选择

在介绍更强大的选择符之前,先花点时间讨论文档结构。

理解父子关系

HTML 文档中的元素是一种层次结构。可用树状图来表示。

  1. <html>
  2. <head>
  3. <base href="http://www.meerkat.web/">
  4. <title>Meerkat Central</title>
  5. </head>
  6. <body>
  7. <h1>Meerkat <em>Central</em></h1>
  8. <p>
  9. Welcome to Meerkat <em>Central</em>, the <strong>best meerkat web site
  10. on <a href="inet.html">the <em>entire</em> Internet</a></strong>!</p>
  11. <ul>
  12. <li>We offer:
  13. <ul>
  14. <li><strong>Detailed information</strong> on how to adopt a meerkat</li>
  15. <li>Tips for living with a meerkat</li>
  16. <li><em>Fun</em> things to do with a meerkat, including:
  17. <ol>
  18. <li>Playing fetch</li>
  19. <li>Digging for food</li>
  20. <li>Hide and seek</li>
  21. </ol>
  22. </li>
  23. </ul>
  24. </li>
  25. <li>...and so much more!</li>
  26. </ul>
  27. <p>
  28. Questions? <a href="mailto:suricate@meerkat.web">Contact us!</a>
  29. </p>
  30. </body>
  31. </html>

上面的 HTML 结构,可用下面的树状图里来表示。

image.png

文档中的元素,要么是是一个元素的子元素,要么是一个元素的父元素,或者兼而有之。“父元素”和“子元素”是“祖辈元素”和“后代元素”的特例。对 HTML 文档来说,body 是浏览器中默认显示的所有元素的祖辈,html 元素被称为根元素(root element)。

后代选择符

后代选择符(descendant selector)也叫上下文选择符(contextual selector),使用空格( )作为连接符。

  1. /* 将 h1 中所有 em 元素都设置文本色为灰色 */
  2. h1 em {color: gray;}

再一个例子。为相同类型的元素应用不同的样式。

  1. .sidebar {background: blue;}
  2. main {background: white;}
  3. .sidebar a:link {color: white;}
  4. main a:link {color: blue;}

效果:

image.png

后代选择符对元素距离一无所知,是根据权重来应用样式的。

  1. <style>
  2. div:not(.help) span {color: gray;}
  3. /* 1. 上下声明的权重一样,后者覆盖前者
  4. 并没有因为 .aside 距离 span 更近,.help 距离 span 较远,就显示灰色,而是显示红色
  5. */
  6. div.help span {color: red;}
  7. </style>
  8. <div class="help">
  9. <div class="aside">
  10. <!-- 2. 这里的 <span> 文本最终显示为红色,
  11. 可见,后代选择器对距离一无所知。
  12. -->
  13. This text contains <span>a span element</span> within.
  14. </div>
  15. </div>

子元素选择符

子元素选择符使用大于号(>)连接符连接。

  1. h1 > strong {color: red;}

与后代选择符不同的是,子元素选择符只会选择某个元素下的直接子元素。

紧邻同胞元素选择符

紧邻同胞元素选择符(adjacent-sibling selector)使用加号(+)连接符连接。

  1. h1 + p {margin-top: 0;}

这个选择符的选择条件较为严苛,上述代码的意思是:将紧跟在 h1 元素之后的 p 元素的 margin-top 设置为 0。

注意,两个元素之间的文本不会影响紧邻同胞元素选择符起作用,因为文本节点不是元素节点。

  1. <div>
  2. <ol>
  3. <li>List item 1</li>
  4. <li>List item 1</li>
  5. <li>List item 1</li>
  6. </ol>
  7. This is some text that is part of the 'div'.
  8. <ul>
  9. <li>A list item</li>
  10. <li>Another list item</li>
  11. <li>Yet another list item</li>
  12. </ul>
  13. </div>

这里,如果我使用 ol + ul {...},依然是为 ul 元素指定样式的。

连续后代同胞选择符

连续后代同胞选择符(general sibling selector)使用波浪号(~)连接符连接。

表示选择同属于某个父元素之下的某个元素之后的所有同胞元素。

h2 ~ ol {font-style: italic}; 为例,HTML 结构如下:

  1. <div>
  2. <h2>Subheadings</h2>
  3. <p>It is the case that not every heading can be a main heading. Some headings
  4. must be subheadings. Examples include:</p>
  5. <ol>
  6. <li>Headings that are less important</li>
  7. <li>Headings that are subsidiary to more important headlines</li>
  8. <li>Headings that like to be dominated</li>
  9. </ol>
  10. <p>Let's restate that for the record:</p>
  11. <ol>
  12. <li>Headings that are less important</li>
  13. <li>Headings that are subsidiary to more important headlines</li>
  14. <li>Headings that like to be dominated</li>
  15. </ol>
  16. </div>

最终,h2 之后的两个 ol 都会被选中。

image.png