반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji

[Front-End] 로그인 폼(Login Form) 첫번째

반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji
LuckyStrike2021. 1. 7. 0:45

로그인 폼(Login Form) 소스 파일 입니다^^

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login Form Design</title> <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css"> <link rel="stylesheet" href="assets/css/style.css"> </head> <body> <form action="#" class="login-form"> <h2>로그인</h2> <div class="textb"> <input type="text" required> <div class="placeholder">아이디</div> </div> <div class="textb"> <input type="password" required> <div class="placeholder">패스워드</div> <div class="show-password fas fa-eye-slash"></div> </div> <div class="checkbox"> <input type="checkbox"> <div class="fas fa-check"></div> 아이디 저장 </div> <button class="btn fas fa-arrow-right" disabled></button> <a href="#">Can't Sign in?</a> <a href="#">Create Account</a> </form> <script src="assets/js/main.js"></script> </body> </html>

* { margin: 0; padding: 0; box-sizing: border-box; font-family: "Ubuntu", sans-serif; } body { background: url('../images/bg.jpg') no-repeat center; background-size: cover; min-height: 100vh; display: flex; align-items: center; justify-content: center; } .login-form { width: calc(100% - 20px); max-width: 500px; background-color: #fff; padding: 50px 40px; } .login-form h2 { text-align: center; margin: 48px 0; font-size: 2.3rem; color: #111; } .textb { margin-bottom: 12px; position: relative; } .textb input { width: 100%; height: 70px; border: none; background-color: #ededed; border-radius: 4px; color: #333; font-size: 1.0rem; font-weight: 700; padding: 14px 60px 0 10px; } .placeholder { font-size: 1.0rem; font-weight: 700; position: absolute; line-height: 70px; top: 0; left: 20px; color: #9d9d9d; user-select: none; pointer-events: none; } .show-password { position: absolute; right: 20px; line-height: 70px; color: #9d9d9d; font-size: 1.3rem; cursor: pointer; } .textb input:focus ~ .placeholder, .textb input:valid ~ .placeholder { left: 10px; top: -10px; } .checkbox { display: flex; align-items: center; position: relative; font-size: 1.1rem; font-weight: 500; color: #333; margin: 20px 0; } .checkbox input { width: 24px; height: 24px; -webkit-appearance: none; background-color: #ededed; border-radius: 4px; margin-right: 10px; cursor: pointer; } .checkbox .fa-check { position: absolute; color: #fff; font-size: 1.1rem; width: 24px; text-align: center; pointer-events: none; opacity: 0; } .checkbox input:checked { background-color: #bc252a; } .checkbox input:checked + .fa-check { opacity: 1; } .btn { display: block; width: 100px; height: 100px; margin: 40px auto; background-color: #bc252a; color: #fff; font-size: 2.5rem; border: none; border-radius: 30px; cursor: pointer; transition: .3s linear; } .btn:hover { opacity: .85; } .login-form a { display: block; text-align: center; text-decoration: none; font-size: 1.1rem; color: #555; text-transform: uppercase; font-weight: 600; margin-bottom: 8px; transition: .2s linear; } .login-form a:hover { color: #111; } .btn:disabled { background-color: transparent; color: #ddd; border: 2px solid; }

var fields = document.querySelectorAll('.textb input'); var btn = document.querySelector('.btn'); function check() { if( (fields[0].value != '') && (fields[1].value != '') ) { btn.disabled = false; } else { btn.disabled = true; } } fields[0].addEventListener('keyup', check); fields[1].addEventListener('keyup', check); document.querySelector('.show-password').addEventListener('click', function(){ if( this.classList[2] == 'fa-eye-slash' ) { this.classList.remove('fa-eye-slash'); this.classList.add('fa-eye'); fields[1].type = "text"; } else { this.classList.remove('fa-eye'); this.classList.add('fa-eye-slash'); fields[1].type = "password"; } });

반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji

프로젝트 Repository : https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility

Project Status

프로젝트 진행기간 : 🗓️ 2021.02.28(Sun) ~ 2021.03.01(Mon) (2일간)

🗓️ 2021.02.28(Sun)

(1) Issue1) README 파일에 프로젝트 초기 Task 작성하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/1

(2) Issue2) 네이버 로그인 페이지 레이아웃 설계하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/2

(3) Issue3) 웹 표준 및 접근성에 기반한 기존 로그인 페이지의 취약점 분석 및 개선안 정리하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/3

(4) Issue4) BEM 방식으로 element 클래스 이름작성하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/4

(5) Issue10) Initial project setup

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/10

(6) Issue12) 네이버 로그인 페이지 기본 레이아웃 작성하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/12

(7) Issue14) 작성한 기본 레이아웃에 스타일 적용시키기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/14

🗓️ 2021.03.01(Mon)

(8) Issue16) 로그인 상태 유지 및 IP 보안 ON/OFF 체크박스 수정하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/16

