코드공부방

구글 로그인 인풋박스(Google Login Inputbox) UI Clone 본문

웹퍼블리셔/UI 클론(Clone)

구글 로그인 인풋박스(Google Login Inputbox) UI Clone

:- ) 2019. 9. 3. 13:25
반응형

구글 로그인 인풋박스(Google Login Inputbox) UI Clone


오래전부터 구글의 로그인폼을 보면 쌈박하다는 생각이 들었다. 요즘은 꽤 대중화된(?) 방식이지만 자칫 딱딱해보일 수 있는 form label에 저런 인터랙션을 넣을 생각을 하다니.. (구글이 최초로 시도한 건지는 모르겠지만..)

 

구글 로그인 페이지

혹시 네이버나 다음도 내가 인지하지 못하고 있는 사이에 바뀌었을까? 라는 생각에 로그인 페이지에 들어가보았다.

 

네이버 로그인 페이지
다음 로그인 페이지

하지만 아주 오래전부터 사용하던 그 것. 내가 알고 있는 form의 딱딱함. 그대로였다. (그 와중에 다음은 로그인페이지에 광고까지 붙여놓았다ㅠㅠ) 물론 로그인페이지의 form에 꼭 인터랙션을 넣는 것이 좋다고 할 수는 없으니 이 얘기는 여기까지 하는걸로 하고 오늘은 구글의 로그인페이지 Inputbox UI를 만들어보려고 한다.


나도 지금까지 많은 사이트를 제작해왔지만 Inputbox에 인터랙션을 넣어본 경험은 전무하다. 대충 생긴걸 보니 input태그와 label태그를 하나의 태그로 묶어서 input focus되면 label의 위치를 positioning하면 될 것 같다는 생각이 들어 바로 작업에 들어갔다.

<!-- html -->
<div class="outBox">
    <div class="inputBox">
        <input type="text" id="sampleId" name="">
        <label for="sampleId">이메일 또는 휴대전화</label>
    </div>
