锚点跳转是网页中常见的定位方式,但默认情况下用户点击目录链接后,目标区域并不会出现任何视觉反馈,很容易在长页面中迷失位置。利用CSS的:target伪类可以精准捕获当前URL片段标识符指向的元素,再配合::before伪元素在目标内容前方插入提示文字,就能实现不依赖JavaScript的页面提示效果。这种方案代码轻量、响应及时,适合文档目录、FAQ折叠面板以及单页导航等场景。

一、:target伪类的匹配机制与触发条件
:target伪类用于匹配当前URL片段标识符所指向的元素。简单来说,当浏览器地址栏末尾出现类似#section1这样的哈希值时,页面中id属性等于section1的元素就会被:target选中。这个状态不是静态的,每当用户点击新的锚点链接或者手动修改地址栏哈希,浏览器都会重新计算哪些元素命中:target,整个过程不需要任何脚本参与。
触发:target有几个关键条件。首先,目标元素必须具有全局唯一的id属性,因为片段标识符只与id对应,而不是name或class。其次,如果URL中没有哈希部分,那么页面中没有任何元素会处于:target状态。第三,同一时刻最多只能有一个元素被:target选中,因为哈希值本身是唯一的。理解这一点很重要,它意味着你可以放心地为多个区块编写相同的:target样式,但只有当前被定位的那个区块会生效。
下面是一个最基础的示例。HTML结构中有两个导航链接和两个区块,当用户点击链接时,对应区块的背景色和左边框发生变化。
<nav> <a href="#section1">跳转到第一节</a> <a href="#section2">跳转到第二节</a> </nav> <section id="section1">这是第一节的内容</section> <section id="section2">这是第二节的内容</section>
对应的CSS只需要一行选择器即可完成高亮效果。
:target {
background-color: #fff3cd;
border-left: 4px solid #ffc107;
}
这个例子虽然简单,但已经展示了:target的核心价值:将样式与URL状态绑定。与:hover、:focus等状态不同,:target不依赖鼠标悬停或键盘焦点,而是依赖页面地址的哈希部分,因此它能保持状态直到用户离开该锚点,非常适合做页面提示。
二、用::before伪元素注入提示内容
::before伪元素可以在目标元素的实际内容之前插入一段虚拟内容,这段内容通过content属性指定。它不需要修改原有HTML结构,就能在视觉上增加提示文字、图标或装饰线条。当::before与:target组合使用时,选择器写成:target::before,意味着只有当前被锚点定位的元素才会显示这段伪元素内容,其他未被定位的元素不会有任何变化。
下面这段CSS会在目标区块顶部生成一个蓝色的提示条。
:target::before {
content: '当前定位到本节';
display: block;
padding: 8px 12px;
margin-bottom: 10px;
background: #e7f3ff;
border: 1px solid #2196f3;
border-radius: 4px;
font-size: 14px;
color: #0b5cad;
}
这里有几个样式细节值得注意。::before默认是行内元素,如果想让提示条独占一行并形成块状背景,必须设置display: block或者display: inline-block。content属性中的文本可以使用单引号或双引号包裹,但要保证引号成对出现。此外,content的值除了直接写字符串,还可以使用attr()函数读取元素自身的属性值,例如content: attr(data-tip);,这样就能为不同的目标区块配置不同的提示文字,而不必写多套选择器。
如果希望提示条不占用目标区块内部空间,而是悬浮在区块上方或固定在视口顶部,可以配合position: absolute或position: fixed。但要注意,绝对定位需要目标元素自身设置position: relative作为参照,否则提示条会相对于最近的定位祖先或初始包含块定位,位置可能不符合预期。
三、完整示例:带淡入动画的页面提示
综合:target和::before,可以制作一个完整的纯CSS页面提示效果。当用户点击导航链接后,目标区块不仅高亮,还会在顶部淡入显示一条提示文字;当用户跳转到其他锚点或清除哈希后,原来的提示自动消失,无需额外脚本控制。
以下是一个可直接运行的完整示例。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>纯CSS页面提示示例</title>
<style>
body {
font-family: sans-serif;
line-height: 1.6;
padding: 20px;
}
nav a {
margin-right: 10px;
color: #0066cc;
text-decoration: none;
}
section {
margin: 40px 0;
padding: 20px;
border: 1px solid #ddd;
}
:target::before {
content: '您已跳转到本节';
display: block;
padding: 10px 14px;
margin-bottom: 12px;
background: #fff8e1;
border-left: 4px solid #ff9800;
border-radius: 4px;
color: #6d4c00;
animation: fadeIn 0.4s ease;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-6px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
</head>
<body>
<nav>
<a href="#intro">简介</a>
<a href="#api">API说明</a>
<a href="#examples">示例</a>
</nav>
<section id="intro">
这是简介部分的内容。
</section>
<section id="api">
这是API说明部分的内容。
</section>
<section id="examples">
这是示例部分的内容。
</section>
</body>
</html>
动画部分使用@keyframes定义了从透明到不透明、从上方轻微下移的过渡效果。由于:target状态在切换瞬间就会重新计算,动画会在每次目标变化时重新触发,提示条看起来像是每次都重新出现。如果希望提示条不会因为用户快速连续点击而闪烁,可以适当调整动画时长,或者干脆去掉动画只保留静态提示。
这个示例最大的优势在于零JavaScript。所有状态管理都交给浏览器原生完成,代码部署后几乎不需要维护。对于建站系统、静态文档或内容型页面来说,这种方案可以有效降低脚本复杂度和前端依赖。
四、定制样式与兼容性注意事项
提示条的视觉样式完全由CSS控制,你可以根据页面整体风格调整背景色、边框、阴影、圆角、字体大小等属性。比如想要更醒目的提示,可以设置box-shadow: 0 2px 8px rgba(0,0,0,0.15);;想要更轻量的提示,可以只保留底部边框而不设置背景。如果希望在提示文字前加上小圆点或图标,可以在content属性中拼接Unicode字符,但要避免使用Emoji,因为部分浏览器或操作系统渲染效果不一致。
在多目标场景中,所有可能被锚点定位的区块都可以共享同一套:target::before样式,只有当前命中的区块会显示提示。不过需要注意,如果某个区块内部还包含其他带id的子元素,当哈希值指向子元素时,父级不会被:target选中,因此父级上定义的:target::before不会出现。这种情况下可以为子元素单独编写提示样式,或者将提示设计为固定在视口顶部,通过body:has(:target)::before之类的选择器实现全局提示,但:has()的兼容性需要根据目标浏览器谨慎评估。
兼容性方面,:target伪类在IE9及以上版本均受支持,::before伪元素在IE9及以上版本也基本可用,但IE9和IE10对双冒号写法的支持较老,建议使用单冒号:before作为降级方案。现代浏览器对双冒号写法统一支持,因此可以放心使用。性能上,:target只会在哈希变化时重新计算样式,不会引入持续的重绘或重排,对页面渲染几乎无影响。
总的来说,:target与::before的组合提供了一种非常直观且轻量的页面提示方案。它特别适合那些不想引入前端框架、又需要给用户清晰导航反馈的页面。通过合理设计content内容和动画效果,即使是简单的文档页面也能获得流畅、友好的浏览体验。
CSS :target伪类::before伪元素页面提示修改时间:2026-09-19 14:50:19