(9) Issue5) 개선안 3을 위한 CSS 이벤트 처리관련 조사 및 구현

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/5

(10) Issue19) 반응형 웹 페이지 구현하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/19

(11) Issue21) Project Reflection 작성하기

→ https://github.com/LeeHyungi0622/responsive-naver-login-page-with-web-standards-and-accessibility/issues/21

레이아웃 설계

Contents의 논리적 흐름을 나타내는 논리 구조도와 레이아웃 요소 배치도 작성

반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji
< 네이버 로그인 화면 레이아웃 설계 >

웹 표준 및 접근성에 기반한 취약점 분석 및 개선안

개선안 1)

현재 페이지의 header 부분이 native HTML5 element인 header 태그를 사용하지 않고 div태그에 id로 “header”를 지정하고 있다.
이런 경우에는 native HTML5 element인 header를 사용하거나 div태그내에 ARIA Landmark role로 “banner” 속성값을 지정해주는 것이 좋을 것 같다.
반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji

https://www.w3.org/TR/wai-aria-practices/examples/landmarks/HTML5.html

반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji

개선안 2)

기존 네이버 로그인 페이지의 contents의 논리적 흐름을 살펴보면 하단의 표에서 가장 좌측(개선안 적용 전)과 같은 순서로 이동하는 것을 알 수 있다. 각 contents의 순서상의 개선안과 태그 속성상의 개선안을 생각해보았다.
생각해 본 개선안을 적용한 후의 결과는 하단의 표에서 가장 우측(개선안 적용 후)와 같은 결과로 변경된다.
반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji

개선안 3)

하나의 input tag에는 하나의 의미있는 label을 mapping 시켜주도록 개선하자.

https://www.w3.org/TR/WCAG20-TECHS/H44.html

현재 네이버의 로그인 화면에서 id와 password 입력란을 보면, <label> 태그에는 z-index값이 8, <input> 태그에는 z-index값이 9 로 지정되어 있다. 따라서 화면 배치상 <label> 태그는 항상 <input> 태그의 뒤에 위치하게 되므로 <label> 태그에 표시된 내용은 의미가 없다. 결국에 <input> 태그의 placeholder에 넣어준 텍스트만 <input> 태그에 표시되는 것이다. 이렇게 되면, 경우에 따라 스크린 리더가 input태그의 뒤에 숨겨진 label의 텍스트와 placeholder 텍스트를 연달아서 두 번 읽어주게 된다.

조사를 해보니, JAWS와 NVDA와 같은 스크린 리더의 경우에는 placeholder를 읽어주지 않는다고 한다. 지금은 단순히 아이디와 패스워드를 입력하는 <input>태그를 다루고 있지만 만약에 구체적인 format의 데이터 입력을 요구하는 경우에는 반드시 시각장애인이 해당 입력 태그에 어떤 format의 데이터를 입력해줘야 하는지를 알려줘야 한다.

스크린 리더에 따라 읽어주기도 하고, 읽어주지 않기도 한다면 안정적으로 placeholder가 아닌 label에 입력해야하는 데이터에 대한 정보를 넣어주고, <input>태그의 위에 중첩시켜서 마치 placeholder와 같이 표시해준다음 입력 태그에 input cursor가 focus되는 경우, label 텍스트를 축소시켜서 입력태그의 상단에 표시될 수 있도록 CSS 효과를 주는 것도 좋은 방법인 것 같다.

(구체적인 데이터의 입력 format은 경우에 따라 placeholder에 입력해서 처리해주면 된다)

반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji
반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji

BEM 방식으로 element의 클래스 이름 작성하기

반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji
< BEM 방식으로 클래스 이름 정하기 >

네이버 로그인 페이지 기본 레이아웃 작성하기

반응형 로그인 페이지 - ban-eunghyeong logeu-in peiji

기본 레이아웃에 스타일 적용하기

개선안 3) 하나의 input tag에는 하나의 의미있는 label을 mapping 시켜주도록 개선한다.

입력 태그에 CSS 이벤트 구현

기존에는 label 태그를 input 태그의 뒤에 z-index 속성을 사용하여 보이지 않도록 처리하였다.
개선한 부분은 input 태그의 placeholder에 표시한 hint 텍스트를 label 태그에 표시하도록 수정하였다.

표시된 label 태그는 input 태그가 focus 상태일 때와 valid 상태일 때, out-focusing 상태일 때 보다 글자 크기를 작게 하여 좌측 상단에 배치될 수 있도록 이벤트 처리하였다.

이렇게 되면 기존에는 경우에 따라 label의 텍스트와 placeholder의 텍스트 모두 스크린 리더가 읽어주는 경우가 생기는데 이를 해결할 수 있으며, 태그와 placeholder의 역할을 분리해야 되는 경우(입력해야 되는 데이터의 format을 알려줘야 하는 경우)를 해결할 수 있다고 생각한다.

반응형 웹 페이지 구현(Responsive web page)