bootstrap 5.3+ 自定义 ratio 比例必须用 --bs-aspect-ratio 变量(如 .ratio-21x9 { --bs-aspect-ratio: 42.857%; }),类名须以 .ratio- 开头,且 css 需在 bootstrap 后加载;旧版需改用 ::before { padding-top: ... }。

自定义 Bootstrap Ratio 比例类必须用 --bs-aspect-ratio 变量
Bootstrap 5.3+ 的 .ratio 系统不靠新增 CSS 规则,而是通过 CSS 自定义变量 --bs-aspect-ratio 控制伪元素的 padding-top 值(即高 ÷ 宽 × 100%)。直接写 .ratio-21x9 { padding-top: 42.857% } 会失效,因为 Bootstrap 的 .ratio::before 只读取该变量。
正确做法是在项目 CSS 中(且必须在 Bootstrap 样式之后加载)添加:
.ratio-21x9 {
--bs-aspect-ratio: 42.857%;
}
然后 HTML 中使用:
<div class="ratio ratio-21x9"><iframe></iframe></div>
- 类名必须以
.ratio- 开头,否则伪元素不匹配 - 旧版本(5.0–5.2)不支持
--bs-aspect-ratio,需改用.ratio-21x9::before { padding-top: 42.857% }覆盖 - 别用
calc()动态计算百分比——CSS 变量值是字符串,var(--bs-aspect-ratio)不支持运行时运算
.ratio 容器里 <iframe></iframe> 或 <video></video> 不显示的常见原因
不是比例类没生效,而是子元素没满足定位和尺寸条件。Bootstrap 的 .ratio 只管容器宽高比,不管子元素怎么铺满。
-
<iframe></iframe>必须是.ratio的**直接子元素**,中间不能套<div> <li>必须移除 <code>width和height内联属性(YouTube 默认代码带width="560" height="315",会覆盖 CSS 百分比) - 推荐加
class="position-absolute top-0 start-0 w-100 h-100";仅用w-100 h-100不够,因为 iframe 默认不是绝对定位 - 若用
<video></video>,同样要加object-fit: cover(否则可能拉伸或留黑边),Bootstrap 5.3+ 才有object-fit-cover工具类 - 不要等它显示后再 JS 补宽高,不可靠
- 把
display: none改成visibility: hidden+position: absolute(保持盒模型存在) - 或者延迟渲染:Tab 切换完成、Modal
shown.bs.modal事件触发后,再动态插入.ratio结构 - 如果父容器宽度会动态变化(比如 sidebar 展开),可加
transform: translateZ(0)强制重绘,或手动调用el.offsetHeight -
--bs-aspect-ratio是静态值,不随字体缩放、视口单位或媒体查询自动变化;想响应式切换比例(比如移动端用 9:16),得配合@media重设变量 - 所有内置比例(
16x9、4x3、21x9)都是固定padding-top百分比,不感知设备像素比,所以在高 DPR 屏幕上依然精准 - 它依赖
position: relative和overflow: hidden,如果父级有transform或clip-path,可能意外裁切子元素
为什么 .ratio 在 Tab 或 Modal 里突然塌陷
本质是浏览器无法在 display: none 状态下计算父容器宽度,导致 padding-top 计算为 0 —— 这不是 Bug,是 CSS 渲染机制决定的。
Ratio 的优势和真正容易被忽略的限制
优势很实在:.ratio-16x9 这类类名语义清晰、开箱即用、兼容性好(fallback 用 padding-top),比手写 aspect-ratio 更稳,尤其在 Safari 14.5 之前。
但限制点常被低估:
最麻烦的是:一旦你开始大量自定义比例类,就等于在维护一套和 Bootstrap 解耦的“伪组件系统”——它不参与 SASS 变量体系,也不能 tree-shake,体积悄悄变大。











