<html lang="en">
<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>Document</title>
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
<div class="header">
<div class="dropdown" data-dropdown>
<button class="link" data-dropdown-button>Information</button>
<div class="dropdown-menu information-grid">
<div>
<div class="dropdown-heading">Free Tutorials</div>
<div class="dropdown-links">
<a href="#" class="link">All</a>
<a href="#" class="link">Latest</a>
<a href="#" class="link">Popular</a>
</div>
</div>
<div>
<div class="dropdown-heading">Courses</div>
<div class="dropdown-links">
<a href="#" class="link">JavaScript</a>
<a href="#" class="link">CSS</a>
<a href="#" class="link">React</a>
</div>
</div>
<div>
<div class="dropdown-heading">Blog</div>
<div class="dropdown-links">
<a href="#" class="link">All</a>
<a href="#" class="link">Latest</a>
<a href="#" class="link">Popular</a>
</div>
</div>
<div>
<div class="dropdown-heading">Other</div>
<div class="dropdown-links">
<a href="#" class="link">Twitter</a>
<a href="#" class="link">Newsletter</a>
<a href="#" class="link">Discord</a>
</div>
</div>
</div>
</div>
<a href="#" class="link">Pricing</a>
<div class="dropdown" data-dropdown>
<button class="link" data-dropdown-button>Login</button>
<div class="dropdown-menu">
<form class="login-form">
<label for="email">Email</label>
<input type="email" name="email" id="email">
<label for="password">Password</label>
<input type="password" name="password" id="password">
<button type="submit">Login</button>
</form>
</div>
</div>
</div>
</body>
</html>
body {
margin: 0;
}
.header {
background-color: #F3F3F3;
display: flex;
align-items: baseline;
padding: .5rem;
gap: 1rem;
}
.link {
background: none;
border: none;
text-decoration: none;
color: #777;
font-family: inherit;
font-size: inherit;
cursor: pointer;
padding: 0;
}
.dropdown.active>.link,
.link:hover {
color: black;
}
.dropdown {
position: relative;
}
.dropdown-menu {
position: absolute;
left: 0;
top: calc(100% + .25rem);
background-color: white;
padding: .75rem;
border-radius: .25rem;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .1);
opacity: 0;
pointer-events: none;
transform: translateY(-10px);
transition: opacity 150ms ease-in-out, transform 150ms ease-in-out;
}
.dropdown.active>.link+.dropdown-menu {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
.information-grid {
display: grid;
grid-template-columns: repeat(2, max-content);
gap: 2rem;
}
.dropdown-links {
display: flex;
flex-direction: column;
gap: .25rem;
}
.login-form>input {
margin-bottom: .5rem;
}
document.addEventListener("click", e =>{
//CSS Selector를 통해 엘리먼트 구분하기
//해당 엘리먼트와 셀렉터가 같다면 true | 다르다면 false 반환
const isDropdownButton = e.target.matches("[data-dropdown-button]");
// Element의 closest() 메서드는 주어진 CSS 선택자와 일치하는 요소를 찾을 때까지, 자기 자신을 포함해 위쪽(부모 방향, 문서 루트까지)으로 문서 트리를 순회합니다.
//드롭다운 메뉴를 누르면 현재 커서가 위치한 그 메뉴를 찾음.
//만약 누른게 메뉴가 아니며 드롭다운 메뉴였을때. 드롭다운 메뉴가 꺼지지 않게 빈값 반환.
if (!isDropdownButton && e.target.closest("[data-dropdown]") != null) return
let currentDropdown
if(isDropdownButton) {
currentDropdown = e.target.closest("[data-dropdown]")
currentDropdown.classList.toggle("active")
//메뉴 누르면 안의 내부창을 활성화.
}
document.querySelectorAll("[data-dropdown].active").forEach(dropdown => {
if(dropdown === currentDropdown) return
//지금 막 연거 뺴고 나머지는 모두 비활성화. 한번에 하나의 메뉴만 뜨도록.
dropdown.classList.remove("active")
})
})
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.