티스토리 뷰


* 지난번에 이어서 이번에는 HTML과 CSS로 드롭다운(드랍다운/drop down) 가로형 메뉴를 만드는 것을 해보자. 기존에는 플래시를 이용하거나 복잡한 자바스크립트를 사용해야했지만 이제는 CSS와 HTML만으로도 다양한 효과의 드랍다운 메뉴를 만들 수 있게 되었다. 물론 IE9이상 버전이어야 좀 제대로 보이기는 할테지만 CSS를 기반으로 만들게 되면 IE8에서도 투박하기는 하지만 기능은 제대로 동작하게 된다. 지금까지 있었던 그러한 투박한 드랍다운 메뉴를 생각한다면 CSS3를 얕보고 있는것이다. CSS3는 웹개발자 본인의 능력에 따라서 얼마든지 화려한 기능을 부여할 수 있다. 


"물론 CSS3는 IE 사용자인 경우 10버전 이상에 한해서 멋지게 되는 것이지만 말이다. 다른 브라우져는 다 잘된다!"


* IE9이하 버전에서는 애니메이션 기능을 구현하려면 부득이하게 자바스크립트를 사용해야 한다. 이 경우에 대한 구현은 나중에 메인배너 교체 애니메이션을 구현할 때 관련 자바스크립트 라이브러리를 만들면서 구현해볼 것이다.


- 이전 글

2013/11/01 - [밑바닥부터 홈페이지 만들기] 예고편

2013/11/01 - [밑바닥부터 홈페이지 만들기] HTML5 기본 템플릿, DOCTYPE 종류

2014/01/13 - [밑바닥부터 홈페이지 만들기] 최종 목표 예고 - toc21.com

2014/01/15 - [밑바닥부터 홈페이지 만들기] nav, ul, li 태그 HTML과 CSS로 가로형 메뉴 만들기



* 이전 작업

: 이전까지는 마우스오버 메뉴를 만들었었는데, 이번에는 드롭다운 메뉴를 만들어볼 것이다. 일단 지난번에 구현했던 메뉴를 이어서 사용하면 된다. 기존에 구현하던 소스는 아래 글의 맨 아래에 있다.


2014/01/15 - [밑바닥부터 홈페이지 만들기] nav, ul, li 태그 HTML과 CSS로 가로형 메뉴 만들기

아래 간단하게 조금 작은 버전으로 구현해보았으니 아래의 메뉴를 만들고 싶으면 참고하면 될 것이다.




* 드롭다운 항목 추가하기

: 가장 먼저할일은 드롭다운의 서브 메뉴로 보여줄 항목들을 추가하는 것이다. 각 메뉴별로 마우스오버되면 보여줄 서브 메뉴의 항목들을 추가하고 <a> 태그를 추가해서 링크도 만들어두자. 각 상위 메뉴의 하위 메뉴 아래에 해당하는 메뉴들을 쭉 써주면 된다. 만약 하위 메뉴를 만들어주고 싶지 않다면 하위 메뉴를 추가 안 해줘도 된다. 위의 메뉴에서는 LECTURES에 하위 메뉴를 만들고 TAG CLOUD에 하위 메뉴를 만들고 싶으므로 해당 상위 메뉴의 아래에만 하위 메뉴를 만들었다. 

    <nav id="topMenu" >
        <ul>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/category/Programming%20Lecture/%EB%B0%91%EB%B0%94%EB%8B%A5%EB%B6%80%ED%84%B0%20%ED%99%88%ED%8E%98%EC%9D%B4%EC%A7%80%20%EB%A7%8C%EB%93%A4%EA%B8%B0">LECTURES</a>
                <ul class="submenu">
                    <li><a class="submenuLink longLink">속깊은 자바스크립트 강좌</a></li>
                    <li><a class="submenuLink longLink">밑바닥부터 홈페이지 만들기</a></li>
                    <li><a class="submenuLink longLink">안드로이드 앱 개발</a></li>
                </ul>
            </li>
            <li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/guestbook">GUEST BOOK</a>
            </li>
            <li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/tag">TAG CLOUD</a>
                <ul class="submenu">
                    <li><a class="submenuLink">자바스크립트</a></li>
                    <li><a class="submenuLink">K100D</a></li>
                    <li><a class="submenuLink">강좌</a></li>
                </ul>
            </li>
            <li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/media">MEDIA LOG</a>
            </li>
            <li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/location">LOCATION LOG</a>
            </li>
        </ul>
    </nav>




