HTML&CSS

CSS로 반응형 사이드바 메뉴 만들기

apost 2021. 8. 11. 11:11

 

 

자바스크립트 없이 반응형으로 메뉴 크기가 늘어났다 줄어드는 사이드바 메뉴를 만듭니다.

자바스크립트 도움 없이 메뉴를 펼쳤다 닫을 수 있으며, 반응형으로 웹 브라우저 너비에 따라 메뉴의 크기가 조절됩니다.

 

먼저 HTML 코드로 메뉴 목록을 만듭니다.

순서 없는 목록으로 메뉴 목록을 만들고 메뉴 아이콘은 CSS에서 가상 요소로 메뉴 항목의 하이퍼링크(<a>) 태그에 각각 부착합니다.

관리와 유지보수가 더 쉽기 때문에 아이콘 부착은 HTML 태그보다는 CSS로 붙이는 것을 추천합니다.

 

HTML 코드에서 가장 중요한 것은 <input> 태그와 메뉴 목록 표시용 <ul> 태그가 동위에 있는 것입니다.

이렇게 해야 체크박스를 이용해 메뉴 목록을 펼치거나 닫는 상태 제어가 가능해집니다. 자바스크립트 없이 구현하기 위해서는 이런 식으로 상태 제어가 가능한 폼 요소가 있어야 합니다.

 

<div class="menu">
    <label for="expand-menu"><div>메뉴</div></label>
    <input type="checkbox" id="expand-menu" name="expand-menu">
    <ul>
        <li><a href="#" class="item"><div>프로필</div></a></li>
        <li><a href="#" class="item"><div>데이터사용량</div></a></li>
        <li><a href="#" class="item"><div>내URL</div></a></li>
        <li><a href="#" class="item"><div>구매내역</div></a></li>
        <li><a href="#" class="item"><div>추천목록</div></a></li>
        <li><a href="#" class="item"><div>설정</div></a></li>
    </ul>
</div>

 

아이콘은 구글 플랫 아이콘을 가져다 씁니다. 다음 링크를 HTML 헤더에 추가하면 됩니다.

 

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

 

"menu" 클래스가 사이드바 메뉴의 루트 역할을 하며, CSS도 "menu" 클래스를 기준으로 제작하고 하위요소에도 접근합니다.

 

CSS로 아이콘을 먼저 부착합니다.

"label" 태그에 부착하는 아이콘은 반응형으로 축소한 메뉴를 펼치는 용도로 사용하는 전체 메뉴 목록 제어용 체크박스를 위한 아이콘입니다. 자바스크립트 없이 구현하는 펼침 메뉴이기 때문에 체크박스로 상태를 제어하게 됩니다.

 

.menu ::before{
    font-family: 'Material Icons';
    font-size: 1.5em;
    float: left;
    clear: left;
}
.menu label::before{ content: '\e5d2'; }
.menu li:nth-child(1) a::before{ content: '\f02e'; }
.menu li:nth-child(2) a::before{ content: '\e8d6'; }
.menu li:nth-child(3) a::before{ content: '\e88a'; }
.menu li:nth-child(4) a::before{ content: '\e8cc'; }
.menu li:nth-child(5) a::before{ content: '\e87d'; }
.menu li:nth-child(6) a::before{ content: '\e8b8'; }

 

아이콘만 붙어있고 CSS로 레이아웃이 작성되지 않은 상태의 메뉴는 다음과 같은 모습이 됩니다.

 

아이콘만 부착한 HTML 태그 상태의 메뉴

 

먼저 메뉴를 펼쳤다 접는 상태를 관리하는 체크박스 폼 요소를 감추고, 체크박스가 체크되지 않았으면, 그 뒤에 나오는 메뉴 목록을 보이지 않도록 감추는 CSS를 추가합니다.

 

#expand-menu { /* 체크박스 폼 요소 감춤 */
    display: none;
}
#expand-menu:checked ~ ul { /* 체크박스 체크되었으면 메뉴 목록 표시 - 반응형 표시용 */
    display: block;
    height: auto;
}

 

사이드바 모양이 갖추지도록 위치와 여백을 부여해서 메뉴 요소들을 배치합니다.

