正确做法是先全局隐藏再显式恢复:用 d-none d-lg-block 实现仅PC/大平板显示、手机端彻底消失,避免误用 d-sm-none 导致竖屏手机仍显示。

用 d-none + 断点类控制「只在手机端隐藏」
想让某个模块在手机上彻底消失(不占位、不触发事件、不被读屏器读取),不能只写 d-sm-none——它在 ≥576px 时才生效,而绝大多数竖屏手机(如 iPhone 14 竖屏 390px)属于 xs 断点,d-sm-none 对它们完全无效,模块照常显示。
正确做法是反向控制:先全局隐藏,再在你希望显示的断点上显式恢复。例如,要「仅在 PC 和平板显示,手机端彻底消失」,就用:
<div class="d-none d-lg-block">PC 专用模块</div>
-
d-none:所有尺寸下都设为display: none -
d-lg-block:仅当视口 ≥992px(Bootstrap 5 的 lg 断点)时恢复为display: block - 这样,iPhone、安卓小屏、横屏手机(多数 ≤767px)、小平板(如 768×1024 竖屏)全被排除,只有真正桌面或大平板才渲染
别踩 d-sm-none 这个坑
d-sm-none 的实际行为是「≥576px 时隐藏」,不是「在手机上隐藏」。它会把横屏手机(比如 576×1024)、iPad mini(768×1024 横屏)、甚至部分折叠屏半开状态都误杀——但你的目标用户(竖屏手机)反而完全不受影响。
更危险的是,有人误以为 d-sm-none 是「手机专属开关」,结果上线后发现手机端模块还在,排查半天才发现断点逻辑理解反了。
- xs 断点(0–575.98px)没有对应工具类,
d-xs-none不存在,写了等于白写 - Bootstrap 的断点全是
min-width媒体查询,不是「区间匹配」,不存在「仅在 xs 生效」的类 - 若真要精确控制 0–575.98px,只能手写媒体查询:
@media (max-width: 575.98px) { .mobile-hidden { display: none; } }
表格列、侧边栏这类结构化内容怎么处理
表格中某几列(如「工号」「直属上级」)在手机端没空间展示,光靠 col-* 类缩放没用——DOM 还在,仍参与布局计算、键盘导航和无障碍读取。
必须用 d-none 组合类直接移除渲染:
<th class="d-none d-md-table-cell">工号</th> <td class="d-none d-md-table-cell">FE001</td>
-
d-none在所有断点下移除单元格 -
d-md-table-cell在 ≥768px 时恢复为display: table-cell,保证表格结构不塌 - 不要用
d-sm-none或d-lg-none单独控制,范围不对且易冲突 - 如果用了
table-responsive容器,注意其内部有overflow-x: auto,即使列被d-none掉,滚动条可能还存在——需配合overflow-x: visible调整
隐藏后还要注意 JS 和无障碍
d-none 不只是视觉变化:元素从文档流中完全消失,绑定在其上的事件监听器不会触发,offsetParent 为 null,getBoundingClientRect() 返回全零值。这点对 JS 控制显隐逻辑很关键。
- 别在
d-none元素上留onclick或addEventListener,它不会响应 - 如果模块含表单控件(如输入框),隐藏后记得
tabindex="-1"或移除autofocus,否则键盘焦点会跳进一个不可见区域 -
d-none默认让屏幕阅读器跳过该元素,无需额外加aria-hidden="true";但若你用的是invisible(visibility: hidden),就必须手动加aria-hidden="true",否则读屏器仍会读取 - 服务端渲染(如 Next.js)中,若根据 UA 判断设备并服务端加
d-none,客户端水合时 UA 判断不一致,会导致 hydration mismatch——应优先用纯 CSS 媒体查询方案
实际最常出问题的地方,是把「隐藏」当成纯样式活儿来干:加个类就完事,不验证 DOM 是否真被移除、不检查键盘导航路径、不看读屏器行为。一旦涉及表单、焦点管理或 SSR,d-none 的语义强度就会立刻暴露出来——它不是“看不见”,而是“不存在”。











