JavaScript, HTML 및 CSS를 사용하여 사이드바 메뉴 축소/확장

JavaScript, HTML 및 CSS만 사용하여 사이드바 메뉴를 축소/확장하는 방법을 알아보세요. 이 자습서에서는 버튼을 사용하여 확장 및 축소할 수 있는 완전히 반응하는 사이드바 메뉴를 구축합니다. 이것은 일반적으로 최신 관리 대시보드에서 볼 수 있습니다.

CSS와 JS를 사용하여 사이드바 메뉴를 검색 표시줄/팝업과 함께 놀랍고 기능적으로 보이게 합니다. 또한 반응형 미디어 쿼리를 테스트하고 코딩하여 데스크톱뿐만 아니라 휴대폰에서도 작동하므로 전체 프로젝트에서 사이드바 패널이 멋지게 보일 수 있습니다. 이 튜토리얼은 보기 전용 튜토리얼이지만 전체 프로젝트 탐색의 기초로 사용할 수 있습니다.

YouTube에서 보기





폴더 구조




index.html
/images
   avatar.jpg
   logo.png
   mobile.svg
/sass
   style.scss
/js
   init.js
/css (generated by Sass)
   style.css
   style.min.css


우리의 HTML



이 자습서의 HTML은 매우 간단합니다. 기본적으로 상단과 하단이 있는 사이드바와 페이지 콘텐츠의 메인이 있습니다. 이 튜토리얼에서는 스타일 지정을 위해 BootStrap을 사용하지 않지만 아이콘을 사용할 것이므로 부트스트랩 아이콘 스타일시트에 대한 참조를 추가하거나 자신의 아이콘을 추가하여 해당 아이콘을 사용해야 합니다.

<!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>Collapse / Expand Sidebar Tutorial</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
    <link rel="stylesheet" href="/css/style.min.css">
</head>
<body>
    <div class="container">
        <div class="sidebar">
            <div class="sidebartop">
                <div class="logo">
                    <img src="/images/logo.png" alt="">
                </div>
                <div class="logo-mobile">
                    <img src="/images/mobile.svg" alt="">
                </div>
                <div class="menu">
                    <i class="bi bi-list"></i>
                </div>
            </div>
            <div class="search">
                <form action="">
                    <button type="submit" class="callSearch"><i class="bi bi-search"></i></button><input type="text" placeholder="Search" class="searchInput">
                </form>
            </div>
            <nav>
                <ul>
                    <li><a href="#"><i class="bi bi-speedometer"></i><span class="text">Dashboard</span></a></li>
                    <li><a href="#"><i class="bi bi-file-earmark"></i><span class="text">Pages</span></a></li>
                    <li><a href="#"><i class="bi bi-pencil-square"></i><span class="text">Posts</span></a></li>
                    <li><a href="#"><i class="bi bi-people"></i><span class="text">Users</span></a></li>
                    <li><a href="#"><i class="bi bi-gear"></i><span class="text">Settings</span></a></li>
                </ul>
            </nav>
            <div class="account">
                <div class="avatar">
                    <img src="/images/avatar.jpg" alt="">
                </div>
                <div class="name">
                    <h4>The DevDrawer</h4>
                    Adminstrator
                </div>
                <div class="logout">
                    <a href="#"><i class="bi bi-box-arrow-left"></i></a>
                </div>
            </div>
        </div>
        <div class="main">
            [page content here]
        </div>
    </div>
    <div class="searchWindow">
        <button type="button" class="cancelSearch"><i class="bi bi-x"></i></button>
        <h2>Search Our Site</h2>
        <form action="">
            <input type="text" placeholder="Enter your text">
            <button type="submit">Search</button>
        </form>
    </div>
    <script src="/js/init.js"></script>
</body>
</html>


기본 Sass



스타일시트는 이 튜토리얼의 중요한 부분이므로 아래에 있는 것을 복사하거나 클래스를 사용하여 자신의 브랜딩과 일치하도록 만들 수 있습니다.

많은 스타일이 있지만 다음은 배치 및 레이아웃을 시작하는 데 도움이 됩니다. 글꼴에 Open Sans를 사용하고 있으므로 Google 글꼴에서 직접 가져옵니다.

HTML 코드에서 참조되는 style.css 및 style.min.css를 생성하는 데 도움이 되는 Sass 애드온이 VS Code에 있음을 명심하십시오. 아직 가지고 있지 않다면 여기에서 다운로드할 수 있습니다: https://marketplace.visualstudio.com/items?itemName=glenn2223.live-sass

@import url('https://fonts.googleapis.com/css2?family=Open+Sans&display=swap');

$primary-color:#333;
$white: #fff;

body {
    color:$primary-color;
    padding:0;
    margin:0;
    position: relative;
    min-height:100vh;
    overflow:hidden;
    font-family: 'Open Sans', sans-serif;
    font-size:14px;
}

