直接给 .dropdown-menu 加 transition 没效果,因为 bootstrap 4 用 js 注入行内样式控制初始隐藏态,css 未定义起点值导致过渡无法触发;必须同时设置 .dropdown-menu(opacity:0/visibility:hidden/transform)和 .dropdown-menu.show(opacity:1/visibility:visible/transform)两组规则,并为 transition 显式声明 opacity、visibility、transform 三属性,缺一不可。

为什么直接给 .dropdown-menu 加 transition 没效果
因为 Bootstrap 4 的下拉菜单初始隐藏状态由 JS 注入行内样式控制,比如 style="opacity: 0; transform: translateY(-5px);"。你只在 CSS 里写 .dropdown-menu { transition: opacity 0.2s; },但起点值不在 CSS 规则中,浏览器根本不知道从哪开始过渡。
必须同时定义隐藏态和显示态的 CSS 规则
真正起作用的是两组规则的配合:初始隐藏态(未加 .show 时)和显隐切换目标态(.dropdown-menu.show)。缺一不可,且需覆盖 JS 写入的行内样式。
-
.dropdown-menu必须显式设为opacity: 0、visibility: hidden、transform: translateY(-0.5rem) -
.dropdown-menu.show必须设为opacity: 1、visibility: visible、transform: translateY(0) - 这两处都得加
!important,否则 JS 行内样式会优先级更高 -
transition只能写在.dropdown-menu上,且必须列出全部参与动画的属性:transition: opacity 0.2s ease, visibility 0.2s, transform 0.2s ease;不能用all
visibility 不可省略,否则点击穿透或布局错乱
只动 opacity 和 transform 会让元素仍占文档流位置、响应鼠标事件——尤其在移动端,用户可能点到下层按钮。漏掉 visibility 就等于没关“渲染开关”。
-
visibility: hidden让元素不参与渲染,也不响应事件,但保留布局空间(这点和display: none不同) - 必须和
opacity: 0配合使用:否则透明但可点;单独用visibility则无淡入感 - 别指望
display能过渡——它根本不支持 CSS 过渡,硬加只会让动画卡顿或失效
移动端悬停失效?别依赖 :hover
Bootstrap 4 默认禁用移动设备上的 :hover 触发,这是有意为之。强行用 CSS hover 模拟下拉,会在 iOS Safari 或安卓 WebView 中出现菜单不收起、点击穿透等问题。
- 真要悬停展开,请用
data-hover="dropdown"+data-toggle="dropdown"组合,并确保结构是<div class="dropdown"> 包裹触发器和菜单 <li>移动端始终以点击为准,悬停逻辑由 Bootstrap JS 自动降级处理,无需额外 hack</li> <li>如果用了自定义 <code>transform,注意检查父容器是否设置了overflow: hidden,否则动画过程可能被裁切
真正生效的临界点不是加了
transition,而是把 JS 控制的显隐流程彻底从 display 切换剥离出来——所有状态都要由 CSS 类接管,连起点值都不能交给 JS 去写。











