如何不使用Material UI库实现类Material UI风格的Select组件
实现Material UI风格的Select组件(无第三方依赖)
这里提供纯React+CSS的实现方案,无需依赖Material UI,可实现聚焦时标签上移至左上角的效果,同时支持默认选中值时标签保持在上方:
import { useState, useEffect } from 'react'; import './CustomSelect.css'; export default function CustomSelect({ placeholder, value, ...props }) { const [isFocused, setIsFocused] = useState(false); const [hasValue, setHasValue] = useState(!!value); // 监听选中值变化,确保有值时标签保持激活状态 useEffect(() => { setHasValue(!!value); }, [value]); return ( <div className="select-container"> <select {...props} value={value} onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} className="custom-select" /> <label className={`select-label ${isFocused || hasValue ? 'active' : ''}`}> {placeholder} </label> </div> ); }
对应的CSS文件 CustomSelect.css:
.select-container { position: relative; width: 240px; margin: 24px 0; } .custom-select { width: 100%; padding: 14px 10px 8px; border: 1px solid #e0e0e0; border-radius: 4px; font-size: 16px; background-color: #fff; box-sizing: border-box; transition: border-color 0.2s ease; } .custom-select:focus { outline: none; border-color: #1976d2; /* 匹配Material UI主色调 */ } .select-label { position: absolute; top: 14px; left: 10px; color: #757575; font-size: 16px; transition: all 0.2s ease; pointer-events: none; /* 避免标签干扰select的点击聚焦 */ background-color: #fff; padding: 0 4px; } .select-label.active { top: -8px; left: 10px; font-size: 12px; color: #1976d2; }
关键实现细节
- 用
isFocused跟踪聚焦状态,hasValue判断是否有选中值,确保默认有值时标签不会回到占位位置 - 标签添加
pointer-events: none,防止点击标签时干扰select的聚焦逻辑 - 给标签设置白色背景,避免移动时与select边框重叠出现视觉断层
- 过渡动画采用
0.2s ease,与Material UI的动画速度保持一致
内容的提问来源于stack exchange,提问作者Harish Kumar
相关产品推荐
相关产品推荐

