CSS 中的 :target
伪选择器在 URL 中的哈希值和元素的 ID 相同时匹配。

<section id="voters">
Content
</section>
:target {
background: yellow;
}
只要 URL 保持不变,该 section
元素就会根据我们的 CSS 具有黄色背景。
您将在何时使用此功能?
一种可能性是,当您需要使用“状态”进行样式设置时。 当页面具有特定哈希值时,它就处于该状态。 它不像操作类名那样灵活(因为只能有一个哈希值,并且它只能与一个元素相关联),但它们类似。 在元素处于 :target
状态时,您可以在更改类名以更改状态时执行任何操作。 例如:更改颜色、更改位置、更改图像、隐藏/显示内容,等等。
我会使用以下经验法则来判断何时 :target
是一个不错的选择。
- 当需要“状态”时
- 当向下跳转的行为可以接受时
- 当可以影响浏览器历史记录时
我们将在本文中介绍所有这些内容。
如何在 URL 中添加哈希值?
最常见的方法是用户单击包含哈希值的链接。 可以是内部(同页面)链接,也可以是完全限定的 URL,该 URL 恰好以哈希值和值结尾。 例如
<a href="#voters">Go To There</a>
<a href="http://example.com/#specific-part">Go To There</a>
跳转行为
无论是否是同页面链接,浏览器的行为都是滚动页面,直到该元素位于页面顶部。 或者,如果无法滚动到那么远,则尽可能地滚动。 这点非常重要,因为这意味着利用这种“状态”行为有点棘手/有限。
例如,我曾经 尝试过各种技术 来复制功能性 CSS 选项卡,但最终决定使用 复选框技巧 是一个 更好的主意,因为它避免了页面跳转问题。 CSS Science 的 Ian Hansson 也提供了一些 选项卡示例。 他的第三个示例使用 :target
,以及绝对定位的元素,这些元素隐藏在页面顶部上方,以防止页面跳转行为。 这个方法很巧妙,但并不是真正的解决方案,因为如果选项卡位于页面更下方,则页面会向上跳转。 锚点实际上是固定位置的,这意味着它们会随着页面滚动而滚动,并且不会出现顶部跳转行为。 非常巧妙!
完美用法:突出显示部分
问题:当哈希链接将您快速滚动到页面上的相关部分时,它会尝试将该部分紧贴到浏览器窗口的顶部。
但是,如果该部分下方没有足够的滚动空间怎么办? 该部分将可见,但不会紧贴顶部,这可能会让人感觉奇怪和令人困惑。

