CSS过渡在搜索栏激活状态的应用_图标消失与输入框伸展

2次阅读

:focus-within更可靠,解决图标消失失效问题;需统一box-sizing、用opacity+visibility过渡;ie11等旧环境需js回退;图标缩放时应避免pointer-events:none导致失焦异常。

CSS过渡在搜索栏激活状态的应用_图标消失与输入框伸展

focus 时图标消失:用 :focus-within 更可靠

直接对 input:focus 控制父容器里的图标,常因结构嵌套深或事件冒泡不一致而失效。比如图标在 div.search-box 内部,但 input:focus 无法向上影响兄弟节点的图标显示。

更稳的做法是把过渡逻辑放在父容器上,用 :focus-within

div.search-box {   transition: padding 0.2s ease; } div.search-box:focus-within .search-icon {   opacity: 0;   transform: scale(0.8); } div.search-box:focus-within input {   width: 100%; }
  • :focus-within 兼容 chrome 60+、firefox 52+、safari 15.4+,旧版 Safari 需降级为 JS 监听 focus/blur
  • 图标必须和 input 在同一可聚焦容器内(不能跨 shadow domiframe
  • 避免对 .search-icon 同时设 display: none 和过渡——display 不触发重绘,得用 opacity + visibility 组合

输入框伸展卡顿:width 不是唯一变量

只改 width 容易出现“先拉伸再对齐”或边缘抖动,尤其在有边框、padding、box-sizing 混用时。

真正要同步过渡的是整个盒模型参与布局的部分:

立即学习前端免费学习笔记(深入)”;

input {   box-sizing: border-box;   padding: 8px 12px;   border: 1px solid #ccc;   width: 160px;   transition: width 0.25s ease, padding 0.25s ease, border-color 0.25s ease; } div.search-box:focus-within input {   width: 240px;   padding: 8px 20px;   border-color: #007bff; }
  • 务必统一设 box-sizing: border-box,否则 width + padding 叠加会超预期尺寸
  • 如果父容器宽度受限(如 flex item),优先过渡 flex-grow 而非 width,避免响应式断裂
  • 动画时间超过 0.3s 易被感知卡顿,低于 0.15s 则像没动;0.2–0.25s 是较稳妥区间

IE11 或老安卓 webview 中图标不消失

:focus-within 在 IE11 完全不支持,部分 android 4.x WebView 也忽略该伪类,此时图标残留是常态,不是代码写错。

最小代价的兼容方案是加一层轻量 JS 回退:

const searchBox = document.querySelector('.search-box'); const input = searchBox.querySelector('input'); input.addEventListener('focus', () => searchBox.classList.add('focused')); input.addEventListener('blur', () => searchBox.classList.remove('focused'));

对应 css 补一句:

.search-box.focused .search-icon { opacity: 0; transform: scale(0.8); }
  • 不用监听整个 document 的 focus/blur,只绑当前 input,避免干扰其他表单
  • 不要用 classList.toggle 配合 autofocus,页面加载时可能误触发
  • 如果项目已用 jquery,别为了这点逻辑引入整包——原生 addEventListener 足够

图标消失后焦点管理异常

图标缩小时若用了 transform: scale(0),部分浏览器(如 Safari 16.4)会把该元素视作“不可交互”,导致点击空白处失焦后无法再点图标区域重新聚焦 input。

根本解法是保持图标可点击区域存在,只是视觉隐藏:

  • opacity: 0 + pointer-events: none 替代 transform: scale(0)visibility: hidden
  • 确保图标父容器没有 overflow: hidden,否则缩放动画裁切会导致视觉残留
  • 如果图标是 SVG,检查是否设置了 focusable="false" —— 这会让它抢不到焦点,但也不会影响 input 的聚焦逻辑

过渡动效本身不难,难的是边界情况下的行为一致性。特别是图标作为交互入口又承担视觉提示时,它的显隐逻辑得和焦点状态严格对齐,差一帧或一个 CSS 层叠顺序,用户就会觉得“点了没反应”。

text=ZqhQzanResources