[ CSS / HTML ] menu bar 만들기

2024. 4. 21. 11:50· FRONT-END/└ CSS

환경 : Visual Studio Code

 

 

[ 해당 실습에서 사용한 메뉴바 body 코드 ]

<body>  
    <ul class="menu">
        <li>
            <a href="#">데이터 관리</a>
            <ul>
                <li><a href="#">포켓몬스터</a></li>
                <li><a href="#">사원정보</a></li>
                <li><a href="#">메뉴정보</a></li>
                <li><a href="#">학생성적</a></li>
            </ul>
        </li>
        <li><a href="#">자유게시판</a></li>
        <li class="menu-end">
            <a href="#">관리자메뉴</a>
            <ul>
                <li><a href="#">회원관리</a></li>
                <li><a href="#">충전상품관리</a></li>
                <li>
                    <a href="#">통계</a>
                    <ul>
                        <li><a href="#">포켓몬통계</a></li>
                        <li><a href="#">사원통계</a></li>
                        <li><a href="#">메뉴통계</a></li>
                        <li><a href="#">회원통계</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">로그인</a>
            <ul>
                <li><a href="#">회원가입</a></li>
            </ul>
        </li>
        <li>
           <a href="#">??? 님</a>
           <ul>
                <li><a href="#">마이페이지</a></li>               
                <li><a href="#">포인트충전</a></li>               
                <li><a href="#">로그아웃</a></li>               
           </ul> 
        </li>
    </ul>


</body>
</html>

    (+) Menu : 계층형 구조(tree 구조)이다.

         계층형 구조를 표현하기에 가장 적합한 태그는 <list> 태그 이다.

               └ <ul>은 순서가 없는 리스트 태그이다 (unorder list)

               └ <ol>은 순서가 있는 리스트 태그이다 (order list)

 

 [ 스타일을 추가하여 메뉴바 형태를 구현 해보자 ]

 

   - 스타일이 아무것도 없는 초기 화면 형태

         - <ul>, <ol> 태그를 부여한대로 출력된다.

         - 단, 우리가 원하지도 않은(지정하지도 않은) 마진과 패딩이 자동으로 들어가 있음. -> 초기화 필수

 

 

    - 디자인 초기화

        /* 디자인 초기화 */
        .menu {
            list-style: none; /* list에 표기되는 모양 제거 */
            margin: 0; /* 기본 여백 제거 */
            padding: 0; /* 기본 여백 제거 */
        }

     (+) 이렇게 menu 클래스에 대한 기본 여백을 제거하게 되면, 하위 list 태그들에 대한 여백이 제거되지 않음

                 └ menu 클래스의 모든 ul에 대한 여백을 제거해 줘야 됨

디자인 초기화 과정 1 결과

 

      /* 메뉴 안에 있는 모든 ul태그에 대한 디자인 초기화 */
        .menu,
        .menu ul {
            list-style: none; /* list에 표기되는 모양 제거 */
            margin: 0; /* 기본 여백 제거 */
            padding: 0; /* 기본 여백 제거 */
        }

      (+) menu 클래스와 menu 클래스의 모든 ul 태그에 대한 기본 여백 및 list 표기 모양을 제거하는 식

 

디자인 초기화 과정 2 결과

 (+) 모든 계층의 공백이 전부 제거되었다는 것을 확인 가능

 (+) 계층형인 것이 화면에 보이지 않아도 괜찮음! 이미 코드로 지정해준 것이 화면에 나타나지 않을 뿐임! (문제될 것 없음)

 

 

    - (추가) a태그 모양 변경 + 크기 설정이 가능하도록 inline-block으로 변경

       .menu a {
            color: inherit; /* 글자 색상은 외부 상태를 따라가겠다 */
            text-decoration: none; /* 밑줄 제거 */
            display: inline-block; /* 크기 설정이 가능하도록 변경 */
        }

    (+) 글자 색상은 외부의 스타일 태그를 따라가도록 설정

    (+) a 태그의 밑줄을 제고

    (+) 화면의 보여지는 형태와 크기를 바꾸기 위하여 display 속성을 inline-block 으로 변경

디자인 초기화 결과

 

 

 

 

    - 메뉴들을 가로로 배치해보자

 

메뉴바를 가로로 만들기 위해선 우리가 준 메뉴의 계층 형태를 이해해야 한다. (아래 그림 참고)

 

 

    - 1차 메뉴를 가로로 정렬

1차 메뉴들이 함께 일렬로 가로 배치돼야된다.

       /* 1차 메뉴(.menu > li)를 가로로 배치(배치 모양 변경) */
        .menu > li { /*.menu 클래스의 바로 및(>) li들에게 모두 적용됨!!*/
            display: inline-block;
        }

    (+) menu 클래스 바로 아래 있는 li 태그들에게 inline-block 속성을 적용한다. 

