로그인 페이지를 만들 던 중 label을 placeholder 처럼 쓰면서 애니메이션을 주고 싶어 어떻게 할 지 생각하다 본게 밑에 보이는 애니메이션이다.
간단하게 설명하자면 input에 focus
되면 label 글자가 왼쪽 위 방향으로 올라가고 인풋이 아닌 다른 부분을 클릭하면 다시돌아와서 사용자가 글자를 입력하는 곳에 방해를 주지 않게 해주는 것 이다. label을 placeholder 처럼 사용하는 가장 멋진 일 이라고 생각해서 한 번 구현해 보기로 하였다.
input
요소에 onFocus 와 onBlur 이벤트를 준다.isFocus
라는State
를 만들어서 초기값을 false로 지정한다.handleFocus
와handleBlur
함수를 만들어 포커스와 블러가 될 때state
값을toggle
하게 만들어준다.Tailwind
를 사용하였으므로className
값에 삼항연산자를 사용하여isFocus
가true
,false
일때의 스타일을 다르게 지정해준다.
구현을 완료했는데 한가지 문제 사항이 생겼다. 두개의 input에 같은 함수를 사용하였기 때문에 Email 인풋을 포커스 할 때도 2개의 인풋이 전부 애니메이션 되고 Password 인풋을 포커스 할 때도 2개의 인풋이 전부 애니메이션 된다는 것이였다!!😿
어떻게 해야할 지 고민하다가 ref
를 사용해서 input element
를 따로 선택 해 줘서 함수에 입력해줄까 했는데 생각대로 잘 되지 않았었다. (Typescript도 처음이라 ref문에서 자꾸 오류가 났다😭)
그래서 결국 밑에 보이는 코드와 같이 Email
인풋의 Focus
, Blur
함수를 따로만들고 Password
인풋의 Focus
,Blur
를 따로 만들었다.
const handleEmailFocus = () => {
setIsFocus(!isFocus);
};
const handleEmailBlur = () => {
setIsFocus(!isFocus);
};
const handlePwFocus = () => {
setIsFocusPw(!isFocusPw);
};
const handlePwBlur = () => {
setIsFocusPw(!isFocusPw);
};
그리고 각각의 인풋에다가 함수들을 넣어줬다.
<div className="relative">
<label htmlFor="email" className={`text-md absolute font-gray-600 transition ease-in-out left-3 top-4 ${isFocus ? "-translate-x-2" : ""} ${isFocus ? "-translate-y-3" : ""} ${isFocus ? "scale-75" : ""}`}>
이메일
</label>
<input onBlur={handleEmailBlur} onFocus={handleEmailFocus} type="text" id="email" name="email" className={`border border-gray-600 w-full rounded-[4px] h-14 pt-4 pl-3 mb-1`} />
</div>
<div className="relative">
<label htmlFor="pw" className={`text-md absolute font-gray-600 transition ease-in-out left-3 top-4 ${isFocusPw ? "-translate-x-2" : ""} ${isFocusPw ? "-translate-y-3" : ""} ${isFocusPw ? "scale-75" : ""}`}>
비밀번호
</label>
<input onBlur={handlePwBlur} onFocus={handlePwFocus} type="text" id="pw" name="pw" className={`border border-gray-600 w-full rounded-[4px] h-14 pt-4 pl-3 mb-2`} />
</div>
사실 지금 위에 함수를 보면 똑같은 기능을 하는 함수가 2개씩 따로따로 구성 되어있다. 이렇게 사용하는 방식은 좋지 않다고 생각한다. 그래서 나중에 이부분을 한번 생각해보고 고쳐볼 생각이다!!
이렇게 하는 방식보다 더 좋은 방식이 있다면 알려주세요 고수분들😿