:focus触发动画需设明确初始width、transition和避免overflow隐藏;失效常因选择器未命中、box-sizing非border-box、父容器溢出裁剪或浏览器样式覆盖。

搜索框点击后自动展开的CSS写法
响应式搜索框伸缩的核心不是靠JS监听,而是用 :focus 触发 transition 动画。直接给输入框加 width 过渡即可,但必须确保初始状态有明确的 width 值(不能是 auto 或 fit-content),否则过渡不生效。
- 初始
width推荐设为固定值(如40px)或使用min-width+flex布局约束 - 聚焦时设为较大值(如
240px),同时加padding-left避免文字被截断 - 务必声明
transition: width 0.3s ease-in-out;,且不要遗漏ease-in-out—— 默认ease在快速连续点击时容易卡顿
为什么:focus无效?检查这些地方
常见失效原因是选择器没命中或样式被覆盖。浏览器中点击输入框后,:focus 伪类确实触发了,但 width 没变,大概率是以下问题:
- 父容器设置了
overflow: hidden,导致展开后内容被裁剪(尤其在 flex 容器里) - 用了
input[type="search"],某些浏览器(如 Safari)会自带内边距和圆角,需重置appearance: none; - CSS 优先级不够:比如外部框架(如 Bootstrap)的
input样式带!important,得提高选择器权重或加!important覆盖 - 没有设置
box-sizing: border-box,导致padding和border叠加在width外,视觉上“撑不开”
移动端适配时的宽度策略
纯百分比(如 width: 100%)在小屏上容易撑满整行、挤走旁边按钮;固定像素又在大屏上显得局促。更稳妥的做法是用 max-width + flex:
.search-wrapper {
display: flex;
}
.search-input {
flex: 1;
max-width: 320px;
width: 40px;
transition: width 0.3s ease-in-out;
}
.search-input:focus {
width: 100%;
max-width: 480px;
}
- 初始状态用小固定宽,聚焦后占满父容器但不超过
max-width - 这样既保证小屏下可操作性,又避免大屏留白过多
- 注意:iOS Safari 对
input:focus的width过渡支持良好,但若配合position: absolute或transform,可能触发渲染 bug,建议避免混用
transition无法触发的隐藏条件
transition 不是万能的 —— 它只对“可计算的数值型属性”起作用。如果 width 的变化涉及以下情况,动画会直接跳变:
立即学习“前端免费学习笔记(深入)”;
- 从
display: none切换到block:display 不支持过渡,改用visibility: hidden+opacity: 0配合height或max-height - 父元素用
width: fit-content包裹,子元素width变化会被重排打断 - 使用了 CSS 自定义属性(
--search-width)但未在transition中显式声明,如transition: --search-width 0.3s(需现代浏览器支持) - 动画期间用户快速失焦再聚焦,可能因浏览器重绘节流导致中间帧丢失 —— 此时加
will-change: width可提升渲染优先级,但仅在必要时启用,避免过度 GPU 占用
真正难调的往往不是怎么写,而是为什么写了却不动。盯着 DevTools 的 Computed 面板看 width 是否真在变,比反复改代码更快。


