메뉴 너비가 줄어드는 애니메이션 효과를 부여하기 위해서 "overflow: hidden;"과 "transition: all 0.5s ease;" 속성이 "menu" 클래스에 추가되어 있습니다.

 

 

.menu {
    display: block;
    width: 200px;
    background-color: #000;
    color: #fff;
    border-radius: 20px;
    padding: 10px;
    box-sizing: border-box;
    overflow: hidden; /* 반응형 애니메이션용 */
    transition: all 0.5s ease; /* 반응형 애니메이션 */
}
.menu ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
.menu a, .menu > label {
    display: block;
    height: 25px;
    padding: 8px;
    cursor: pointer;
    color: #fff;
    text-decoration: none;
}

 

마우스가 호버되면 현재 메뉴 항목이 선택되어 보이도록 마우스 호버 반전 처리를 하고, 아이콘과 텍스트 사이를 패딩 값으로 조금 띄워서 배치를 완료합니다.

 

.menu a:hover {
    color: #000;
}
.menu ul li:hover, .menu > label:hover {
    background-color: #fff;
    color: #000;
    border-radius: 10px;
}
.menu div {
    line-height: 1.5;
    font-size: 1em;
    font-family: 'Noto Sans KR';
    padding: 0 0 0 50px; /* 아이콘과 텍스트 사이 여백 */
}

 

완성된 기본 사이드바 메뉴

 

잘 동작하는 기본 사이드바 메뉴가 완성되었으므로, 웹 브라우저 너비에 따라 2단계에 거쳐 반응형으로 메뉴 크기가 변경되는 기능을 추가합니다.

미디어쿼리로 크기를 조절하는 CSS를 추가합니다.

1단계는 너비를 줄여서 메뉴 텍스트 없이 아이콘만 보이도록 합니다. "menu" 클래스 너비를 60px로 줄이면 아이콘만 보이는 상태가 됩니다.

2단계는 메뉴목록 아이콘들도 보이지 않도록 해서 메뉴를 펼치기 위한 아이콘 1개만 표시되도록 합니다. 메뉴 목록 태그를 보이지 않도록 감추면 자동으로 높이가 줄어들면서 메뉴 펼침 아이콘만 남게 됩니다.

 

이때 중요한 추가 처리를 해야 합니다. 메뉴 펼침 아이콘은 체크박스의 기능을 하기 때문에 클릭해서 체크박스가 체크가 된 상태가 되면 메뉴가 펼쳐진 상태로 있어야 하기 때문에 체크박스가 체크되지 않은 상태(":not(:checked))") 일 때만 메뉴 목록이 감추어지도록 해야 합니다. 중요합니다.

 

@media screen and (max-width:1023px) {
    .menu { /* 1단계 */
        width: 60px;
    }
}
@media screen and (max-width:560px) {
    .menu #expand-menu:not(:checked) ~ ul { /* 2단계 */
        display: none;
    }
}

 

웹 브라우저 너비를 변경해가면서 테스트를 해보면 기능적으로는 잘 동작하지만 뭔가 이상합니다.

1단계 메뉴가 축소되는 애니메이션이 진행되면서 텍스트가 말려 내려가는 현상이 생기면서 뭔가 모양이 보기 좋지 않습니다.

 

 

앞서 정의했던 ".menu div" 클래스를 조금 수정해서 텍스트가 말려내려가지 않도록 합니다.

 

.menu div {
    position: absolute; /* 절대 위치로 텍스트 고정 */
    left: 50px;
    line-height: 1.5;
    font-size: 1em;
    font-family: 'Noto Sans KR';
    padding: 0 0 0 20px; /* 패딩 20p로 축소 */
}

 

데스크탑 화면에서도 3선 메뉴 아이콘을 클릭했을 때  2단계 감춤으로 메뉴가 감추어지도록 하려면 앞서 만들었던 560px 이하용 미디어 쿼리의 클래스를 미디어 쿼리 밖으로 이동시키면 됩니다.

 

.menu #expand-menu:not(:checked) ~ ul { /* 데스크탑 화면에서도 메뉴를 접었더 펼칠 수 있음 */
    display: none;
}

 

 

완성된 코드는 다음 다운로드 링크에서 다운로드할 수 있습니다.

 

sidebar.zip
0.00MB