假设您想将联系页面上的链接颜色更改为红色。 在其他所有页面上,它们都是蓝色的,但出于某种原因,在您的联系页面上将它们改为红色是有意义的。 有几种方法可以实现这一点。
- 您可以为您的联系页面声明一个单独的样式表。 这不是理想的,因为它很冗余。 如果您进行任何其他更改,您将始终需要在主样式表和联系页面样式表上进行更改。
- 您可以在该页面上的所有链接上添加一个唯一的类。 这不是理想的,因为它不是非常语义化,而且也很冗余。 为什么在页面上的每个链接上应用一个类,而它们从上下文角度来看与站点其他地方的链接并没有什么不同?
- 最好的解决方案是为您的 body 元素添加一个唯一的 ID。 这完美地解决了问题。 您可以使用相同的样式表并使用单个 CSS 选择器定位您想要的目标链接。
如何实现
很简单,只需将 ID 应用于 body 标签即可
...
</head>
<body id="contact-page">
...
现在,以将联系页面上的所有链接颜色更改为红色为例,只需使用以下 CSS 代码
a {
color: blue;
}
#contact-page a {
color: red;
}
更实用的例子
您明白了。 这项技术最实用的实现之一是在**导航**中。 看看这个导航示例
您看到论坛选项卡是如何成为“活动”选项卡了吗? 当然,这只是一个 CSS 的微小变化,可能是背景图片位置的微小调整。 XHTML 可能类似于这样
...
<li><a href="/fieldtips">Field tips</a></li>
<li class="active"><a href="/forums">Forums</a></li>
...
应用于列表项的“active”类会改变背景图片。 这将奏效,但是当我们切换到“Field Tips”页面时会发生什么? 我们将不得不从论坛选项卡中删除 active 类,并将其应用于“Field Tips”选项卡。 这很不方便。 这意味着导航块的代码在网站的每个页面上都是唯一的。 所以假设在以后我们想要添加一个“Contact”选项卡,我们将不得不修改每个页面的代码。 没什么乐趣。
让我们更聪明一点。 首先,我们不想在每个页面上都包含导航块代码,我们想要包含它,可能使用一个简单的 PHP 包含,就像这样
<?php include_once("nav.html"); ?>
但是,我们如何将“active”类应用于当前的导航列表元素呢?
这就是我们刚刚学习的将唯一 ID 应用于 body 元素的地方! 而不是仅将类应用于活动列表元素,让我们将唯一类应用于每个单独的列表项,并为我们的 body 元素提供一个唯一的 ID。
...
</head>
<body id="field-tips">
...
<li class="fieldtips"><a href="/fieldtips">Field tips</a></li>
<li class="forums"><a href="/forums">Forums</a></li>
...
现在,我们可以使用一些巧妙的 CSS 定位导航中的特定元素
#field-tips li.fieldtips, #forums li.forums {
background-position: bottom;
}
这意味着导航块的代码可以**在每个页面上保持一致**,但只有该页面特有的导航元素才会受到此 CSS 的影响并“切换”到活动状态。
让我们变得更动态
读者 Brian 在如何使用 PHP 将唯一 ID 应用于 body 元素方面发表了一条很棒的评论
<body id="<?= basename($_SERVER['PHP_SELF'], ".php")?>">
这将返回正在执行的 PHP 文件的名称作为 ID(例如 body id=”index.php”)。 要省略 .php 部分,只需删除“.php”部分即可。
哇,这非常有用,感谢 Chris。
很棒的文章和主题。 具有讽刺意味的是,我今天早上也正好在考虑写关于这个主题的文章。 我被另一个主题吸引了,所以没有写,但有点滑稽。
只有一个词可以形容它:牛逼
谢谢各位!
这对使用不同颜色等来区分网站不同部分的网站来说是一个好技巧。 一个很好的例子是ICWA,我参与维护。
理论上听起来不错,我在静态网站上多次使用过这种技术,但在大型数据库驱动的网站上,作为 UI 专家,我发现后端开发人员不喜欢它,因为它意味着他们不能在整个网站上使用相同的 body 元素代码(例如,使用 .NET 主页)。 也就是说,让他们很好地使用它只需要多做一点点工作(尽管会伴随着很多抱怨和呻吟 :-P)。
…当然,您在 PHP 代码片段中已经对此进行了说明。
您错过了第四个相当明显的选项:像往常一样调用您的通用样式表,然后调用另一个样式表(如果您想以略微不同的方式为一组页面设置样式),或者在文档的 head 中添加一个样式块(如果您只有一个页面),重新定义仅不同的规则。 只要您在调用主样式表后进行此重新定义,您就可以使用与主样式表中相同的特异性。 这利用了级联,不会让您为了更改一两件事而不得不复制整个主样式表,也不意味着您必须启动整个 body ID 东西。
@hank: 是的,在使用任何动态框架的网站上,通常会有一个索引或标题文件,这些文件是网站上所有页面的通用文件。 这意味着将唯一 ID 添加到其中会更加困难,但正如我们都知道的那样,这可以实现 =)
@patrick h. lauke: 是的,这是真的,您可以在原始样式表之后包含一个附加样式表或样式块,它将覆盖在原始样式表中设置的规则。 这件事让我有点困扰,也许这只是我需要克服的个人问题,但我就是不喜欢它。 对我来说,它并不真正“利用级联”,而是声明两个相同的选择器,让它们发生冲突,并让浏览器决定它将遵循哪个。 也许对此有一些规范(可能确实有),但我只是喜欢在 CSS 中更加具体的想法,而不是声明相同的选择器。
chris,说得有道理——并且必须承认,使用我的方法来处理导航示例会变得很麻烦(但对于快速的一次性重新定义,我仍然认为它比尝试将所有特殊情况保留在通用样式表中并使用更具体的页面选择器应用它们要省事)。
作为参考,在规范中明确地将一个样式的某些方面重新声明为后续样式的情况作为级联规则的一部分,因此这不是由浏览器处理的错误处理/冲突。
“4. 按指定的顺序排序:如果两个声明具有相同的权重、来源和特异性,则后指定的声明胜出。”
CSS 2.1 / 6 分配属性值、级联和继承 / 6.4.1 级联顺序
一般来说,如果你有一个网站的通用页眉,你可以在页面的顶部声明页面 ID,并在其下方调用页眉包含。
至少在我的 Cold Fusion 中就是这样做的。
很棒的提示。
使用相同的方式,我们也可以做一些 CSS 的国际化(例如:带有文本的背景图片),例如,我们将使用一个类应用到 body 标签上。
所以,在 body 标签中,你可以为 CSS 的国际化添加一个类,就像这样:
<body id="some_page" class="french">
<h2 class="hello_world">Bonjour le monde !</h2>
或者
<body id="some_page" class="english">
<h2 class="hello_world">Hello world !</h2>
然后在 CSS 中,我们可以做一些事情,比如
h2 {
text-indent: -5000px;
height: 30px;
width: 300px;
background-repeat: no-repeat;
}
.french h2.hello_world { background-image: url(french_hello_world.gif); }
.english h2.hello_world { background-image: url(english_hello_world.gif); }
等等…
之后,开发者可以选择如何动态地改变类,我个人用 PHP 做了一些类似的事情:
<body id="some_page" class="<?php echo $language; ?>">
<h2 class="hello_world"><?php echo $title_hello_world; ?></h2>
这是一个非常古老的技巧 - 我已经使用它很多年了。
为了进一步说明导航示例,如果你为每个 body 标签添加一个类 *和* 一个 id,你可以使用类打开导航的当前部分,并使用 id 突出显示当前页面 - 例如在一个下拉菜单或可扩展导航中。
你也可以使用 body 类来改变网站每个部分的外观。使用多个 body 类,你可以根据网站部分和页面类型(首页、文章、联系表单等)改变外观。
作为一个通用的规则,不要重复使用页面 id:如果你想在多个页面上共享样式,使用类,如果样式对一个页面是唯一的,使用 id。
有趣的是,有人提到他“考虑”过写一篇类似的文章,而我实际上写了 :)
我大部分情况下同意(虽然我不会使用 body id 来设置活动导航项目的样式)。我唯一的建议是使用 id **和** 类,其中 id 定义网站中的一个区域,而类进一步指定这个区域(例如,你可以有两个联系页面,每个页面位于网站的不同区域)。
我写了关于它的文章 这里
好吧,我总是将名为“current”的 ID 放入 <li> 标签中,以显示实际页面的链接,就像这样
<li id="current"><a href="?op=link1">Link 1</a></li>
<li><a href="?op=link2">Link 2</a></li>
<li><a href="?op=link3">Link 3</a></li>
...
为了做到这一点,我有一个 PHP 循环,它遍历所有 LI 标签,并验证链接的目标是否与请求的页面相同 - 由 $op 变量传递。
这对我很有效,因为我所有的链接都定义了一个名为 $op 的变量,用于在主页面内容中包含请求的页面。
(对于我的英语不好,请见谅;只是一个试图学习一些酷炫东西的巴西人 :))
这是一个很棒的技巧,我已经在我的框架中使用它几年了。
除了表示当前页面(类型)的 ID 之外,我还有一些我认为非常有用的类
<body id="home-page" class="rainy morning js-disabled not-logged-in">
我在 JS 中做的第一件事是 $(‘body’).addClass(‘js-enabled’).removeClass(‘js-disabled’); 天气类是从 http://developer.yahoo.com/weather/ 生成的
此外,为了避免在每个导航项目中使用类或 id,我已经开始使用属性选择器
#home-page #navigation a[href=”/”], #about-page #navigation a[href=”/about/”] { /* selected nav styling */ }
当然,依赖 href 属性可能有点不安全,但我是我网站上唯一的开发者,所以对我来说没问题。
我还将 ‘-page’ 添加到 body-id,以避免重复 ID。
好文章!
是的,用这种方法你可以获得更好的控制,
感谢 Chris Coyier 的这个教程
很棒的工作!以前从未玩过 body 标签,迫不及待地想在我的下一个项目中实现它。
你好,我最近从另一个网站上学习了这个技巧,但我有一个问题,也许你能回答… 我有一个主要导航,我通过 body id 技巧对其进行了影响。但在我内页上,我还有另一个子导航,我希望它也能有相同的效果,当点击其中一项时,我希望它在加载新页面时继续突出显示。
有什么想法吗?
@phillip:你可以在子页面的 body 标签中添加类。像
然后使用 ID 控制主导航的突出显示,使用类控制子导航的突出显示。
好文章,但我有一个问题:你如何使用 body 标签中的 ID 来改变 CSS,以改变样式表,就像 http://www.csszengarden.com 那样做?
id=”current” 的技巧是如何工作的?它在没有 body id(或其他 id)、没有 PHP 或 JavaScript 的情况下可以工作吗?
浏览器如何知道哪个是当前页面?
写完这篇文章几年后,我发现它非常有用,让我的生活变得轻松了许多。谢谢你。我在我的 PHP 页眉中使用了它,它与我静态版本中的精灵一起工作得很好。无论如何,如果你看到这条评论,你能告诉我是否自那以后有什么更新吗?再次感谢。
好技巧!但对于动态生成的列表,你会怎么做?让 PHP 生成 CSS 吗?由于我几乎总是需要根据数据库内容生成菜单,所以这不是一个好选择… 我当然也不希望在 HTML 中有 CSS。如果我用 LESS 或 Sass 编译怎么办?或者我是不是遗漏了什么?