在 CSS 选择器体系中,相邻兄弟选择器使用加号(+)连接两个简单选择器,用来选中某个元素之后紧邻的一个同级元素。它要求两者拥有相同的父节点,并且后者必须立即跟在前者后面,中间不能插入其他同级标签。这种选择方式非常适合处理结构规律但又不希望手动加辅助类的布局场景。

一、相邻兄弟选择器的语法与匹配规则
相邻兄弟选择器的基础写法是 A + B,表示在 HTML 结构中,选中所有紧接在 A 元素后面的 B 元素。这里的关键限制是“紧邻”与“同父”。如果 A 和 B 之间夹杂了任何别的同级元素,哪怕只是一个换行或文本节点之外的标签,选择器也会失效。很多初学者误以为加号会选择 A 后面的所有 B,其实它只认第一个直接相邻的。
为了看清差异,下面是一段结构示例。第二个 <p> 紧跟着 <h2>,因此会被命中;但第三个 <p> 前面是另一个 <p>,就不在选择范围内。
<div class="box"> <h2>标题</h2> <p>第一段,紧邻 h2,会被选中</p> <p>第二段,前面是 p,不会被 h2 + p 选中</p> </div>
对应的 CSS 规则如下。只有紧邻的段落会显示上边框,用来视觉上分隔标题与正文。
h2 + p {
margin-top: 0;
padding-top: 12px;
border-top: 1px solid #ccc;
}
二、与通用兄弟选择器的区别
另一个容易搞混的是通用兄弟选择器(~)。写法为 A ~ B,它会选中 A 之后出现的所有同级 B 元素,而不要求紧邻。如果你的需求是“只要排在后面都改样式”,就用波浪号;如果只是“紧跟在后面的那一个”,就必须用加号。下面用表格列出核心差异。
| 选择器 | 符号 | 匹配范围 | 中间可插入其他元素 |
|---|---|---|---|
| 相邻兄弟 | + | 仅紧跟的一个 | 不可 |
| 通用兄弟 | ~ | 后面所有同级 | 可 |
从维护角度看,相邻兄弟选择器能减少冗余类名。例如在导航里,我们常希望菜单项之间有竖线分隔,但首尾不要。借助 li + li 就能精准给从第二个开始的每个 <li> 加左边框,而不用在 HTML 里写“分割线”类。
nav li + li {
border-left: 1px solid #ddd;
padding-left: 10px;
margin-left: 10px;
}
三、典型使用场景与代码示例
表单是相邻兄弟选择器很好用的地方。比如把输入框 <input> 紧跟在 <label> 后面,当输入框获得焦点时,可以利用 label + input:focus 给标签变色,提示用户正在填写哪一项。这种联动完全靠结构顺序完成,不需要 JS 参与。
<form> <label>用户名</label> <input type="text" name="user"> <label>密码</label> <input type="password" name="pwd"> </form>
样式部分通过相邻关系,在输入聚焦时改变前面标签颜色,提升体验。
label {
display: block;
color: #333;
}
label + input:focus {
outline: 2px solid #2a7;
}
label + input:focus + label,
label:has(+ input:focus) {
color: #2a7;
font-weight: bold;
}
需要注意的是,老旧浏览器对 :has() 支持不全,如果只做前向样式控制,label + input:focus 已经足够改变输入框本身;若要反向影响前面标签,可优先考虑 JS 或调整 DOM 顺序。总体来讲,相邻兄弟选择器是轻量、语义清晰的方案,在排版分隔、状态联动中非常实用。
四、常见误区与排查建议
当样式没有生效时,先检查两个元素是否真的同父且紧邻。有时模板引擎会偷偷插入空白 <span> 或注释节点,虽然注释不影响标签相邻,但某些服务端组件可能塞进真实元素。另外,相邻兄弟不能向前选择,也就是说 B + A 无法选中 A,因为 CSS 选择器不具备反向匹配能力。
如果确实需要“前面那个元素”受影响,要么调换 HTML 顺序,要么用 :has() 这类较新规范。在不确定时,打开浏览器开发者工具,看 Elements 面板里两个标签之间有没有其他节点,能快速定位为什么加号没起作用。
CSSadjacent_sibling_selector元素样式控制修改时间:2026-08-04 14:36:30