HTML에 각각 필요한 곳에 class를 추가하였고, 중간중간의 상위 메뉴를 구분할 수 있게 상위 메뉴의 li 태그에 topMenuLi class를 추가하였다. 이것을 추가한 이유는 스타일을 #topMenu ul li 를 그대로 사용하게 되면 해당 li가 상위 메뉴의 li인지, 하위 메뉴의 li인지 불분명하기 때문에 서로 다른 스타일을 적용하기 위해서 해준 것이기도 하고, 하위 메뉴에 마우스 오버를 하였을 때 특정 li에 대한 스타일을 변경하기 위하여 적용한 것이기도 하다.



* 드랍다운을 위한 CSS 적용

: CSS의 경우에는 핵심 내용은 hover를 어디에 설정하느냐, 그리고 hover를 하는 경우 height를 변화 시키는 부분이다. 부드럽게 애니메이션을 추가하는 것은 다소 부가적인 기능으로 보면 될 것이다. 간단하게 로직을 설명한다면, 평상시에 하위 메뉴는 기본적으로 높이를 0px로 설정하였다가, 상위 메뉴의 li에 마우스 오버되면 해당 상위 메뉴에 아래에 있는 하위 메뉴의 높이를 93px로 만들어서 보여주게 하는 것이다. 여기서 93px가 나온 기준은 조금 뒤에 다시 설명할 것이다.

    <style>
    #topMenu {
            height: 30px;  /* 메인 메뉴의 높이 */
            width: 850px;  /* 메인 메뉴의 넓이 */
    }
    #topMenu ul {           /* 메인 메뉴 안의 ul을 설정함: 상위메뉴의 ul+하위 메뉴의 ul */
        list-style-type: none;  /* 메인 메뉴 안의 ul 내부의 목록 표시를 없애줌 */
        margin: 0px;            /* 메인 메뉴 안의 ul의 margin을 없앰 */
        padding: 0px;           /* 메인 메뉴 안의 ul의 padding을 없앰 */
    }
    #topMenu ul li {            /* 메인 메뉴 안에 ul 태그 안에 있는 li 태그의 스타일 적용(상위/하위메뉴 모두) */
        color: white;               /* 글씨 색을 흰색으로 설정 */
        background-color: #2d2d2d;  /* 배경 색을 RGB(2D2D2D)로 설정 */
        float: left;                /* 왼쪽으로 나열되도록 설정 */
        line-height: 30px;          /* 텍스트 한 줄의 높이를 30px로 설정 */
        vertical-align: middle;     /* 세로 정렬을 가운데로 설정 */
        text-align: center;         /* 텍스트를 가운데로 정렬 */
        position: relative;         /* 해당 li 태그 내부의 top/left 포지션 초기화 */
    }
    .menuLink, .submenuLink {           /* 상위 메뉴와 하위 메뉴의 a 태그에 공통으로 설정할 스타일 */
        text-decoration:none;               /* a 태그의 꾸밈 효과 제거 */
        display: block;                     /* a 태그의 클릭 범위를 넓힘 */
        width: 150px;                       /* 기본 넓이를 150px로 설정 */
        font-size: 12px;                    /* 폰트 사이즈를 12px로 설정 */
        font-weight: bold;                  /* 폰트를 굵게 설정 */
        font-family: "Trebuchet MS", Dotum; /* 기본 폰트를 영어/한글 순서대로 설정 */
    }
    .menuLink {     /* 상위 메뉴의 글씨색을 흰색으로 설정 */
        color: white;
    }
    .topMenuLi:hover .menuLink {    /* 상위 메뉴의 li에 마우스오버 되었을 때 스타일 설정 */
        color: red;                 /* 글씨 색 빨간색 */
        background-color: #4d4d4d;  /* 배경색을 밝은 회색으로 설정 */
    }
    .submenuLink {          /* 하위 메뉴의 a 태그 스타일 설정 */
        color: #2d2d2d;             /* 글씨 색을 RGB(2D2D2D)로 설정 */
        background-color: white;    /* 배경색을 흰색으로 설정 */
        border: solid 1px black;    /* 테두리를 설정 */
        margin-top: -1px;           /* 위 칸의 하단 테두리와 아래칸의 상단 테두리가 겹쳐지도록 설덩 */
    }
    .longLink {     /* 좀 더 긴 메뉴 스타일 설정 */
        width: 190px;   /* 넓이는 190px로 설정 */
    }
    .submenu {              /* 하위 메뉴 스타일 설정 */
        position: absolute;     /* html의 flow에 영향을 미치지 않게 absolute 설정 */
        height: 0px;            /* 초기 높이는 0px로 설정 */
        overflow: hidden;       /* 실 내용이 높이보다 커지면 해당 내용 감춤 */
        transition: height .2s; /* height를 변화 시켰을 때 0.2초간 변화 되도록 설정(기본) */
        -webkit-transition: height .2s; /* height를 변화 시켰을 때 0.2초간 변화 되도록 설정(구버전 크롬/사파라ㅣ) */
        -moz-transition: height .2s; /* height를 변화 시켰을 때 0.2초간 변화 되도록 설정(구버전 파폭) */
        -o-transition: height .2s; /* height를 변화 시켰을 때 0.2초간 변화 되도록 설정(구버전 오페라) */
    }
    .topMenuLi:hover .submenu { /* 상위 메뉴에 마우스 모버한 경우 그 안의 하위 메뉴 스타일 설정 */
        height: 93px;           /* 높이를 93px로 설정 */
    }
    .submenuLink:hover {        /* 하위 메뉴의 a 태그의 마우스 오버 스타일 설정 */
        color: red;                 /* 글씨색을 빨간색으로 설정 */
        background-color: #dddddd;  /* 배경을 RGB(DDDDDD)로 설정 */
    }
    </style>

