display: none 彻底移除元素,不占空间、触发重排、无障碍友好;visibility: hidden 保留占位、仅重绘、子元素可单独显示;二者均不响应鼠标事件,但 pointer-events 设置才决定事件穿透。
设置 display: none 后,元素不仅不可见,而且不占任何空间,其后续兄弟元素会立即上移填补空位。浏览器渲染时完全跳过该元素的布局计算。
offsetHeight 或 getBoundingClientRect() 会返回 0
display: none 元素,无障碍支持较好visibility: hidden 只让元素变透明不可见,它在文档流中的位置、尺寸、边距都照常保留,周围元素不会移动。
visibility: visible 单独显示(这是和 opacity: 0 的关键区别)offsetHeight 返回真实值两者都会让元素无法响应鼠标事件(如 click、hover),但事件仍可能穿透到下层元素——这取决于 pointer-events 设置,而非 visibility 或 display 本身。
display: none 元素完全从事件系统中移除,其上的事件监听器不会触发visibility: hidden 元素虽不可见,但若设 pointer-events: auto(默认),鼠标事件仍会被捕获(不过用户看不到反馈)pointer-events: none,避免意外触发opacity: 0 是视觉透明,元素依然参与布局、响应事件、影响 z-index 层叠,和前两者有本质区别。
button {
op
acity: 0; /* 看不见,但能点中,占据空间,会挡住后面元素 */
/* 如果真想隐藏又保留结构,用 visibility: hidden 更准确 */
}真正需要「渐隐动画」时才用 opacity;纯隐藏逻辑,请优先选 display 或 visibility,并明确你是否要保留占位。
最易被忽略的一点:display 切换可能引发 layout thrashing,尤其在循环中反复读写 offsetHeight 再设 display;visibility 则相对温和——但如果你忘了子元素的 visibility 继承行为,反而会暴露本该隐藏的内容。