이제 할 일도 없고 주말에 개인프로젝트 하는것도 좀 아닌것 같아서 


이 사이트 저 사이트 구경을 하는중 재밌는걸 발견




이메일 주소와 비밀번호는 placeholder처럼 보이지만


포커스가 들어오면 색이 바뀌고


value가 있거나 포커스가 있으면 위쪽으로 작아지면서 움직이는 효과가 있다


어떻게 구현했을지 궁금해서 소스를 까보았다




input에 포커스가 들어오거나 값이 있으면 div와 label에 자바스크립트로 클래스를 추가해주는 방식이다


사실 이걸 구현하는데 자바스크립트가 필요하지는 않다




이걸 html과 css만으로 재작성해보자 우선 다음과 같이 dom 구조를 만들어주자


<div className={cx("item")}>
<input className={cx("input")} type="email"/>
<label className={cx("label")}>이메일 주소</label>
</div>
<div className={cx("item")}>
<input className={cx("input")} type="password" />
<label className={cx("label")}>비밀번호</label>
</div>


그 다음 사이트에서 css를 가져온다


기본적인 스타일링은 가져올 가치가 있지만, 애니메이션 처리를 하는 부분은 자바스크립트에 의존하고있어서 별로 가치가 없다


폰트나 레이아웃에 대한 부분은 그대로 사용하지만, css 효과를 넣는 부분은 전부 재작성한다


css는 개븅신언어니까 scss로 짜면 좋다



보니까 위 사이트의 코드는 css의 c의 특성인 cascade의 특징을 잘 살리지 못하고 있다


하위 클래스에 중복되는 스타일이 많아서 대충 상위 클래스로 몇개 올려놨다


.item {
margin-top: 27px;
position: relative;
padding: 10px 0 11px;
border-bottom: 1px solid #dddfe4;
font-weight: 400;
font-size: 16px;
vertical-align: baseline;
word-break: keep-all;
transition: border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
&:focus-within {
border-color: #1ea1f7;
}
.input {
position: relative;
z-index: 1;
border: 0;
padding: 0;
outline: 0;
background-color: transparent;
line-height: 19px;
width: 100%;
&:focus+label {
transform: scale(0.75) translateY(-39px);
color: #1ea1f7;
}
&:not([value=""])+label {
transform: scale(0.75) translateY(-39px);
}
}
.label {
pointer-events: none;
line-height: 19px;
color: #7b858e;
position: absolute;
bottom: 3px;
left: 0;
top: 11px;
transform-origin: bottom left;
transition: bottom, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
}


그다음 머 별거없다 젖절하게 셀렉터를 박아주면 된다


여기서는[value=""], +, :not, :focus-widthin 셀렉터로 간단하게 구현했다


암튼 이 코드는 다음처럼 동작한다



js를 사용하는 방식은 이벤트를 엮는 과정이 성가시기 때문에 css로 작성하는 편이 낫다


폴리필을 고려한다면 또 다르긴한데 암튼 그렇다