드롭다운 메뉴.

심민기·2022년 5월 13일
0

웹 개발

목록 보기
33/33

<!DOCTYPE html>
<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")
    })
})
profile
왕초보

0개의 댓글