</div>
/* CSS */
.outBox {margin:50px auto; padding:20px; max-width:320px; border:1px solid #999; border-radius:6px;}
.outBox .inputBox {position:relative; height:50px;}
.outBox .inputBox input[type="text"] {padding:0 10px; width:100%; height:50px; font-size:14px; box-sizing:border-box; border:1px solid #999; outline:none;}
.outBox .inputBox label {position:absolute; left:0; bottom:0; padding:0 6px; color:#999; font-size:14px; font-weight:normal; background:#fff; transform:translate(4px, -18px);}
Inputbox에 포커스 됐을때 라인 색상도 바뀌어야 하기 때문에 outline속성값을 none으로 주었다.

label mouse hover 커서 변경

현재까지의 결과물이다. Inputbox위에 label도 잘 위치해 있다. 이제 Inputbox에 마우스 포커싱이 되면 label의 위치만 위로 보내면 되겠지 라고 생각했는데 뭔가 이상했다. label위에 마우스커서가 가면 화살표 모양으로 나오는 것이었다. (어색) Inputbox의 placeholder처럼 보여야 하기때문에 마우스 커서가 변경되면 곤란하다.

 

구글의 label mouse hover

역시 구글은 무엇인가 처리가 되어있는건지 label에 마우스를 올려도 Inputbox의 커서와 동일했다. (자연스럽다) 확인해보니 pointer-events라는 속성에 none값을 주니 커서도 원하는대로 작동됐다. pointer-events 속성에 대한 설명은 다른 포스팅에서 별도로 해봐야겠다. 여기서 사용된 none값은 HTML요소ㅓ에 정의된 클릭 또는 상태(hover, active 등), 커서 옵션들을 비활성화 시킨다. 때문에 label태그에 마우스를 올려도 Inputbox의 커서가 그대로 나오게 된다. 

/* label에 pointer-events속성 추가 */
.outBox .inputBox label {pointer-events:none; position:absolute; left:0; bottom:0; padding:0 6px; color:#999; font-size:14px; font-weight:normal; background:#fff; transform:translate(4px, -18px);}

 


이제 기본적인 모습은 완성이 됐고, 마우스 포커스가 Inputbox에 갔을때 Inputbox에 border 두께, 컬러를 변경하는 것과 label의 위치, 폰트 컬러, 사이즈를 변경해주면 된다. 

.outBox .inputBox input[type="text"]:focus {border:2px solid red;}
.outBox .inputBox input[type="text"]:focus + label {color:red; font-size:12px; transform:translate(-10px, -48px);}

또한 label에 애니메이트 효과를 주기위해 transition속성도 추가하였다.

/* transition 속성 추가 */
.outBox .inputBox label {transition:all .2s; pointer-events:none; position:absolute; left:0; bottom:0; padding:0 6px; color:#999; font-size:14px; font-weight:normal; background:#fff; transform:translate(4px, -18px);}

완성된 폼 inputbox 애니메이션 Ver 1.0(?)

완성되었다. 근데 label의 폰트사이즈가 변화되는 애니메이션이 뭔가 어색한 느낌이 든다. 이는 css의 font-size속성으로 변화를 줬는데 transform속성의 scale값을 조절하니 좀 더 부드러운 애니메이션이 구현되었다.

/* CSS */
.outBox {margin:50px auto; padding:20px; max-width:320px; border:1px solid #999; border-radius:6px;}
.outBox .inputBox {position:relative; height:50px;}
.outBox .inputBox input[type="text"] {padding:0 10px; width:100%; height:50px; font-size:14px; box-sizing:border-box; border:1px solid #999; outline:none;}
.outBox .inputBox label {position:absolute; left:0; bottom:0; padding:0 6px; color:#999; font-size:14px; font-weight:normal; background:#fff; transform:scale(1) translate(4px, -18px); transition:all .15s; pointer-events:none;}
.outBox .inputBox input[type="text"]:focus {border:2px solid red;}
.outBox .inputBox input[type="text"]:focus + label {color:red; transform:scale(.85) translate(-10px, -48px);}

완성된 폼 inputbox 애니메이션 Ver 2.0(?)


여기서 마무리 하려고 했는데 한가지 문제가 더 있었다. Inputbox에 어떠한 내용이 들어가 있으면 label은 올라간 그 위치에 머물러 있고, 내용이 비워지면 다시 원래 자리로 돌아와야 하지만 그 처리가 안되있으니 Inputbox에서 포커싱아웃되면 입력된 내용을 label이 덮는 문제가 생긴 것이다.

 

label이 입력한 내용을 덮는 문제 발생

이를 해결하기 위해서 Javascript를 사용하였다. 원하는 효과는 아래와 같다.
"Inputbox에 포커싱/포커싱아웃 됐을때, 입력된 내용이 있으면 label은 윗쪽에 위치하고, 입력된 내용이 없는 빈 값 상태일때는 label이 원래 위치인 Inputbox쪽으로 내려오게 하면 된다." 
그러기 위해 form을 감싸고 있는 .outBox에 Inputbox의 value값의 유/무에 따라 "existence" 클래스를 토글하기로 한다.

//Javascript
var loginBox = document.querySelector('.outBox');
var loginInputBox = document.querySelector('#sampleId');
loginInputBox.addEventListener('keyup', function(){
    if(!loginInputBox.value == ''){
        //빈 값이 아닌 경우
        loginBox.classList.add('existence');   
    }else{
        //빈 값인 경우
        loginBox.classList.remove('existence');   
    }
});

최초에는 최초에는 loginInputBox에 focus 이벤트를 주었는데, 그렇게하니 실시간으로 값의 유/무를 확인이 안되어 keyup 이벤트로 수정하였다.

 

최종 완성된 폼 inputbox 애니메이션 Ver 3.0(?)

완성되었다. 딱 화면만 봤을때는 매우 간단하게 생각했는데 실제 구현하다보니 몇가지 작은 이슈도 있었고, 난생 처음보는 pointer-events 속성도 사용해 볼 수 있었다.


최종 HTML, CSS, Javascript 코드는 아래와 같다.

<!-- HTML -->
<div class="outBox">
    <div class="inputBox">
        <input type="text" id="sampleId" name="">
        <label for="sampleId">이메일 또는 휴대전화</label>
    </div>
</div>
/* CSS */
.outBox {margin:50px auto; padding:20px; max-width:320px; border:1px solid #999; border-radius:6px;}
.outBox .inputBox {position:relative; height:50px;}
.outBox .inputBox input[type="text"] {padding:0 10px; width:100%; height:50px; font-size:14px; box-sizing:border-box; border:1px solid #999; outline:none;}
.outBox .inputBox label {position:absolute; left:0; bottom:0; padding:0 6px; color:#999; font-size:14px; font-weight:normal; background:#fff; transform:scale(1) translate(4px, -18px); transition:all .15s; pointer-events:none;}
.outBox .inputBox input[type="text"]:focus,
.outBox.existence .inputBox input[type="text"] {border:2px solid red;}
.outBox .inputBox input[type="text"]:focus + label,
.outBox.existence .inputBox label {color:red; transform:scale(.85) translate(-10px, -48px);}
//Javascript
var loginBox = document.querySelector('.outBox');
var loginInputBox = document.querySelector('#sampleId');
loginInputBox.addEventListener('keyup', function(){
    if(!loginInputBox.value == ''){
        loginBox.classList.add('existence');   
    }else{
        loginBox.classList.remove('existence');   
    }
});

2019/09/04 - [JavaScript] - 스크롤 감지하여 고정메뉴 노출/비노출 처리 이벤트

 

스크롤 감지하여 고정메뉴 노출/비노출 처리 이벤트

스크롤 감지하여 고정메뉴 노출/비노출 처리 이벤트 상단, 하단에 모두 고정 메뉴나 콘텐츠가 있는 경우 모바일 환경에서는 콘텐츠를 볼 수 있는 영역이 좁아 부담스러울 수 있다. 따라서 사용자가 스크롤을 올리..

code-study.tistory.com

2019/09/04 - [JavaScript] - 무한스크롤 (Infinity Scroll) UI 구현하기

 

무한스크롤 (Infinity Scroll) UI 구현하기

무한스크롤 (Infinity Scroll) UI 구현하기 쇼핑몰이나 상품 또는 게시글 목록에서 갯수가 많아지면 자연스럽게 페이징(Page nate, pagenation 등으로도 불리운다) 처리를 하게 된다. 근데 PC에서 쓰이는 페이징..

code-study.tistory.com

2019/08/28 - [JavaScript] - 강제로 body 스크롤막기 (PC, Mobile (iOS, Android..) 모든 환경)

 

강제로 body 스크롤막기 (PC, Mobile (iOS, Android..) 모든 환경)

레이어팝업을 띄우면 뒤쪽 콘텐츠의 스크롤을 막아달라는 요청이 간혹 있다. (그냥 스크롤이 가능하게 되길 희망하는 클라이언트도 있다.) /* CSS */ .hidden {height:100%; min-height:100%; overflow:hidden !i..

code-study.tistory.com

2019/08/28 - [CSS] - CSS 반응형 작업 시 박스 비율 유지하기

 

CSS 반응형 작업 시 박스 비율 유지하기

작업을 하다보면 리사이즈 됨에도 박스비율을 유지해야 하는 경우가 있다. (특히 반응형 작업에서) 박스의 width값은 100%로 지정하면 되지만 height값을 어떻게 해야 박스의 비율을 유지할 수 있을까? max-width..

code-study.tistory.com

 

반응형
Comments