2.4 ID和类选择符

ID和类为我们选择元素提供了另一套手段,利用它们可以不用考虑文档的层次结构。只要你在HTML标记中为元素添加了idclass属性,就可以在CSS选择符中使用ID和类名,直接选中文档中特定的区域。

可以给idclass属性设定任何值,但不能以数字或特殊符号开头。

2.4.1 类属性

类属性就是HTML元素的class属性,body标签中包含的任何HTML元素都可以添加这个属性。下面这段代码展示了HTML class属性的用法。

  1. <h1 class="specialtext">This is a heading with the <span>same class</span> as the second paragraph.</h1>
  2. <p>This tag has no class.</p>
  3. <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展示了这段代码的显示结果。

enter image description here图2-14 应用默认样式的效果

注意,我已经给其中两个标签添加了specialtext类。

1. 类选择符

  1. .类名

注意,类选择符前面是点(.),紧跟着类名,两者之间没有空格。

类选择符就是在HTML类名前面加一个点(英文句号)。

好,我们来为标签应用如下CSS样式。

  1. p {font-family:helvetica, sans-serif; font-size:1.2em;}
  2. .specialtext {font-style:italic;}

图2-15展示了应用样式后的效果。

enter image description here图2-15 两个段落中文本的字体都变成了Helvetica,而标题和第二个段落都有specialtext类,所以都变成了斜体

应用这两条规则的结果,就是两个段落都以Helvetica字体(如果本地没有该字体则使用浏览器通用的无衬线字体)显示,而带有specialtext类的段落同时也变成了斜体。h1中的文本仍然使用浏览器默认字体(一般是Times),因为Helvetica字体只应用给段落,不过由于它也有specialtext类,所以也应用了斜体。 另外,没有默认样式的span,由于我们没有明确为其添加样式,所以就继承了其父元素的样式。

2. 标签带类选择符

如果你只想瞄准带有这个类的段落,可以把标签名和类选择符写在一块,比如:

  1. p {font-family:helvetica, sans-serif; font-size:1.2em;}
  2. .specialtext {font-style:italic;}
  3. p.specialtext {color:red;}

如图2-16所示,第三条CSS规则只选择带specialtext类的段落。像这样组合标签名和类选择符,可以让你更精确地选择特定的标签。

enter image description here图2-16 通过组合标签名和类选择符,可以让选择符更具体

下面我们就把这个技巧进一步发挥一下。

  1. p {font-family:helvetica, sans-serif; font-size:1.2em;}
  2. .specialtext {font-style:italic;}
  3. p.specialtext {color:red;}
  4. p.specialtext span {font-weight:bold;}

如图2-17所示,单词“regardless”变成了粗斜体,因为包含它的span位于一个带有specialtext类的段落中。这四条规则全都会对span产生影响,因为它从其父元素,那个带specialtext类的段落那里,继承了前三条规则的样式。我们已经两次提到了继承,关于继承我们放在本章后面再详细介绍。

enter image description here图2-17 再添加一个选择符,可以把选择目标锁定为更特殊的元素

3. 多类选择符

可以给元素添加多个类,比如:

  1. <p class="specialtext featured">Here the span tag <span>may or may not</span> be styled.</p>

多个类名,如这里的specialtextfeatured,放在同一对引号里,用空格分隔。实际上,更准确的说法,就应该是HTML的class属性可以有多个空格分隔的值。要选择同时存在这两个类名的元素,可以这样写:

  1. .specialtext.featured {font-size:120%;}

注意,CSS选择符的两个类名之间没有空格,因为我们只想选择同时具有这两个类名的那个元素。如果你加了空格,那就变成了“祖先/后代”关系的上下文选择符了。

每个类名分别用一个HTML class属性的做法是常见的错误,正确的做法是像上面的代码那样,只用一个class属性,但给它设定多个值。本章后面还会讲到多类名的实际用法。

2.4.2 ID属性

ID与类的写法相似,而且表示ID选择符的#(井号)的用法,也跟表示类选择符的.(句号)类似。

如果有一个段落像下面这样设定了ID属性

  1. <p id="specialtext">This is the special text.</p>

那么,相应的ID选择符就是这样的:

  1. #specialtext {CSS样式声明}

或者这样的:

  1. p#specialtext {CSS样式声明}

除此之外,ID与类的用法都一样,而且我们前面讨论的关于类选择符的(几乎)一切,都适应于ID选择符。那两者到底有什么区别呢?

用于页内导航的ID

ID也可以用在页内导航链接中。下面就是一个链接,其目标是同一页的另一个位置。

  1. <a href="#bio">Biography</a>

看到href属性值开头的#了吗?它表示这个链接的目标在当前页面中,因而不会触发浏览器加载页面(如果没有#,浏览器就会尝试加载bio目录下的默认页面了)。

