:hover 在 div 上“不生效”通常因 div 无尺寸、被 pointer-events: none 禁用,或未设 tabindex 导致:focus 缺失;实际 :hover 本身对所有元素有效,关键在确保可交互性与样式可见性。

为什么 :hover 在 div 上看起来“不生效”
默认情况下,<div> 等非表单、非链接元素没有焦点能力,也不被浏览器视为“可交互”,所以即使写了 <code>:hover 样式,它可能在视觉上没变化——不是伪类失效,而是元素没触发条件。更常见的是:你加了 :hover,但没加 :focus 的配套样式,或没给元素设置 tabindex,导致键盘操作时完全没反馈。
-
:hover只依赖鼠标悬停,对所有元素都有效(包括<div>),但需确保该元素有尺寸(比如设置了 <code>width/height或内容撑开)、且未被其他样式(如pointer-events: none)禁用 -
:focus默认只作用于原生可聚焦元素:<a href></a>、<button></button>、<input>、<textarea></textarea>、<select></select>,以及带tabindex属性的任意元素 - 若想让
<div> 响应 <code>:focus,必须显式添加tabindex="0"(推荐)或tabindex="-1"(仅脚本聚焦):hover和:focus同时写样式时的常见冲突当两者共存时,容易误以为“只有一个生效”,其实是层叠顺序或状态切换逻辑没理清。比如你写了
div:hover { color: red; }和div:focus { color: blue; },但鼠标悬停时点击一下,焦点获取后颜色变蓝;再点空白处失焦,颜色回退——这本身是正常行为。问题常出在:- 没考虑
:focus-visible:现代浏览器会自动区分鼠标/键盘触发焦点,直接写:focus可能造成鼠标操作后意外出现焦点框(尤其 Chrome) - 遗漏
:focus-within:父容器内子元素获得焦点时,父元素需要响应样式(比如下拉菜单展开区高亮),这时该用:focus-within而非:focus - 重置了 outline:写了
outline: none却没提供替代焦点样式,导致键盘用户完全看不到当前焦点在哪
正确写法示例:可交互容器 + 键鼠双模式支持
下面是一个带点击展开功能的卡片,支持鼠标悬停提示、键盘 Tab 进入、Enter 触发,且焦点样式清晰可见:
/* HTML 结构 */ <div class="card" tabindex="0" role="button" aria-expanded="false"> <h3>标题</h3> <p>内容摘要</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill11112" title="CSS工具箱(专业版)"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20e352aa140.jpg" alt="CSS工具箱(专业版)" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill11112" title="CSS工具箱(专业版)">CSS工具箱(专业版)</a> <p>全功能 CSS 工程手册,覆盖性能优化、无障碍、设计系统与跨浏览器兼容。</p> </div> <a href="/xiazai/skill11112" title="CSS工具箱(专业版)" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p> </div>/* CSS 样式 */ .card { padding: 1rem; border: 1px solid #ddd; border-radius: 4px; transition: all 0.2s; } <p>.card:hover, .card:focus-visible { background-color: #f5f5f5; border-color: #007bff; outline: 2px solid transparent; outline-offset: 2px; }</p><p>.card:focus-visible { outline-color: #007bff; }</p><p>/<em> 避免鼠标操作后出现难看的默认 focus outline </em>/ .card:focus:not(:focus-visible) { outline: none; }-
tabindex="0"让<div> 可被键盘聚焦<li> <code>role="button"告诉辅助技术这是个按钮行为,提升可访问性 -
:focus-visible是关键:只在键盘触发焦点时应用样式,鼠标悬停+点击不触发 -
outline: none必须配合:focus-visible使用,否则会破坏键盘导航体验 - 打开浏览器开发者工具,选中元素,在 “Styles” 面板里勾选
:hover/:focus强制激活,看样式是否真的被定义、有没有被更高优先级规则覆盖 - 检查元素是否渲染出实际尺寸:空
<div> 没宽高、没内容、没边框背景,悬停就“看不见”,用 <code>background: cyan临时测试 - 确认是否被
pointer-events: none或父级overflow: hidden截断了事件区域(尤其是绝对定位子元素超出父容器时)
调试时优先检查这三件事
样式不生效,90% 情况下不是伪类写错了,而是环境或状态没到位:
可交互性的边界很窄:一个没
tabindex的<div>,再漂亮的 <code>:hover也救不了键盘用户的体验。别只盯着样式生效与否,先确认它是不是真能被用户“触达”。 - 没考虑

















