transition必须写在常态选择器中而非:focus内,且仅对可插值属性生效;起始值需显式声明,避免使用display、height:auto等不支持过渡的属性。

transition 必须配合 :focus 使用,且只对可插值属性生效;单纯加 transition 不会触发动画,关键在“状态变化是否真实发生”。
为什么 :focus 加了 transition 却没反应
常见错误不是写法不对,而是浏览器没识别到「从 A 到 B 的有效变化」:
- 起始值未显式声明——比如只在
.input:focus { border-color: #007bff; }里改颜色,但基础样式没设border-color,浏览器可能取默认medium none currentcolor,无法插值 - 用了不可过渡的属性——
display、height: auto、font-family、z-index都不支持过渡,哪怕写了transition: all 0.3s也无效 - 伪类里重复写
transition——:focus规则中再写一遍transition没用,必须放在基础选择器(如input或.input)里 - 焦点被 JS 快速覆盖——例如监听
focus后立刻调用blur(),或连续操作 class 导致状态来不及渲染
transition 应该写在哪个选择器里
必须写在「常态元素」的选择器中,而不是 :focus 块内:
input {
border: 2px solid #ccc;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
input:focus {
border-color: #007bff;
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}
这样浏览器才能在获得焦点时,对比「常态下的 border-color」和「:focus 下的新值」,启动插值计算。如果把 transition 写进 input:focus,它只在焦点态生效,失去起点参照,动画不会启动。
立即学习“前端免费学习笔记(深入)”;
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
哪些属性适合用在 :focus 过渡中
优先选合成层友好、重绘开销低的属性:
-
border-color:安全,兼容性好,视觉反馈明确 -
outline-color/outline-offset:注意outline默认有浏览器样式,需先outline: none再自定义 -
box-shadow:比border更轻量,适合高亮提示 -
transform(如scale(1.02)):性能最优,但需搭配will-change: transform预提升图层(仅必要时) -
opacity:慎用,输入框透明可能导致内容可读性下降
避免用 width、height、margin、padding——它们触发布局重排(reflow),在焦点切换这种高频交互中容易卡顿。
移动端 :focus 过渡的兼容性坑
iOS Safari 和部分安卓 WebView 对 :focus 触发时机很保守:
- 点击 input 不一定立即触发
:focus,尤其在 meta viewport 缩放或页面有user-scalable=no时 - 软键盘弹出后,焦点可能被临时移走,导致过渡中断
- 某些安卓机型需要
tabindex="0"才能让非表单元素响应:focus
更稳妥的做法是:用 :focus-within 包裹父容器(如 .form-group:focus-within label),或配合 JS 监听 focusin 事件手动加 class,再让 class 触发过渡——这样控制权更稳,也方便加 fallback。
真正难的不是写对那几行 CSS,而是确认「浏览器是否真的认为这个变化值得动起来」:起止值都得是确定的、可计算的、不依赖继承或默认值的数值。很多失效案例,删掉一行 !important 或补一个 border: 2px solid transparent 就好了。


