가로로 배치된 메뉴 출력결과

 

    - 1차 메뉴들끼리 연관 배치가 되어야 함

     (+)파란색끼리만 연관 배치.

        /*
            모든 메뉴는 li안에 a와 ul이 있다.
            li끼리는 연관배치, ul은 절대배치를 사용한다
        */
        .menu li {
            position: relative;
        }
        .menu li > ul {
            position: absolute;
        }

    (+) menu 클래스의 li의 position을 relative로 두고, 그 li태그 아래 ul태그들에게 absolute 속성을 부여한다. 

          즉, li끼리는 연관 배치, ul은 절대 배치를 사용한다.

메뉴 가로 정렬 최종 결과

 

 

 

 

     - 메뉴의 글자 크기 및 폭 지정

        /*
            메뉴의 글자크기와 폭을 지정
        */
        .menu,
        .menu ul {
            background-color: black;
        }
        .menu li {
            font-size: 24px;
            width: 200px;
            color: white;
            padding: 0.5em;
            text-align: center;
        }

 

 

 

     - 2차 이상의 메뉴를 숨김 처리 후, 마우스를 올렸을 경우에 보여지도록 처리

        /* 2차 이상의 메뉴(.menu li > ul)를 숨김 처리 */
        .menu li > ul {
            display: none;
        }

        /*
            모든 메뉴(.menu li)에
            마우스가 올라가면(:hover)
            하위 메뉴(ul)를 표시하도록 처리
         */
        .menu li:hover > ul {
            display: block;
        }

        /* 모든 메뉴에 마우스가 올라가면 강조 표시 */
        .menu li:hover {
            background-color: #636e72;
        }

마우스를 올렸을 경우 보여지는 2차 이상의 메뉴들

      (+) 위 결과 화면에서의 문제점 :
           하위 메뉴가 살짝 우측으로 치우쳐져서 나온다.

                → position을 지정해주지 않았기 때문

 

     - 문제점 해결

        /* 2차 메뉴(ul)의 위치를 미세조정 */
        .menu > li > ul {
            top: 100%; /* 위에서 부터 이 영역의 높이만큼 미뤄서 붙여라. */
            left: 0;
        }
        /* 3차 이상의 메뉴(ul)의 위치를 미세조정 */
        .menu > li > ul > li ul {
            top: 0;
            left: 100%;
        }

 

 

 이렇게 하면 모든 구현이 어느정도 완성 되었다.

 

 

 

그런데, 메뉴의 이름이 길어지지게 되면 하나의 메뉴 칸이 늘어나는 현상이 발생한다. (메뉴 칸이 늘어나선 안 됨.)

따라서 말줄임표 처리를 해줘야 된다. 

 

         /* 혹시 메뉴에 글자가 많아서 넘어가는 경우를 말줄임표 처리 */
        .menu a {
            width: 100%;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

      (+) menu 클래스 아래 모든 a태그에 적용

      (+) 글자가 많아지면 보이지 않고, 말줄임표 처리하도록 적용 

 

 

    - (추가) 연관배치가 되어있는 메뉴들 중, 한 가지 메뉴만 오른쪽에 위치시키기

                     └ position을 변경 

        /* menu-end 클래스가 붙은 메뉴 한 개만큼은 우측으로 붙여서 처리 */
        .menu {
            /* 메뉴를 원하는 위치에 배치하고 싶다면 */
            position: relative;

            /* 메뉴를 상단에 고정하고 싶다면 */
            /* position: fixed;
            left: 0;
            right: 0;
            top: 0; */
        }
        .menu li.menu-end {
            position: absolute;
            right: 0;
            top: 0;
        }

    (+) 오른쪽 상단에 위치시키고 싶은 메뉴에 클래스를 부여하여 처리 (menu-end)

    (+) position이 absolute라면 기준이되는 기준 영역을 추가적으로 지정해주어야만 한다.

               → 전체 메뉴 클래스인 .menu에 position을 relative로 설정

               → 만약 fixed로 설정하면, 페이지 내에서 스크롤을 내려도 계속 상단에 고정되어 있게 되는 효과를 줄 수 있다. 

               → relative 혹은 fixed 중 원하는 속성을 부여해주면 된다

실행결과

 

그런데, 이렇게 해주면 또 문제가 발생할 수 있다. 

이전에 3차 이상의 메뉴가 오른쪽으로 나오게끔 설정해주었기 때문에, 만약 3차 이상의 메뉴가 있는 경우 화면에서 보여지지 않는다.

 →  따라서 클래스 명이 menu-end가 붙은 태그들은 3차 이상의 메뉴가 왼쪽에서 보이게끔 해줘야 한다. 

 

        /* 우측 메뉴는 3차 이상의 메뉴가 왼쪽에 나오도록 처리 */
        .menu > li.menu-end > ul > li > ul {
            top: 0;
            left: auto; /* 원래 left 값을 제거 */
            right: 100%;
        }

      (+) 원래 지정해준 left의 값을 제거해준 후 right의 값을 부여해야한다.

              → left의 값을 auto로 설정해야 한다. (none, 0 둘 다 안 됨!!)

3차 메뉴가 있는 메뉴를 오른쪽에 붙인 출력화면

 

 

 

메뉴바 구현 끝!

 

 

 

 

 

개인 공부 기록용입니다:)

728x90