: 기존의 단순한 마우스오버 스타일에서 조금 변경된 내용도 있고, topMenuLi 등과 같이 추가적인 동작을 위해서 추가하는 클래스도 있다. 여기서 중간의 .submenu 클래스에 있는 transition은 IE에서는 IE10 이후에 제공해주고, 크롬/파폭/사파리/오페라에서는 각 브라우져 벤더사들의 prefix를 추가해주면 기본적으로 제공해준다. 중요한 것은 transition을 height에 .2초를 기준으로 걸어놓고, 기본 상태에서는 height: 0px, 그리고 overflow: hidden으로 설정해놓고 상위 메뉴가 마우스오버가 되는 경우(.topMenuLi:hover 인 경우) .submenu의 높이를 적절하게 설정한다는 것이다. 여기서 93px가 되는 것은, 각 상단/하단 테두리가 1px씩, 줄 높이가 30px로 3단인 경우 96px인데, 각 .submenuLink에서 margin-top: -1px로 인해 -3이 되어서 각 3단 submenu는 93px가 되는 것이다. 현재는 93px가 되었지만, 만약 하위 메뉴의 개수나 테두리, 줄 높이가 달라지게 되면 해당 값도 다시 산출해야할 것이다.



* CSS3의 transition

: CSS3에서 정의하고 있는 transition은 상당히 매력적인 도구이다. 만약 CSS/HTML이 플래시를 대체할 수 있느냐 여부는 바로 이 transition이 커다란 역할을 하고 있을 것이다. 하지만 현재는 국내에서 대부분의 점유를 차지하고 있는 IE10이상에서만 지원을 해주고 있는 것이 단점이다. 만약 IE9이하 버전에서 호환되게 하고 싶다면 jquery를 사용하는 것이 편할 것이다. 그리고 나중에 메인 배너를 만들 때에 자바스크립트로 Animation을 직접 만들어 보고 이러한 경우에도 응용 가능한 라이브러리를 직접 만들어볼 것이다.