.container {
    display:flex;
    flex-flow:row wrap;
    .sidebar {
        background-color:$primary-color;
        color:$white;
        width:30%;
        height:100%;
        padding:0 1rem;
        position: fixed;
        top:0;
        left:0;
        transition: width .10s ease-in-out;
        a {
            color:$white;
            text-decoration: none;
        }
        .sidebartop{
            display:flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: flex-start;
            padding-top:1rem;
            height:55px;
            .logo {
                width:70%;
                img {
                    height:auto;
                    width:100%;
                }
            }
            .menu {
                width:20%;
                text-align:end;
                i {
                    cursor:pointer;
                    font-size:1.75rem;
                }
            }
            .logo-mobile {
                display:none;
            }
        }
        .search {
            display:flex;
            flex-direction:row;
            justify-content: space-between;
            align-items: flex-start;
            position: relative;
            margin:1rem 0;
            button {
                cursor:pointer;
                width:auto;
                background-color:transparent;
                border:0;
                color:$white;
                position: absolute;
                font-size:1.25rem;
                left:1.5rem;
                top:50%;
                transform: translate(-50%, -50%);
            }
            input {
                background-color:lighten($primary-color, 5%);
                border:0px;
                padding:1rem;
                border-radius: .5rem;
                width:calc(100% + 1rem);
                &::placeholder {
                    padding-left:1.5rem;
                }
            }
        }
        nav {
            ul {
                padding:0;
                margin:0;
                list-style:none;
                li {
                    display:block;
                    align-items:center;
                    padding:1.25rem 0;
                    position: relative;
                    background-color:transparent;
                    transition: background-color .25s ease-in-out;
                    a {
                        display:block;
                        i {
                            font-size:1.25rem;
                        }
                        .text {
                            position: relative;
                            left:1rem;
                            top:-.2rem;
                        }
                    }
                }
            }
        }
        .account {
            display:flex;
            justify-content: space-between;
            align-content:center;
            align-items:center;
            width:calc(100% - 2rem);
            position: absolute;
            bottom:1rem;
            .avatar {
                margin-right:1rem;
                width:20%;
                img {
                    border-radius:50%;
                    height:50px;
                    width:50px;
                }
            }
            .name {
                flex: 1 1 auto;
                h4 {
                    padding:0;
                    margin:0;
                }
            }
            .logout {
                flex: 1 1 auto;
                text-align: end;
                i {
                    font-size:1.5rem;
                }
            }
        }
    }
    .main {
        margin-left:calc(30% + 2rem);
        padding:1rem;
    }
}


우리 JS



JS는 짧은 클래스를 추가하거나 제거합니다. 기본적으로 메뉴를 클릭하고 축소 또는 확장된 사이드바를 표시하는 본문 클래스를 추가합니다. 아래 코드를 실행하면 HTML 본문에 새 클래스가 추가되는 것을 볼 수 있습니다.

참고: Sass에 short 클래스를 추가하지 않았기 때문에 아직 스타일 변경 사항을 볼 수 없지만 클래스가 추가되는 것을 볼 수 있습니다.

참고: 아래의 JS는 로컬 저장소 항목도 추가하여 사용자를 위해 선택한 사이드바 상태를 유지합니다.

const menu = document.querySelector(".menu"); // get menu item for click event

menu.addEventListener("click", function () {
    expandSidebar();
    showHover();
    getSearch();
});

/**
 * expand sidebar if it is short, otherwise collapse it
 */
function expandSidebar() {
    document.querySelector("body").classList.toggle("short");
    let keepSidebar = document.querySelectorAll("body.short");
    if (keepSidebar.length === 1) {
        localStorage.setItem("keepSidebar", "true");
    } else {
        localStorage.removeItem("keepSidebar");
    }
}

/**
 * show hover effect on sidebar
 */
function showHover() {
    const li = document.querySelectorAll(".short .sidebar li a");
    if (li.length > 0) {
        li.forEach(function (item) {
            item.addEventListener("mouseover", function () {
                const text = item.querySelector(".text");
                text.classList.add("hover");
            });
            item.addEventListener("mouseout", function () {
                const text = item.querySelector(".text");
                text.classList.remove("hover");
            });
        });
    }
}

/**
 * get search button click if short sidebar or mobile
 */
function getSearch() {
    document.querySelector(".callSearch").addEventListener("click", function (e) {
        e.preventDefault();
        if (
            document.querySelector("body").classList.contains("short") ||
            window.innerWidth <= 844
        ) {
            document.querySelector(".searchWindow").classList.toggle("active");
        }
    });
    document
        .querySelector(".cancelSearch")
        .addEventListener("click", function () {
            document.querySelector(".searchWindow").classList.toggle("active");
        });
}

/**
 * check local storage for keep sidebar
 */
function showStoredSidebar() {
    if (localStorage.getItem("keepSidebar") === "true") {
        document.querySelector("body").classList.add("short");
        showHover();
        getSearch();
    }
}

showStoredSidebar(); // show sidebar if stored in local storage



