h5中可纯css实现material design输入框标签上浮缩放效果:label包裹input确保语义化与无障碍,利用:focus、:not(:placeholder-shown)、:not(:valid)触发transform动画,配合transition优化性能;ios兼容需js兜底监听input/blur事件切换active类。

在 H5 中实现点击 input 时标签(label)上浮并缩放的 Material Design 效果,核心是利用 CSS 的 :focus 状态 + 伪元素或相邻兄弟选择器,配合过渡动画。不需要框架也能轻量实现。
结构:用 <label></label> 包裹 <input>
推荐语义化写法,确保 label 可点击且无障碍友好:
<label class="md-input"> <input type="text" required><span class="md-label">用户名</span> </label>
这样能天然绑定焦点(点击 label 自动聚焦 input),也方便用 CSS 选择器控制内部元素。
CSS 实现上浮与缩放动画
关键点:标签默认在输入框内,获得焦点后上移、缩小、变色,并保持在左上角固定位置:
.md-input {
position: relative;
margin: 24px 0;
}
.md-input input {
width: 100%;
padding: 16px 0 8px;
font-size: 16px;
border: none;
border-bottom: 1px solid #999;
background: transparent;
outline: none;
transition: border-color 0.2s;
}
.md-input input:focus {
border-bottom-color: #2196F3;
}
.md-label {
position: absolute;
top: 16px;
left: 0;
font-size: 16px;
color: #999;
pointer-events: none;
transition: all 0.2s ease;
transform-origin: left top;
}
.md-input input:focus + .md-label,
.md-input input:not(:placeholder-shown) + .md-label,
.md-input input:not(:valid) + .md-label {
transform: translateY(-24px) scale(0.75);
color: #2196F3;
font-weight: 500;
}
-
用
+ .md-label选中紧邻的 label(注意 HTML 中 label 必须包裹 input 或 input 在 label 内且 label 为父容器) -
:not(:placeholder-shown)让有内容时 label 保持上浮状态(兼容 Chrome/Firefox) -
:not(:valid)配合required属性,空值时 label 仍上浮(增强表单反馈) - 动画使用
transform而非top,性能更好且支持 GPU 加速
补充:兼容 placeholder 和 iOS 输入体验
iOS Safari 对 :placeholder-shown 支持不稳定,可加 JS 做兜底:
document.querySelectorAll('.md-input input').forEach(input => {
const label = input.nextElementSibling || input.parentElement.querySelector('.md-label');
const updateLabel = () => {
if (input.value.trim() || input.checkValidity()) {
label.classList.add('active');
} else {
label.classList.remove('active');
}
};
input.addEventListener('input', updateLabel);
input.addEventListener('blur', updateLabel);
});
对应 CSS 补充:
.md-label.active {
transform: translateY(-24px) scale(0.75);
color: #2196F3;
font-weight: 500;
}
进阶:支持多行文本(textarea)和错误状态
只需复用相同结构和类名,额外添加:
- 对
textarea,把padding-bottom设为足够空间(如12px),避免文字顶到 label - 错误时给外层
.md-input加class="error",改border-bottom-color为#f44336,label 颜色同步更新 - 禁用状态用
input:disabled降低 label 透明度:opacity: 0.6











