width从0到100%不生效是因为::after默认inline/inline-block不支持width过渡,须设display:block、position:absolute、left/right,并确保父元素position:relative;transition需写在非:focus状态,且content: ""不可省略。

focus时用::after伪元素做横线动画,为什么width从0到100%不生效?
因为::after默认是display: inline(或inline-block),不支持width过渡;必须显式设为block并配合position: absolute和left/right控制范围。
- 确保父容器
position: relative,否则absolute伪元素会相对于body定位 -
::after需设置content: "",否则不渲染 - 过渡必须写在非:focus状态上(即初始状态),否则首次聚焦无动画
- 别漏掉
transition: width 0.3s ease——只写transition: all可能因浏览器重排导致抖动
input:focus + ::after横线延伸的最小可行CSS写法
以下是最简可靠结构,兼容Chrome/Firefox/Safari(Edge 103+):
input {
position: relative;
padding-bottom: 4px;
}
input::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: #007bff;
transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
input:focus::after {
width: 100%;
}
注意:padding-bottom预留空间给横线,否则会被文字遮挡;cubic-bezier比ease更顺滑,但不是必需。
为什么用transform: scaleX()比width更稳?
width触发布局重排(reflow),尤其在缩放字体或RTL页面中易错位;transform只触发重绘(repaint),性能好、定位准。
立即学习“前端免费学习笔记(深入)”;
- 把
width: 0 → width: 100%换成transform: scaleX(0) → transform: scaleX(1) - 必须加
transform-origin: left center,否则缩放中心默认在中间,线条会向两边展开 - 初始
::after要设width: 100%(撑满),再靠scaleX(0)隐藏,否则动画起点不准
移动端iOS Safari聚焦时横线跳动或不显示?
iOS Safari对input聚焦有特殊行为:键盘弹出可能触发重绘,导致::after位置偏移或消失。
- 强制给
input加min-height: 44px(符合苹果可点击区域规范),减少重排 - 避免用
%定义::after的width,改用left: 0; right: 0;配合transform - 如果仍异常,加
-webkit-appearance: none禁用原生样式干扰
真正难搞的是表单嵌套在flex/grid容器里时的尺寸继承问题——此时100%不再指input宽度,而是父容器内容区宽度。这种情况下,老老实实用transform + getBoundingClientRect()动态设宽反而更可控。


















