coupang 클론코딩
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>coupang</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<script src="script/script.js"></script>
</head>
<body>
<h1>
<a href="#">
<img src="img/logo.png" alt="coupang logo">
</a>
</h1>
<main>
<form action="#" method="post" id="loginFrm">
<fieldset>
<legend class="skip">로그인양식</legend>
<ul>
<li>
<span class="id_bg"></span>
<span><input type="text" name="user_id" placeholder="아이디(이메일)"></span> </span>
</li>
<li class="error id_error">아이디(이메일)을 입력해주세요.</li>
<li>
<span class="pw_bg"></span>
<span><input type="password" name="user_pw" placeholder="비밀번호"></span>
<span class="pw_show_hide" title="문자보이기"></span>
</li>
<li class="error pw_error">비밀번호를 입력해주세요.</li>
</ul>
<div class="btm">
<p>
<label>
<input type="checkbox" name="login_y" id="login_y">
<span>자동로그인</span>
</label>
</p>
<a href="#" class="idpw_search">아이디(이메일)/비밀번호 찾기</a>
</div>
<button type="submit" id="login_btn">로그인</button>
</fieldset>
</form>
<a herf="#" class="join_link">회원가입</a>
</main>
<footer>
©Coupang Corp. All rights reserved.
</footer>
</body>
</html>
window.onload=function(){
const pw_show_hide = document.querySelector('.pw_show_hide');
const input_id = document.querySelector('input[type=text]');
const input_pw = document.querySelector('input[type=password]');
const id_error = document.querySelector('.id_error');
const pw_error = document.querySelector('.pw_error');
console.log(pw_show_hide, input_id, input_pw, id_error, pw_error);
input_id.addEventListener('click', function(){
id_error.style.display = 'block';
})
input_pw.addEventListener('click', function(){
pw_error.style.display = 'block';
})
let i = true;
pw_show_hide.addEventListener('click', function(){
if(i==true){
pw_show_hide.style.backgroundPosition = '-126px 0'
i=false;
}else{
pw_show_hide.style.backgroundPosition = '-105px 0'
i=true;
}
})
}
/* #0074e9 (파랑) | #e7223d (빨강) */
h1 {text-align: center; margin: 50px auto 30px;}
h1 a {}
h1 a img {width: 200px;}
main {width: 500px; margin: 0 auto;}
main #loginFrm {border-bottom: 1px solid #ccc;
margin-bottom: 20px; padding-bottom: 20px;
}
main #loginFrm fieldset {}
main #loginFrm fieldset ul {}
main #loginFrm fieldset ul li {
border:1px solid #ccc; background: #fff;
display: flex; flex-flow: 10px;
margin-bottom: 10px;
position: relative;
}
main #loginFrm fieldset ul .error {
color: #e7223d; padding:10px; display: none;
}
main #loginFrm fieldset ul .id_error {border:0;}
main #loginFrm fieldset ul .pw_error {border:0;}
main #loginFrm fieldset ul li span {}
main #loginFrm fieldset ul li .id_bg {
border-right: 1px solid #ccc;
padding: 20px; width: 10px;
background-color: #f5f5f5;
position: relative;
}
main #loginFrm fieldset ul li .id_bg::after {
content: ''; display: block;
background-image: url(../img/icon.svg);
background-position: 0 0;
width: 21px; height: 21px;
position: absolute; left: 14px; top: 11px;
}
main #loginFrm fieldset ul li .pw_bg {
border-right: 1px solid #ccc;
padding: 20px; width: 10px;
background-color: #f5f5f5;
position: relative;
}
main #loginFrm fieldset ul li .pw_bg::after {
content: ''; display: block;
background-image: url(../img/icon.svg);
background-position: -21px 0;
width: 21px; height: 21px;
position: absolute; left: 14px; top: 11px;
}
main #loginFrm fieldset ul li span input { width: 400px; height: 40px; border: 0; padding-left: 10px;}
main #loginFrm fieldset ul li span input::placeholder {font-size: 0.95rem; color: #aaa;}
main #loginFrm fieldset ul li span input[type=text] {}
main #loginFrm fieldset ul li span input[type=password] {}
main #loginFrm fieldset ul li .pw_show_hide {
background-image: url(../img/icon.svg);
background-position: -105px 0;
width: 21px; height: 21px;
position: absolute;
right: 11px; top: 8px;
}
main #loginFrm fieldset .btm {
display: flex; flex-flow: row nowrap;
padding: 15px 0; justify-content: space-between;
}
main #loginFrm fieldset .btm p {}
main #loginFrm fieldset .btm p label {}
main #loginFrm fieldset .btm p label input[name=login_y] {appearance: none;}
main #loginFrm fieldset .btm p label input[name=login_y] + span::before {
background: #fff;
border: 1px solid #ccc;
content: ''; display: inline-block;
width:17px; height: 17px;
background-image: url(../img/icon.svg);
background-position: -65px -22px;
margin-right: 5px;
}
main #loginFrm fieldset .btm p label input[name=login_y]:checked + span::before {
background-position: -84px -21px;
}
main #loginFrm fieldset .btm p label span {}
main #loginFrm fieldset .btm .idpw_search {color: #004b96;}
main #loginFrm fieldset .btm .idpw_search::after{
content: '';
display: inline-block;
width: 8px;
height: 15px;
background-image: url(../img/icon.svg);
background-position: -104px -21px;
margin-left: 5px;
}
main #loginFrm fieldset #login_btn {
background: #0074e9;
width: 100%; color: #fff; padding: 20px 0;
box-shadow:0 2px 0 #004b96;
}
main .join_link {
border: 1px solid #aaa; color: #0074e9; padding: 20px 0; width: 100%;
display: block; text-align: center;
background: #fff;
box-shadow: 0 2px 0 #eee;
}
footer {color: #333; text-align: center; font-size: 0.85rem; margin-top: 20px;}
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
1.HTML 파싱 + DOM 트리 생성 (바이트->문자->토큰->노드->DOM)
2.CSS 파싱 + CSSOM 트리 생성 (바이트->문자->토큰->노드->CSSOM)
3.랜더 트리 생성
4.레이아웃(리플로우)
5.페인트(리페인트)
리플로우와 리페인트는 동시에 실행되지 않고 순차적으로 실행됨.
레이아웃의 영향이 없는 변경은 리플로우 없이 리페인트로만 실행됨.
transform과 opacity는 리플로우, 리페인트 생략