: 아무튼 transition을 사용할 때에 매력적인 점이 있다면, 하위 호환과는 다소 상관없이 동작하도록 할 수 있다는 점이다. IE9이하에서는 지원을 안한다고는 하지만, 해당 태그의 높이가 0px에서 93px로 부드럽게 변환되는 것이 아니라, 순간적으로 바로 93px가 되는 것 뿐이고, <style> 태그 안에 있는 transition과 관련된 스타일들은 그대로 무시된다. 이러한 점이 transition을 사용하게 될 경우에 하위 호환성에 대하여 덜 신경써도 되는 아주 편한 점이다.



* 링크 삽입 및 정리

: 이제 마지막으로 각 하위 메뉴에 링크시킬 링크들을 삽입하고, 마지막 문구를 조정하여 메뉴를 확정시키면 된다. 


	<nav id="topMenu" >
		<ul>
			<li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/category/Programming%20Lecture">LECTURES</a>
                <ul class="submenu">
                    <li><a href="http://unikys.tistory.com/category/Programming%20Lecture/%EC%86%8D%EA%B9%8A%EC%9D%80%20%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%EA%B0%95%EC%A2%8C" class="submenuLink longLink">속깊은 자바스크립트 강좌</a></li>
                    <li><a href="http://unikys.tistory.com/category/Programming%20Lecture/%EB%B0%91%EB%B0%94%EB%8B%A5%EB%B6%80%ED%84%B0%20%ED%99%88%ED%8E%98%EC%9D%B4%EC%A7%80%20%EB%A7%8C%EB%93%A4%EA%B8%B0" class="submenuLink longLink">밑바닥부터 홈페이지 만들기</a></li>
                    <li><a href="http://unikys.tistory.com/category/Programming%20Lecture/Android%28%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%29%20%EC%95%B1%20%EA%B0%9C%EB%B0%9C" class="submenuLink longLink">안드로이드 앱 개발</a></li>
                </ul>
            </li>
			<li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/guestbook">GUEST BOOK</a>
            </li>
			<li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/tag">TAG CLOUD</a>
                <ul class="submenu">
                    <li><a href="http://unikys.tistory.com/tag/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8" class="submenuLink">자바스크립트</a></li>
                    <li><a href="http://unikys.tistory.com/tag/%EA%B0%95%EC%A2%8C" class="submenuLink">강좌</a></li>
                    <li><a href="http://unikys.tistory.com/tag/K100D" class="submenuLink">K100D</a></li>
                </ul>
            </li>
			<li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/media">MEDIA LOG</a>
            </li>
			<li>|</li>
            <li class="topMenuLi">
                <a class="menuLink" href="http://unikys.tistory.com/location">LOCATION LOG</a>
            </li>
		</ul>
	</nav>




* 구현 결과

: 이렇게 구현한 결과의 화면은 아래와 같다.




: IE9버전 이하면 부드럽지 않게 팝업이 보이겠지만, IE10이상 또는 크롬/파폭/사파리/모바일에서는 잘 동작할 것이다. 물론 가장 중요한 하위 메뉴를 보여주는 것은 잘 동작하고 있는 것을 볼 수 있을 것이다. 서브메뉴의 수정은 submenu 클래스 아래에 있는 태그들을 더 추가하거나 하면 메뉴도 바로바로 더 추가가능하고, 위에서 언급한 CSS의 높이만 적절하게 수정해주면 된다. 만약 하위메뉴가 없는 부분에는 태그 아래에 같은 양식으로 그대로 submenu 클래스가 있는 태그들을 추가하면 하위 메뉴는 바로 생기게 되므로 이렇게 css와 html 만으로 메뉴를 만들게 되면 확장과 수정도 아주 편하게 할 수 있다.



