:only-of-type只按标签名匹配唯一子元素,与媒体语义无关;它检查元素是否为父容器中该标签的唯一实例,无视其他类型兄弟元素或隐藏状态。

:only-of-type 并不适用于“媒体资源”——它只对 HTML 元素类型(即标签名)起作用,和 <img>、<video> 是否是“唯一媒体资源”无直接关系。如果你的目标是样式化页面中唯一的某个媒体元素(比如仅有一个 <video>),那 :only-of-type 有时能凑效,但前提是你理解它真正匹配的是什么。
为什么 :only-of-type 不看“媒体语义”,只看标签名?
这个伪类的逻辑非常机械:它检查某个元素在其父容器内是否是**该标签名的唯一子元素**。例如:
div > video:only-of-type
只有当 <div> 下有且仅有一个 <video>,且没有其他 <video> 兄弟节点时才匹配——不管有没有 <img>、<audio> 或 <p> 同在。
常见误用场景:
立即学习“前端免费学习笔记(深入)”;
- 父容器里有一个
<video>和两个<source>——:only-of-type不生效,因为<source>是合法兄弟,不影响<video>的“唯一性”;但若父容器里还有另一个<video>,哪怕被display: none隐藏,它仍会破坏匹配 - 用
section > *:only-of-type想选“唯一子元素”,结果意外命中了<h1>或<div>,而非你预期的媒体标签
真正想突出“唯一媒体元素”时,更稳妥的写法
如果目标明确是“这个容器里只含一个媒体元素(<img>/<video>/<audio>),且没有其他同类”,建议组合使用属性选择器或 JS 辅助判断。纯 CSS 下可尝试:
- 对每个媒体标签单独写规则:
video:only-of-type, img:only-of-type, audio:only-of-type——但注意这会把“唯一<img>”和“唯一<video>”一视同仁,缺乏语义区分 - 加一层语义 wrapper:
<figure class="media-single"><video></figure>,再用.media-single video精准控制,避免依赖 DOM 结构巧合 - 用
:has()(需确认浏览器支持):section:has(video):not(:has(video ~ video))表示“包含<video>且不存在第二个”,但目前 Safari 对:has()在伪类中的嵌套支持仍有限
:only-of-type 在媒体相关布局中真正实用的场景
它最自然的用例,其实是处理「嵌套媒体容器」中默认样式退让问题。例如:
- 文章正文
<article>内,如果只插入一个<figure>(里面包着<img>),那么figure:only-of-type可以用来取消默认外边距、居中或加边框;一旦插入第二个<figure>,样式自动回退 - 卡片组件中,用
.card > video:only-of-type给单视频卡片设 16:9 aspect-ratio,而多元素卡片则交由通用 flex 布局处理 - 注意:不要对
<source>或<track>使用:only-of-type——它们是空元素,且浏览器不渲染,伪类匹配无意义
真正容易被忽略的一点:CSS 伪类永远不感知元素是否“被 JavaScript 动态移除/替换”,也不感知 hidden 属性或 aria-hidden。只要 DOM 树里还存在那个标签,:only-of-type 就按原始结构计算。所以动态媒体加载场景下,优先用 class 控制状态,别依赖伪类“猜”结构唯一性。


