使用与CSS选择符里相同的 #ID名语法,可以把链接导航到同一页面中的目标ID。在这个页面的下方,应该有对应的目标元素。

  1. <h3 id="bio">Biography</h3><p>I was born when I was very young…</p>

同样要注意,作为目标的ID值前面是没有#的,就是一个普通的ID值。

用户单击前面的链接时,页面会向下滚动到ID值为bioh3元素的位置。如果链接的href属性里只有一个#,那么点击该链接会返回页面顶部。

  1. <a href="#">Back to Top</a>

换句话说,要写一个“返回顶部”链接,根本不需要ID为#的目标元素。

另外,如果你暂时不知道某个href应该放什么URL,也可以用#作为占位符,但不能把该属性留空。因为href属性值为空的链接的行为跟正常链接不一样。这样,团队中的其他人将来可以用中间层(比如PHP)变量替换#,以便动态接收来自数据库的URL。

2.4.3 什么时候用ID,什么时候用类

乍一看,类和ID都是用于在标记中标识特定标签的HTML属性,似乎完全是可以相互取代嘛。然而,它们的用途实际上大不相同。

1. 什么时候使用ID

ID的用途是在页面中唯一地标识一个元素。正因为如此,同一个页面中的每一个ID属性,都必须有独一无二的值(名字)。好吧,换一个角度讲,每个ID名在页面中都只能用一次。

  1. <nav id="mainmenu">

也可以使用ID把JavaScript与某个标签关联起来(比如,当用户鼠标移动到一个链接上面时,运行激活动画的脚本)。ID值的唯一性对JavaScript尤其重要,否则就会导致JavaScript行为异常。

在这里,页面中就不能再有其他元素使用mainmenu作为ID名了。为了标识页面的某一部分,比如主导航菜单,可以为nav(navigation,导航)添加一个ID属性,并让它包含菜单元素。

  1. <nav id="mainmenu">
  2. <ul>
  3. <li><a href="#">Yin</a></li>
  4. <li><a href="#">Yang</a></li>
  5. </ul>
  6. </nav>

有了用唯一ID标识的菜单之后,就可以使用上下文选择符来选择其中包含的各种类型的标签了。比如,可以将这个菜单中的链接设置为橙色,同时又不会影响页面中的其他链接:

  1. #mainmenu a {color:orange;}

利用唯一ID,可以在CSS中方便地定位到这个元素,以及它的子元素。到了后面读者会发现,我经常会给页面中每个顶级区域都添加一个ID,从而得到非常明确的上下文,以便编写CSS时只选择嵌套在相应区域内的标签。

差不多了吧,你已经理解了ID表示的是页面中一个唯一的HTML元素,下面就来聊一聊什么时候使用类吧。

2. 什么时候使用类

类的目的是为了标识一组具有相同特征的元素,比如本章前面例子中的那个specialtext类。

在下面这个孩子名字的列表中,我想把男孩的名字变成蓝色,把女孩的名字变成粉红色。首先,我用类在标记中标识出了性别。

  1. <nav>
  2. <ul>
  3. <li class="boy"><a href="#">Alan</a></li>
  4. <li class="boy"><a href="#">Andrew</a></li>
  5. <li class="girl"><a href="#">Angela</a></li>
  6. <li class="boy"><a href="#">Angus</a></li>
  7. <li class="girl"><a href="#">Anne</a></li>
  8. <li class="girl"><a href="#">Annette</a></li>
  9. </ul>
  10. </nav>

然后,再用CSS为链接应用颜色:

  1. .boy a {color:#6CF;}/*蓝色*/
  2. .girl a {color:#F9C;}/*粉红色*/

第一条规则选择所有类名为boy的祖先元素包含的a元素,第二条规则选择所有类名为girl的祖先元素包含的a元素。这两种情况下的祖先元素,都是作为相应链接父元素的li元素。

不要乱用类

要避免Web开发专家Jeffrey Zeldman说的“类泛滥——标记中的麻疹”出现。什么意思呢?就是说你不要像使用ID一样,每个类都指定一个不同的类名,然后再为每个类编写规则。如果你确实有这种随意使用类的习惯,那说明你可能像大多数对CSS充满激情的初学者一样,还不了解继承和上下文选择符的作用。于是,你可能会给每个标签都重复写同样的样式(比如为页面中很多标签分别指定相同的字体)。实际上,继承和上下文选择符能让不同的标签共享样式,从而降低你需要编写和维护的CSS量。

2.4.4 ID和类的小结

ID的用途是在页面标记中唯一地标识一个特定的元素。它能够为我们编写CSS规则提供必要的上下文,排除无关的标记,而只选择该上下文中的标签。

相对来说,类是可以应用给任意多个页面中的任意多个HTML元素的公共标识符,以便我们为这些元素应用相同的CSS样式。而且,使用类也让为不同标签名的元素应用相同的样式成为可能。