css_mouseover_menu[unikys_tistory].html



* 정리 및 trouble shooting

    • 마우스 오버가 잘 안된다면 각 스타일의 hover를 체크한다.
    • 하위 메뉴가 다른 곳에 나타나면 부모의 position을 relative로, 하위 메뉴의 위치를 position:absolute로 설정한다.
    • 하위 메뉴가 약간 옆에 나타난다면 ul과 li의 padding, margin을 0px로 설정한다.
    • 각 상위별로 서로 다른 하위 메뉴 수가 있다면 메뉴별로 id를 부여해서 해당 id 아래의 submenu 높이를 다르게 설정한다. 
    • 이전글에 있는 trouble shooting을 참고한다.

2014/01/15 - [밑바닥부터 홈페이지 만들기] nav, ul, li 태그 HTML과 CSS로 가로형 메뉴 만들기


    • (stcold님 댓글 문의로 추가) IE9이하 버전에서 잘 안된다면 (1) DOCTYPE를 제대로 선언하거나 html5shim을 추가하거나 nav 태그를 div 태그로 수정한다. 이전글의 IE9 이하 HTML5 태그 지원 시키기" 부분과 trouble shooting 참고.
    • (home11님 댓글 문의로 추가) submenu가 세로로 가지 않고 나란히 내려가는 경우에는 여러 가지 문제가 있을 수 있는데, (1) submenuLink의 width를 .submenu와 똑같이 해줘야한다. (2) 메뉴의 넓이 설정은 #topMenu ul li의 width를 설정하지 말고 #topMenuLi와 .submenu li를 통해서 한다. (3) #topMenu ul li에 있는 float:left를 빼고 #topMenuLi에다가 float:left를 추가한다. 등과 같은 해결 방법이 가능하다. 중요한 것은 submenu의 <li>의 width와 그 아래의 <a> 태그의 width가 일치하거나 비슷해야한다는 겁니다.
    • (Jr.J님 댓글 문의로 추가) 상단 메뉴의 글씨 색이 흰색이 아니라 회색이 되는 경우도 다양한 원인이 있을 수 있는데, (1) .menuLink {color: white;} 를 제대로 선언 안해준 경우로 오타, RGB값의 확인이 필요하고, (2) 상단 메뉴의 <a> 태그에 class="menuLink"를 추가 안해준 경우, (3) 다른 스타일이 덮어씌워진 경우가 있을 수 있는데 다른 스타일로 덮어씌워진 경우 .menuLink {color: white !important;} 를 설정하면 해당 css가 가장 우선순위가 높게 되서 글씨색이 흰색이 된다. 하지만 만약 id를 기반으로 important를 쓰는 경우, 예를 들면 #link2 {color:gray !important;} 이런식으로 id에다가 important로 해당 링크의 글씨색을 설정하고 있는 경우가 있다면 위의 class에 important로 설정하는 경우보다 id로 important를 설정하는 스타일이 우선순위가 높으므로 해당 스타일을 없애거나 id를 없애거나, 글씨색을 흰색으로 설정하는 selector를 id급으로 올려서 덮어씌워야한다.



* 다음에는 간단한 마우스 오버 이미지 배너를 만들어보도록 하겠다. 이것을 만들 수 있는 방법은 다양하게 있는데, 각 이미지의 목적이나 중요도에 따라 다르게 구현하는 몇 가지 방법들을 보여줄 것이다.


- 다음글

2014/01/27 - [밑바닥부터 홈페이지 만들기] 마우스 오버 이미지 배너 만들기(CSS, 자바스크립트 등)

2016/06/17 - [밑바닥부터 홈페이지 만들기] HTML과 CSS로 가로 드롭다운 메뉴 만들기

2016/06/?? - HTML과 자바스크립트로 드롭다운 메뉴 만들기

2016/07/?? - 간단한 반응형웹과 모바일용 웹 만들기


 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함