@namespace 用于声明命名空间上下文,使css选择器能区分同名但不同命名空间的元素(如xhtml与svg中的);它不匹配元素,必须置于@import之后、其他样式规则之前,且需配合ns|elem语法(如svg|a)才能精准控制。

@namespace 不是用来“选择”元素的,它本身不匹配任何元素,只用来**声明命名空间上下文**,让后续的选择器能正确区分同名但不同命名空间的标签(比如 a 在 XHTML 和 SVG 中语义完全不同)。
为什么直接写 a { color: red; } 会出问题
在含内联 SVG 或 MathML 的 HTML5 页面中,a 元素可能同时存在于 http://www.w3.org/1999/xhtml 和 http://www.w3.org/2000/svg 命名空间下。不加约束时,a 选择器会命中两者——你只想改超链接颜色,结果 SVG 超链接也跟着变色了。
浏览器自动为已知 foreign elements 分配命名空间(svg、math),但 CSS 选择器默认不感知这个区别,除非你用 @namespace 显式告诉它。
- HTML5 中
<svg></svg>内部的<a></a>自动属于 SVG 命名空间 - HTML 中的
<a></a>默认属于 XHTML 命名空间(即使没写xmlns) - 没声明
@namespace时,a是“无命名空间限定”的通配匹配
@namespace 必须放在哪儿?顺序错了就失效
它不是随便放的装饰性规则,而是解析期生效的指令。必须严格满足:
- 所有
@charset和@import之后 - 所有其他样式规则(
a {}、.cls {}等)之前 - 哪怕多一个空行、一个注释、一个空格在它前面,整条规则都会被浏览器忽略
错误示例:
@charset "UTF-8";<br>/* 这里空了一行 */<br>@namespace url(http://www.w3.org/1999/xhtml);→ 第二行空行导致
@namespace 失效正确写法(顶格、紧接 @import 后):
@import "base.css";<br>@namespace url(http://www.w3.org/1999/xhtml);<br>@namespace svg url(http://www.w3.org/2000/svg);<br>a { color: blue; }<br>svg|a { fill: orange; }
怎么写才能精准控制 XHTML 和 SVG 的 a 标签
声明命名空间后,要用带命名空间前缀的选择器语法才能生效:
-
@namespace url(http://www.w3.org/1999/xhtml);→ 设 XHTML 为默认命名空间,之后的a、div等类型选择器只匹配 XHTML 元素 -
@namespace svg url(http://www.w3.org/2000/svg);→ 给 SVG 命名空间起别名svg -
svg|a→ 只匹配 SVG 命名空间下的<a></a>(注意竖线|是分隔符,不是管道符) -
*|a→ 匹配任意命名空间下的a(包括未声明的) -
a[href]→ 属性选择器不受默认命名空间影响,仍会跨空间匹配(这是规范行为,不是 bug)
常见误操作:svg:a 或 svg a 都无效 —— CSS 中命名空间分隔符只能是 |,不能用冒号或空格。
实际项目中最容易被忽略的兼容性细节
不是所有浏览器都完整支持命名空间选择器,尤其在旧版移动端 WebKit 或 IE 中:
- Chrome / Firefox / Safari(现代版本):支持
@namespace+ns|elem语法 - IE 9–11:支持声明,但对
svg|a类选择器支持不稳定,建议降级用 class 控制 - Android Browser(4.4 及更早):基本不识别
@namespace,整条规则被跳过 - 属性选择器如
[href]永远不继承默认命名空间,这点常被当成“bug”反复调试
如果你的项目需要兼容低版本 Android 或老 IE,@namespace 更适合作为渐进增强手段,核心样式仍应依赖 class 或 data-* 属性隔离。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











