:focus过渡无效因元素不可聚焦,须设tabindex、确保可获焦且未被拦截;:focus-within需contenteditable容器内子元素获焦;过渡仅用transform等安全属性;:active应避免纯白,用色值混合并加tap高亮透明。

为什么:focus加了过渡却没反应?
浏览器只对“可聚焦元素”触发:focus伪类,而默认可聚焦的只有<a></a>、<button></button>、<input>等少数标签。给<div>或<code><span></span>直接写:focus { transition: ... }是无效的——它根本不会获得焦点。
必须同时满足三个条件:
- 元素有
tabindex属性(哪怕只是tabindex="0") - 用户通过键盘 Tab 进入,或 JS 调用
.focus() - 没被
pointer-events: none或visibility: hidden拦截
移动端尤其容易失效:iOS Safari 对非表单元素的tabindex支持不稳定,建议搭配touchstart监听并手动调用.focus(),再加preventDefault()防缩放。
:focus-within怎么让编辑器一激活就展开面板?
:focus-within不是“自己获得焦点”,而是“内部任意子元素获得焦点”时才触发。所以编辑器容器本身必须设contenteditable="true",不能只靠tabindex。
立即学习“前端免费学习笔记(深入)”;
常见失效点:
- 扩展面板放在
body下(比如用 React Portal),脱离了编辑器 DOM 子树 →:focus-within完全不匹配 - 编辑器用了 Slate/Draft.js 等库,焦点被劫持到虚拟节点 → 需确认最终焦点落在真实 DOM 子元素上(如
<div contenteditable><br></div>) - 面板用
display: none隐藏 → 即使匹配:focus-within也无法显示,应改用opacity: 0; visibility: hidden; pointer-events: none
示例结构必须是:
<div contenteditable="true"> <div class="editor-content"></div> <div class="toolbar"></div> </div>然后写
div[contenteditable]:focus-within .toolbar { opacity: 1; visibility: visible; pointer-events: auto; }过渡动画卡顿或抖动,transition该写哪些属性?
只过渡安全属性,避免触发布局重排(reflow):
- ✅ 推荐:
background-color、color、opacity、transform、box-shadow - ❌ 避免:
width、height、padding、margin、font-size(这些会改变盒模型)
特别注意表格行高亮:tbody tr { transition: background-color 0.2s ease; }
别写transition: all——后续加border或padding会让整行跳动。
另外,移动端要包裹媒体查询防止无意义渲染:@media (hover: hover) { tbody tr:hover { transition: background-color 0.2s ease; } }
深色主题下:active背景变白看着像闪一下,怎么调?
纯白background-color: white在深色背景上对比度过高,人眼感知为闪烁而非反馈。这不是 bug,是视觉动效设计问题。
更稳妥的做法是生成与原色协调的浅色变体:
- 原背景
#1e40af(深蓝)→:active用#dbeafe(极浅蓝) - 或用 CSS 新特性动态计算:
background-color: color-mix(in srgb, #1e40af 20%, white);
必须配transition,但时间别超过0.15s,否则失去“瞬间按压感”。
还要清除 iOS 默认遮罩:-webkit-tap-highlight-color: transparent;,否则:active根本看不到。
真正麻烦的从来不是写几行 CSS,而是不同设备对“焦点”“激活”“悬停”的触发逻辑差异太大——同一段代码,在桌面 Chrome 里流畅,在 iOS Safari 里静默,在旧版 Android WebView 里延迟半秒。



















