<input> 태그를 focus하면 placeholder가 위로 이동하는것처럼 보여지는 form을 만들어 보자.
HTML
<div className="input__wrapper">
<div className="input-box">
<input type="email" required />
<span className="input-label">EMAIL</span>
</div>
<div className="input-box">
<input type="text" required />
<span className="input-label">NAME</span>
</div>
</div>
CSS
.input__wrapper {
width: 400px;
height: 300px;
margin: 40% auto;
.input-box {
margin: 10px 0;
input {
width: 100%;
height: 50px;
padding: 0 15px;
background-color: rgb(30, 30, 30);
border: 1px solid rgb(49, 172, 110);
border-radius: 5px;
color: rgb(49, 172, 110);
}
.input-label {
color: rgb(49, 172, 110);
}
}
}
scss를 사용해 nesting 되어 있는 코드.
<input> 태그와 <span> 태그를 각각 <div> 태그로 한번씩 감싸줬다.
각 <input> 태그의 placeholder 역할은 <span> 태그가 해줄 것이다.
먼저 <span> 태그를 position : relative 를 이용해 <input> 태그의 placeholder 자리로 넣어주자.
CSS
.input-label {
color: rgb(49, 172, 110);
position: relative;
left: 15px;
bottom: 33px;
transition: 0.3s;
padding: 5px 10px;
pointer-events: none;
}
<span> 태그의 선택자에 postion, left, bottom 값을 넣어서 이동시키고,
transition은 부드러운 이동을 위해, 배경에 약간의 여백이 필요하기 때문에 padding 값 추가,
pointer-events : none 을 주어 클릭이 안되도록 설정했다.
이제 <input> 태그에 focus를 주면 <span> 태그가 border로 이동하도록 값을 추가해 준다.
CSS
input {
width: 100%;
height: 50px;
padding: 0 15px;
background-color: rgb(30, 30, 30);
border: 1px solid rgb(49, 172, 110);
border-radius: 5px;
color: rgb(49, 172, 110);
&:focus ~ .input-label {
bottom: 58px;
background-color: rgb(73, 80, 76);
}
}
<span> 태그의 배경색은 구분을 위해서 다른색상을 넣었는데, 원래는 body의 배경색과 동일한 색상을 넣어주면 된다.
약간의 스타일을 주기위해 border를 추가하고 스타일을 약간 더 다듬어 보자.
CSS
&:focus ~ .input-label {
left: 28px;
bottom: 58px;
background-color: rgb(30, 30, 30);
border-left: 1px solid rgb(49, 172, 110);
border-right: 1px solid rgb(49, 172, 110);
font-size: 12px;
}
왼쪽과 오른쪽에 border를 주었고,
left값을 추가해 왼쪽으로 좀 더 이동시키고 font-size도 작아지게 추가했다.
이제 중요한점!
<input> 태그에 value가 들어있으면 <span> 태그를 위쪽에 고정시켜주는걸 추가해야 한다.
CSS
&:valid ~ .input-label {
left: 28px;
bottom: 58px;
background-color: rgb(49, 172, 110);
border-left: 1px solid rgb(49, 172, 110);
border-right: 1px solid rgb(49, 172, 110);
border-radius: 3px;
font-size: 12px;
color: black;
}
:valid 선택자를 추가하여 <input> 태그의 입력 조건을 만족했을 때의 style을 지정해 줄 수 있다.
추가로 :invalid 선택자는 입력 조건을 만족하지 않았을 때의 style을 지정해 줄 수 있다.
근데 :invalid 선택자를 추가할 경우, 최초의 <span> 태그의 위치 ( <input> 태그 안에 placeholder처럼 들어가 있는 )를
잃어버리기 때문에 :invalid 선택자까지 쓰려면 좀 더 생각을 해봐야 할 것 같다.
물론 지금 상태도 <input type="email">일 경우 email 형식을 제대로 입력하지 않고 focus를 해제하면
<input> 태그의 value와 <span> 태그가 겹치는 이슈가 있다... 해결책을 찾아 다음에 한번 더 포스팅!
일단 지금은 css만...🙄
완성본
HTML
<div className="input__wrapper">
<div className="input-box">
<input type="email" required />
<span className="input-label">EMAIL</span>
</div>
<div className="input-box">
<input type="text" required />
<span className="input-label">NAME</span>
</div>
</div>
CSS ( scss )
.input__wrapper {
width: 400px;
height: 300px;
margin: 40% auto;
.input-box {
margin: 10px 0;
input {
width: 100%;
height: 50px;
padding: 0 15px;
background-color: rgb(30, 30, 30);
border: 1px solid rgb(49, 172, 110);
border-radius: 5px;
color: rgb(49, 172, 110);
&:focus ~ .input-label,
&:valid ~ .input-label {
left: 16px;
bottom: 58px;
border-left: 1px solid rgb(49, 172, 110);
border-right: 1px solid rgb(49, 172, 110);
font-size: 12px;
}
&:focus ~ .input-label {
background-color: rgb(30, 30, 30);
}
&:valid ~ .input-label {
background-color: rgb(49, 172, 110);
color: black;
border-radius: 3px;
}
}
.input-label {
color: rgb(49, 172, 110);
position: relative;
left: 15px;
bottom: 33px;
transition: 0.3s;
pointer-events: none;
padding: 3px 5px;
}
}
}