Sass에 짧은 클래스 추가하기



이제 짧은 클래스가 HTML 본문에 추가되었으므로 스타일을 지정해야 합니다. 따라서 style.scss 파일을 열고 맨 아래에 다음을 추가하십시오(현재 CSS 외부).

이 클래스는 축소/확장 모양을 처리하고 사이드바에서 불필요한 항목을 숨깁니다.

.short {
    .sidebar {
        width:5%;
        text-align:center;
        .logo, .searchInput, .text, .avatar, .name {
            display:none;
        }
        .sidebartop {
            display:block;
            height:75px;
            .logo-mobile {
                display:none;
            }
            .menu {
                width:100%;
                text-align:center;
            }
        }
        .text.hover {
            display: block !important;
            background-color:rgba(255,255,255,.9);
            color:$primary-color;
            padding:.5rem;
            box-shadow: 1px 1px 5px 0 rgba(0,0,0,.25);
            position: absolute;
            left:3rem;
            top:1rem;
            border-radius:.25rem;
        }
        .account {
            display:block;
            .logout {
                width:100%;
                text-align:center;
            }
        }
        .search {
            margin:1.75rem -.2rem;
        }
    }
    .main {
        margin-left:calc(5% + 2rem)
    }
}


또한 이제 축소된 사이드바의 아이콘 위로 이동하여 아이콘과 관련된 호버 텍스트를 볼 수 있습니다.

검색 팝업



위 JS에서는 당시 사용하지 않던 검색 기능을 추가했는데, 지금은 해당 화면에서 검색 자체가 불가능하기 때문에 축소된 사이드바 검색 아이콘을 클릭했을 때 팝업을 생성해야 합니다.

따라서 먼저 팝업을 올바르게 표시하기 위해 Sass를 추가해 보겠습니다.

.searchWindow{
    position: fixed;
    height:100vh;
    width:100vw;
    background-color:rgba(51,51,51,.9);
    z-index:1;
    top:0;
    padding:1rem;
    text-align:center;
    color:$white;
    padding-top:20vh;
    display:none;
    input {
        background-color:darken($white, 25%);
        border:0px;
        padding:1rem .5rem;
        border-radius:.5rem;
        width:60vw;
        &::placeholder {
            padding-left:.5rem;
        }
    }
    button {
        background-color:transparent;
        border:2px solid $white;
        font-size:1rem;
        padding:1rem 2rem;
        color:$white;
        border-radius: .5rem;
        cursor:pointer;
        &.cancelSearch {
            border:0px;
            font-size:2rem;
            position: absolute;
            top:0;
            right:2vw;
        }
    }
    &.active {
        display:block;
    }
}



이제 위의 JS 기능과 CSS를 사용하면 축소된 사이드바에서 검색 아이콘을 클릭할 때 검색 창에 대한 팝업이 표시되어야 합니다.

모바일 스타일링



마지막으로 모바일 스타일을 추가해야 합니다. 이 스타일은 모든 유형의 모바일 장치에 적용되지는 않지만 적어도 지금은 iPhone을 포함하는 데 사용할 수 있습니다. 다른 화면 크기를 포함하도록 스타일을 수정할 수 있습니다.

아래에서는 전화기의 수직 및 수평 보기를 다룹니다.

@media (max-width:844px) {
    .container {
        .sidebar {
            width:5%;
            text-align:center;
            .logo, .searchInput, .text, .avatar, .name {
                display:none;
            }
            .sidebartop {
                display:block;
                height:auto;
                .logo-mobile {
                    display:block;
                    img {
                        height:auto;
                        width:80%
                    }
                }
                .menu {
                    display:none;
                }
            }
            nav {
                ul {
                    li {
                        padding:0;
                        a {
                            padding:0.6rem 0;
                        }
                    }
                }
            }
            .account {
                display:block;
                .logout {
                    width:100%;
                    text-align:center;
                }
            }
            .search {
                margin:1.5rem -.2rem;
            }
        }
        .main {
            margin-left:calc(5% + 2rem)
        }
    }
}

@media (max-width:390px) {
    .container {
        .sidebar {
            width:8%;
            nav {
                ul {
                    li {
                        padding:0;
                        a {
                            padding:2rem 0;
                        }
                    }
                }
            }
            .search {
                margin-top:4rem;
                margin-bottom:3rem;
                margin-left:-.5rem;
            }
        }
        .main {
            margin-left:calc(8% + 2rem)
        }
    }
    .searchWindow{
        padding:0;
        padding-top:10vh;
        input {
            width:calc(100% - 2rem);
        }
        button {
            width:calc(100% - 1rem);
            margin-top:.5rem;
        }
    }
}


결론



이제 코드 작업을 완료해야 하며 로컬 저장소 개체에 설정을 유지하고 모바일에서 작동하는 축소 및 확장 가능한 사이드바가 있어야 합니다. 행운을 빕니다.

좋은 웹페이지 즐겨찾기