输入框实现placeholder 变成 title 展示
需求:
- 输入框需要有placeholder
- 在输入框聚焦,或者有内容的时候 placeholder 要变成label 浮动在框内部
- 浮动最好能有动画,不要很生硬的跳转
进程:
- 既然placeholder 会变成title 那只有两种做法
1、将label 隐藏在上方,并且在fouce 输入框的时候展示,并且隐藏 placeholder
2、做一个假的placeholder 放在placeholder 的位置,并且在fouce 输入框的时候向上移动 - 第一个方案比第二个方案要更加的麻烦,因为会有额外的行为,隐藏placeholder 并且在隐藏的同时展示label 如果两个文本位置不一致的话会有点突兀,所以这边推荐第二个方案
#tsx
import React from 'react'
import styles from './index.module.less'type InputFloatingProps = {label?: string;type?: string;onChange?: (value: string) => void;
}
const InputFloating: React.FC<InputFloatingProps> = ({ label, type, onChange }) => {return (<div className={styles.field}><input required type={type} onChange={e => {onChange?.(e.target.value)}} pl/><label>{label}</label></div>);
}
export default InputFloating
#less
.field {position: relative;margin-top: 24px;> input {width: 100%;padding: 24px 12px 8px;font-size: 16px;border: 1px solid #979797;border-radius: 6px;outline: none;&:focus + label, &:valid + label {top: 4px;font-family: PingFang SC;font-weight: 400;font-size: 12px;line-height: 22px;color: #979797;}}> label {position: absolute;left: 12px;top: 16px;color: #979797;pointer-events: none;transition: 0.18s ease;font-family: PingFang SC;font-weight: 400;font-size: 18px;line-height: 22px;}
}
效果:


拓展:
- &:focus + label 是表示当前focus 的input 同级的
下一个dom 如果是 label 就生效,必须是连续的,如果中间加了个span 或者是其他的什么就不会生效 - &:focus ~ label 这个表示是当前focus 的input 同级的
之后的所有的label 都会触发 - input:valid 表示当前的input 里面是合法的输入,但是有些浏览器 input 输入是空也会认为是合法的,所以需要input 里加上 required,不然可能默认就是在上面的