我可不是在信口开河。 根据个人经验,页面跳转链接不会将我带到我所链接到的位置的顶部,我就会感到十分困惑。 我发现这种情况在 FAQ 页面上经常发生,因为链接到的部分通常不太高。
所以,让我们解决这个问题!
一种历史方法称为 黄色淡出技巧。 37signals 在页面中添加新内容的情况下采用了这种方法,他们试图吸引用户注意新内容。 Jonathan Snook 将这个想法移植到了 CSS 中,并将其与 :target
相结合。
我们不会使用黄色淡出,而是通过将部分向右轻轻推动并闪烁红色边框来指示我们刚刚单击的链接所引用的部分。 我们不会让你觉得,你已经到达了这里。
该结构是导航的一部分,它通过 ID 链接到各个部分。
<nav>
<a href="#one">1</a>
<a href="#two">2</a>
<a href="#three">3</a>
</nav>
<section>
<div id="one"><h2>One</h2>Pellentesque habitant morbi ...</div>
<div id="two"><h2>Two</h2>Pellentesque habitant morbi ...</div>
<div id="three"><h2>Three</h2>Pellentesque habitant morbi ...</div>
</section>
当部分变为 :target
时,它们会通过 translateX
变换稍微向右移动(防止出现任何奇怪的文本换行或我们在使用填充时可能遇到的任何问题),并且通过关键帧动画闪烁红色边框。
:target {
animation: highlight 1s ease;
transform: translateX(20px);
}
@keyframes highlight {
0% { border-left-color: red; }
100% { border-left-color: white; }
}
section > div {
border-left: 40px solid white;
padding: 10px;
transition: all 0.5s ease;
padding-right: 50px;
margin-left: -20px;
}
实际上,这就是全部内容。 如果您担心浏览器支持,我会将其归类为渐进增强。 也就是说,这只是一个不错的功能,不是必需的功能。
解决跳转问题!
假设您喜欢使用 :target
来实现状态,但不喜欢页面跳转行为,您可以在不跳转页面的情况下更改 URL 中的哈希链接。
使用 jQuery,您可以定位所有哈希链接,阻止其默认行为,并使用 pushState(或者 replaceState,我认为)来更改 URL(这不会移动页面)。
$("a[href^=#]").on("click", function(e) {
e.preventDefault();
history.pushState({}, "", this.href);
});
您也可以在那里互换使用 replaceState
,这会更改 URL,但不会在浏览器历史记录中添加条目。 有时您可能想要这样做,有时您可能不想要。 至少在这里您可以选择,而默认情况下单击哈希链接则不行,因为哈希链接总是添加条目。
但是,有一个坏消息
当 URL 更改为新的哈希值时,您可能会认为当前的目标会更改,并且新的 CSS 会生效。 但事实并非如此(在撰写本文时已测试了当前的 WebKit 和 Firefox)。 这是一个错误。
从理论上讲,您可以测量并保存页面当前的滚动位置,让链接自然移动,然后将其设置回原来的位置。 但这听起来太糟糕了,我甚至无法强迫自己为它创建一个测试页面。
更多
- Selectors Level 4 中的规范(与上面的内容没有重大区别)。
- 仅使用 CSS 和 :target 选择器创建简单的图像库(存在页面跳转问题,这是一个很好的示例)。
- 黄色淡出技巧演示(尽管用于现有内容,而不是新添加的内容)。
- Caleb Ogden 的一个 CSS 目标,名副其实。(现在已离线,但 Wayback Machine 拥有一个损坏的版本。)。
您通常会在其他文章中提到的浏览器兼容性信息不见了。 何时可以使用这种技术,它是否可以优雅降级?
您可以在所有现代浏览器和 IE9+ 中使用它。 但 IE 存在一个问题。
来自 quirksmode 页面
我之前使用过这种方法来创建纯 CSS 点击式幻灯片。 效果很好。 http://sitesbypalmer.com/themes/contrast/portfolio
无关紧要:我喜欢您的照片。
关于 CSS Science 标签示例,将隐藏元素设置为“position: fixed;” 能解决跳转问题吗?因为它们将始终位于视窗内?
很聪明。尝试做个演示吗?
我有点困惑 - CSS Science 页面不是已经对第三个示例使用了“position:fixed;” 吗?据我所知没有跳转问题。
啊,是的,检查他的示例后发现,实际上 span 元素使用了“position: fixed;”。
我已经创建了一个关于此的演示:http://jsfiddle.net/pq9hx/1/embedded/result/
(非常非常基础的演示!)
等等,这不会让 pushState/replaceState 技术在目前无法使用(也许在这些浏览器的错误版本存在时也无法使用)吗?
呃,虽然根据错误报告,使用 location.hash 是有效的,但我目前不太清楚它与 pushState 或 replaceState 的区别。
(奇怪的是,Paul Irish 似乎在今天早些时候就报告了这个错误。哦,Paul Irish,总是领先我们一步。)
我以前在任何代码后使用“return false;” 来阻止页面跳转。例如(这发生在我开始使用 jQuery 之前),每当我有一个 onclick 事件时,我都会将 href 设置为“#”,这会导致页面跳转。如果我在 javascript 代码后添加“return false;”,它就不会执行该操作(onclick=”example(‘test’); return false;”)。不过我不确定它是否会导致其他问题,在我使用时似乎没有问题。
关于 target 的精彩文章,之前我在遵循这些教程时使用过它 http://webstutorial.com/css3-tabs/css3 和 http://webstutorial.com/html5-css3-toggle-slideup-slidedown/html-5
之前的教程 + 你的教程让我成为了 :target 的专家。
谢谢 Chris
不久前我看到一个 jQuery 插件,它可以让您从另一个网站访问示例页面,并在链接中包含 #hash 时,它会停止自动“立即将您拉到页面底部”的操作,而是从页面顶部平滑滚动到该元素。因此,从其他网站访问的人点击指向您网站页面中间的链接时,会更容易找到方向。
不过它并没有真正起作用,它似乎仍然会跳转。我想知道是否有人知道如何使用 jQuery(正确的方法)来实现这一点。我认为你可能在本文中提到了类似的事情,但我对 jQuery 不太擅长,所以我不太清楚。
我从未见过有人正确地做到这一点,也许它并不值得?
我不确定你是否想到了我的示例,因为它不会跳转,它确实是滚动:http://osvaldas.info/incoming/examples/more-noticeable-html-bookmarks/#bookmark (文章)
另一种变体:我最近做了一个小型演示,使用 :target 在较小的设备上隐藏“画布外”的内容。请看 http://sandbox.webpro.nl/css3/adaptive-layout-pattern-off-canvas-variation.html(使用较小的宽度查看效果)。
有趣的是,我昨天做了一件事,过度地使用了 :target 选择器。我建议在 Opera 中查看它,因为在我的测试中,它是在 transform: scaleY 上支持过渡的唯一浏览器。
http://www.informatik.uni-freiburg.de/~dufners/gryth
我赞同使用
position: fixed
来防止页面在:target
上跳转。我在弹出窗口中使用了它 - http://kizu.ru/en/fun/popups/几个月前我玩过 :target http://rkrupinski.com/stuff/target/
我一直想知道它到底做了什么。
现在我的脑海里充满了使用 :target 选择器的怪异作品!
哈哈哈!!!
嗨!
我几个月前在 http://creativejuiz.fr/trytotry/juizy-slideshow-full-css3-html5/ 上玩过 :target,我将通用兄弟选择器与 :target 伪类结合在“隐藏”元素中(查看源代码)。它起作用了!没有跳转!
还可以查看使用 :target 伪类和过渡制作的 CSS3视差效果:http://www.creativejuiz.fr/trytotry/css3-parallax/
感谢您的文章;)
在文章中,您提到我的(CSS Science 上的)示例,如果标签位于页面更下方,则无法正常工作。
使用 :target 选择的元素都具有 position fixed 属性,所以这不会产生影响。我故意让页面很长,这样您就可以向下滚动一点并检查一下。
这真是太酷了。对于博客和知识库非常有用。
这个教程很有趣,它使用的是 CSS 动画。我知道并非所有浏览器都支持 CSS 动画,但我喜欢它。使用 CSS 动画可以吗?
读完这篇文章后,我想知道是否可以使用 :target 创建一个纯 CSS 模态窗口(我已经看到过几个例子,但没有一个是使用 :target 的)。事实证明你可以…
http://jsfiddle.net/leonard_mcginty/SzhLq/
我没有对其进行大量的测试,当然它在通常的浏览器中会崩溃并烧毁,但实验总是很有趣的。
像往常一样,Coyier 先生的提示很棒 :-)
感谢您的数据,有很多东西要学,我之前没有听说过“:target”。跟上所有事情太难了。
我很高兴我发现了这个脚本,我原本打算在两天内将一堆 target 链接添加到我正在开发的网站中,而这种方法将使最终结果非常棒。
我非常兴奋,希望我脑海中的 WebKit 动画能够在较旧的浏览器中很好地降级…
嗨!
我使用您的技术做了一个实验,让我们看看吧!
http://cssdeck.com/item/307/animated-list-with-target
嗨 Chris,
读完这篇文章后,我玩了一下 :target。它运行得很好,除了在较旧的 IE 中,当然。
我以前在任何代码后使用“return false;” 来阻止页面跳转。例如(这发生在我开始使用 jQuery 之前),每当我有一个 onclick 事件时,我都会将 href 设置为“#”,这会导致页面跳转。如果我在 javascript 代码后添加“return false;”,它就不会执行该操作(onclick=”example(‘test’); return false;”)。不过我不确定它是否会导致其他问题,在我使用时似乎没有问题。
如何使用 javascript:void() 来避免页面跳转行为?我这样使用它 href=”javascript:void()”
我在几个针对现代浏览器的项目中使用过 :target 伪类。最近,我实际上使用它来创建纯 CSS 手风琴。
当然,我知道 jQuery 可以实现手风琴,而且 HTML5 有
summary
和details
。但summary
和details
的浏览器支持范围并不广,而 :target 几乎支持所有现代浏览器,包括 IE9。所以,如果您发现自己处于这样一种情况,即非常大的公司客户不希望您使用 JS 库,但他们可以使用 CSS3(是的,这种情况确实发生在我身上),那么这是一种值得考虑的方法。我写了一篇关于这种方法的博客文章。
http://blog.frankmtaylor.com/2012/04/17/clever-css-tricks-using-target-to-create-accordions/
Chris,我认为我已经解决了你在“与跳转作斗争!”中描述的问题。
不使用 pushState/replaceState,而是使用 location.hash 和 location.replace 分别更新哈希值。这些机制将正确地重新评估 CSS,绕过 WebKit/Gecko 的错误。
我在这里写了一篇博客文章
http://www.zachleat.com/web/moving-target/
哎呀,没关系 - 这不是与跳转作斗争的解决方案。抱歉 Chris!
我一直在思考非 JS 弹出窗口的想法(一位同事问我是否可行),在研究的过程中,我偶然发现了你的这篇文本。我之前读到过滚动跳跃不可避免,这让我很沮丧,但我还是开始尝试这样做。最终,我找到了解决方法,你可以在这里看到:http://laboratorium.krazov.com/css-pop-up/。当然,它也有一些缺陷,但这只是为了娱乐而已。
(我在完成之后注意到了评论,很可能我的评论并没有展示什么新东西。)