행주기씨대종중

홈페이지 관리/운영 자료

홈페이지메뉴만들기

페이지 정보

profile_image
작성자 관리자
댓글 0건 조회 14,782회 작성일 21-02-22 12:27

본문

HTML5 기본 템플릿, DOCTYPE 종류

* 홈페이지를 밑바닥부터 만들 때 가장 먼저 해야할 것은 기본 틀을 만들어두는 것이다. 이제 거의 모든 브라우져들이 HTML5를 지원해주므로 HTML5에서 사용하고 있는 기본 템플릿을 살펴보자.

* Zen-coding의 HTML5 템플릿

: 웹 개발을 하는데 잘 쓰면 유용한 개발 플러그인 중에 Zen-coding이라는 플러그인이 있다. 이 플러그인은 코딩을 단축키의 연속으로 하듯이 간단한 문자열로 소스코드를 바로바로 생성할 수 있는 플러그인이다. 이러한 Zen-coding에서 HTML5용 템플릿을 생성하면 아래와 같은 템플릿이 나오게 된다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="utf-8"/>
    <title></title>
</head>
<body>
</body>
</html>

: 나중에 기회가 되면 이 플러그인에 대해서 별도로 다루기로 하고, 우선 이 템플릿의 틀을 기본으로 삼고 자신의 홈페이지에 맞는 설정을 하면 될 것이다. 먼저 각각의 줄이 의미하는 바를 하나씩 따져보도록 하자.

* DOCTYPE 태그

<!DOCTYPE html>

: 가장 위에 나오는 이 태그는 현재 문서가 어떠한 문서인지 선언하는 태그이다. DOCument TYPE 의 약자로 이해하면 바로 쉽게 이해될 것이다. 여기서 문서 타입은 바로 뒤에 나온 "html"로 현재 문서는 HTML5를 기반으로 작성하겠다는 것이다. 이 DOCTYPE 태그의 뒤에 들어갈 수 있는 종류는 아래와 같으므로, 자신이 사용하고자하는 웹페이지의 종류를 고려해서 사용하면 된다. 잘 모르겠다 하면, html만 써도 기본적인 태그들은 다 하위호환해주므로 문제 없을 것이다.

HTML 버전
<!DOCTYPE 선언>
설명
HTML5
<!DOCTYPE html>
HTML5
HTML 4.01 Strict
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

HTML 4.01 Transitional
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
font 등 deprecated 태그 호환 가능, frameset 사용 불가
HTML 4.01 Frameset
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
frameset 태그도 호환
XHTML 1.0 Strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Deprecated 태그 사용 불가, XML 작성 규격을 따름
XHTML 1.0 Transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
frameset 사용 불가, XML 작성 규격을 따름
XHTML 1.0 Frameset
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
frameset 사용 가능, XML 작성 규격을 따름
XHTML 1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1.0 Strict에 모듈 추가 가능

: 이 DOCTYPE 태그를 사용 안 한다면, IE에서는 Quirk 모드로 들어가게 되는데, 이 모드에서는 원래와는 다른 랜더링 방식을 사용하니 예상하고 있는 모양과는 다른 모양이 나오게 될 것이다. 따라서, 원하는 모양대로 웹페이지를 보여주고 싶다면, 이 DOCTYPE을 명확하게 본인이 사용하고 있는 HTML 버전에 맞게 설정해야한다.

* HTML 태그
: html 태그는 DOCTYPE 바로 아래에 오게 되며, HTML5에서는 lang이라는 attribute를 사용하고 있는 것을 확인할 수 있다. 이 속성은 필수는 아니지만, 현재 페이지가 어떠한 언어로 되어있는지 명시해주는 것이므로 브라우져에서 어떠한 언어로 해당 웹페이지가 구성되어있는지 알려준다. 해당하는 언어의 코드 ko는 한국어로, 다른 나라의 언어로 하고자한다면, ISO 639-1에 나와있는 언어 목록을 참고한다. http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
: 그리고 ko-kr이나 en-us 처럼 언어의 뒤에 -를 붙이고 어느 나라 코드를 입력해도 된다. 해당 html 안의 lang 속성은 웹접근성에서 체크리스트 중 하나이기도 하므로, 반드시 작성하는 것을 습관 들이자.

<html lang="ko">
</html>

* HEAD 태그
: head 태그는 말머리 태그로 생각하면 되며, 하위 태그를 사용해서 현재 웹페이지에 대한 메타정보나 제목 등을 설정할 수 있다. 아래가 템플릿으로 생성된 태그들이다.

<head>
    <meta charset="utf-8"/>
    <title></title>
</head>
: 여기서 meta 태그의 charset 속성을 설정함으로써 현재 웹페이지를 브라우져에서 어떠한 인코딩으로 읽어야하는지 결정할 수 있다. 일단 utf-8로 설정했는데, 하나의 인코딩 방법을 결정하게 되면 이후 모든 웹서버, DB, 소스 파일까지 인코딩을 통일해서 작성해야 이유 모를 오류나 캐릭터 깨짐이 나타나지 않을 것이므로 모든 환경설정을 고려해서 설정하도록 하자. 그 다음은 title 태그로 title 태그 안에 현재 웹페이지에서 보여주고 싶은 제목을 설정하면, 브라우져에서나 즐겨찾기 등을 할 때 해당 제목이 보여진다. 이후 개발을 하다가 사용하게 될 자바스크립트의 script 태그나 css의 link 태그들을 head에 추가해서 사용하면 된다.

* BODY 태그
: body 태그는 이후 주로 개발을 하게 될 태그로 웹페이지의 내용이 이 부분에 들어가게 된다. 처음에만 한번 만들고나면 다시 볼일이 거의 없을 것이다.

<body>
</body>

* 템플릿을 기반으로 기본 틀 만들기
: 이 템플릿을 기반으로 몇가지 필요한 태그들을 추가하여 기본 페이지를 만들어보자. 해당 페이지는 이후 php를 사용하게 될 것이므로 index.php로 저장을 하고 제목과 현재 페이지에 대하여 요약하고 있는 meta 태그들을 몇가지 추가했다.

<!DOCTYPE html>
<html lang="ko-KR">
<head>
    <meta charset="utf-8"/>
    <meta name="description" content="The Overflowing church website's main page" />
    <meta name="author" content="unikys@gmail.com" />
    <title>The Overflowing Church</title>
</head>
<body>
    This site is under construction!
</body>
</html>
: 개발중이므로 간단하게 개발중이라는 문구를 띄워놨고, meta 태그로 추가한 것이 2가지가 있는데 하나씩 살펴보면,

<meta name="description" content="The Overflowing church website's main page"/>
: 이 태그는 현재 웹페이지에 대하여 요약하고 있는 태그로, name="description"이라는 속성을 추가하고, content=""에다가 현재 페이지에 대하여 설명을 달아주면 이 정보를 검색엔진들이 가져다가 사용한다.

<meta name="author" content="unikys@gmail.com" />
: 다음은 name="author"로 설정 되어있는 meta 태그로 현재 페이지의 작성자를 적어준다. 어딘가 웹개발을 도와줄 때 나의 이름을 슬그머니 남기고 싶다면 이 태그를 적극적으로 활용한다. 전면에는 내 이름이 없지만, 소스에 나의 이름을 남겨놓는게 조금은 더 보람과 책임감을 느낄 수 있게 될 것이다.

nav, ul, li 태그 HTML과 CSS로 가로형 메뉴 만들기

* 웹사이트의 대략적인 구조를 받기 전에 어느 웹페이지에 적용할만한 메뉴를 html과 css로 만들어보자. 드랍다운 메뉴나 마우스오버와 같은 추가적인 기능은 디자이너와 기획자가 기능을 결정해서 오면 구현하기로 하고 일단 기본 틀을 만들어 놓자. 아래가 지난번까지 작업했던 html의 템플릿 소스이다.
<!DOCTYPE html>
<html lang="ko-KR">
<head>
    <meta charset="utf-8"/>
    <meta name="description" content="The Overflowing church website's main page" />
    <meta name="author" content="unikys@gmail.com" />
    <title>The Overflowing Church</title>
</head>
<body>
    This site is under construction!
</body>
</html>

* <nav> 태그
: html5에서 <nav> 태그는 현재 웹 사이트에서 주요한 지점으로 이동할 수 있는 네비게이션(NAVigation) 역할을 담당하고 있는 태그이다. 예전에는 메뉴든 뭐든 전부다 div에 넣는 것이 일반적이었지만, 이제 div는 일반적으로 떠다니는 내용을 넣을 때의 역할을 하는 경우가 많아졌고, html5에서는 각 영역별로 그 의미를 나타내기 위하여 <nav> 태그와 같은 특정 태그를 사용하게 되었다. 일반적으로 웹사이트에서 주요한 네비게이션은 바로 '메뉴'일 것이다. 따라서 이러한 메뉴를 <nav> 태그로 만들어보도록 하자.

* <nav> 태그로 메뉴 만들 때의 html 템플릿
: 최근 <nav> 태그로 메뉴를 만들 때에는 기본적으로 <ul>과 <li> 태그를 이용하는 것이 일반적이다. 왜냐하면 목록은 순서가 중요하지 않은 목록이기 때문에 <ul> 태그를 사용하는 것이다. 그리고 각 목록의 항목들을 나타내는 <li> 태그의 안에는 메뉴 <a> 태그로 메뉴들의 링크를 만들어두는 것이 기본적인 템플릿이다. 아래와 같이 작성할 수 있다.

        <nav>
              <ul>
                  <li><a href="#">About us</a></li>
                  <li><a href="#">Ministries</a></li>
                  <li><a href="#">Community</a></li>
                  <li><a href="#">Locations</a></li>
                  <li><a href="#">Blog</a></li>
              </ul>
        </nav>
: 위처럼 작성하서 페이지를 확인해보자.

: 이런 단순한 모양은 CSS를 적용하지 않았을 때 reader로 봤을때 나오게 되는 순수한 모습이다. HTML5와 CSS를 적용해서 홈페이지를 만들었을 때에는 'CSS가 없어도 홈페이지의 내용을 알고 이해할 수 있어야 한다'. 처음에는 이러한 모양에서 CSS를 어떻게 입혀야할 지 애매하지만, 몇 번 하다보면 금방 익숙하게 처리가 가능해진다.

* CSS로 메뉴 모양 만들어주기
: 그럼 이제는 CSS로 모양을 만들고 스타일을 입혀주자. 가로 메뉴를 만들려고 하고 있고, 색은 흑백 반전식으로 하고 싶다. 그렇다면 아래와 같이 차근차근 CSS를 적용해보자. 먼저 CSS를 만들기 전에 위의 템플릿에 있는 태그들이 스타일을 적용하기 쉽게 만들어주자.

        <nav id="topMenu" >
                <ul>
                        <li><a class="menuLink" href="#">About us</a></li>
                        <li><a class="menuLink" href="#">Ministries</a></li>
                        <li><a class="menuLink" href="#">Community</a></li>
                        <li><a class="menuLink" href="#">Locations</a></li>
                        <li><a class="menuLink" href="#">Blog</a></li>
                </ul>
        </nav>
: <a>의 태그는 여러개에 같은 CSS를 적용하고자 하니 class 속성을 부여하고, <nav> 태그는 고유한 하나의 상단 메뉴가 될 것이므로 id를 부여하자. 그리고 하나씩 필요한 CSS를 맞춰나가자. 먼저 <li> 태그의 목록 표시를 없애주자. <head>태그에 <style> 시트를 추가해서 한번 적용시켜보자. 이러한 내용을 헤더에다가 추가하면 된다. id로 설정된 태그의 스타일을 지정할 때에는 #을 해당 아이디의 앞에 붙이면 되고 클래스는 .을 해당 아이디 앞에 붙이면 된다. 한번에 여러 아이디/클래스/태그명을 같이 붙일 수 있으며, 이러한 경우 상하 관계로 설정이 가능한 것이다. 각 css를 line-by-line으로 적용하면 효과를 표시해주려고 했는데 너무 길어질 것 같아서, 각 라인별로 어떠한 역할을 하는지 주석을 달아놨다.

<style>
 #topMenu { // topMenu의 ID를 가진 태그의 스타일 지정
  height: 30px; //topMenu의 높이를 30px로 설정(잘못 설정하면 아래 내용이 깨짐)
  width: 850px; //topMenu의 넓이를 850px (잘못 설정하면 브라우져 넓이가 좁아지면 깨짐)
            }
 #topMenu ul li { // topMenu의 ID를 가진 태그 안에 <ul> 태그 안에 <li> 태그의 스타일을 지정
  list-style: none; // <li> 태그는 위의 이미지처럼 목록을 나타내는 점을 없앤다
  color: white; // 글씨 색을 흰색으로 설정
  background-color: #2d2d2d;  // 배경색을 진한 회색(RGB(2D,2D,2D)으로 설정
  float: left; // <li>태그들이 왼쪽에 흐르게 설정(그러면 아래있는 내용은 오른쪽으로 옴)
  line-height: 30px; // 글씨가 가운데로 오도록 설정하기 위해 한줄의 높이를 30px로 설정
  vertical-align: middle; // 세로 정렬을 가운데로 설정(위의 line-height와 같이 설정 필요함)
  text-align: center; // 글씨 정렬을 가운데로 설정
              }
 #topMenu .menuLink { // topMenu 아이디 태그 안의 menuLink 클래스 태그들의 스타일 설정
  text-decoration:none; // 링크(<a> 태그)가 가지는 기본 꾸밈 효과(밑줄 등)을 없앰
  color: white; // 폰트색을 흰색으로 설정
  display: block; // 링크를 글씨뿐만 아니라 전체 영역을 클릭해도 링크가 걸리게 설정
  width: 150px; // 메뉴링크의 넓이 설정
  font-size: 12px; // 폰트 사이즈 12px로 설정
  font-weight: bold; // 폰트를 굵게
  font-family: "Trebuchet MS", Dotum, Arial; // 기본폰트 적용, 시스템폰트를 종류별로 순서대로
              }
 #topMenu .menuLink:hover { //topMenu 아이디 태그 안의 menuLink클래스 태그에 마우스가 over되면 스타일 설정
  color: red; // 글씨 색을 붉은색으로 설정
  background-color: #4d4d4d; // 배경색을 조금 더 밝은 회색으로 설정
                              }
</style>

* 구현 내용 확인
: 이렇게 구성을 하고 브라우져로 열어보면 다음과 같이 보이게 된다. (메뉴는 다소 바뀌었다.)


: 그리고 마우스오버를 해보면 아래와 같이 hover로 설정한 글씨 색과 조금 더 밝은 바탕화면색으로 변경되는 것을 확인할 수 있다.


: 이렇게 구현을 해봤으면 '반드시' 여러 브라우져에서 띄워서 같이 확인을 하는 습관을 들이면 좋을 것이다. 아래는 크롬에서도 확인을 해본 것이다. 일반적으로 IE와 크롬이 두 가지를 체크하곤 하지만, 추가로 서버에 올려놓고 모바일 브라우져에서도 확인하면 좋을 것이다.


: IE에서 테스트할 때 중요한 것은 IE는 버전별로도 다르게 보이기 때문에 항상 버전별로도 테스트를 하면 좋다는 것이다. IE9 이후에서 메뉴의 도구>개발자툴(또는 F12 단축키)에서 선택.


: 그러면 위에서 정상적으로 보이던 것이 아래와 같이 나오게 된다..! 이러한 현상들이 바로 여러 브라우져 버전에서 다 잘 나오는지 테스트를 해야하는 이유이다. 모든 사람들이 같은 브라우져를 쓰는 것이 아니므로 최대한 많은 사람들에게 정상적인 사이트를 보여주면 좋다.



* IE9이하 HTML5 태그 지원 시키기
: <nav> 태그는 html5에서 새로 나온 태그로 기존의 IE(Internet Explorer) 버전들에서는 다른 브라우져들과 다르게 인식을 하게 된다. IE9 이전 버전에서는 "불명의 태그에 대하여 CSS 적용"이 정상적으로 안된다. 따라서 브라우져의 호환성을 위하여 IE에서도 이러한 태그들을 인식할 수 있도록 해줘야한다. 그러한 역할을 하는 라이브러리는 html5shiv 또는 html5shim 이다.

https://code.google.com/p/html5shiv/
https://code.google.com/p/html5shim/
: 이 두가지 간의 차이는 오로지 v로 끝냐느냐, m으로 끝나느냐의 차이 뿐이라 어느것을 사용해도 상관이 없다. <body> 태그보다 위에 반드시 넣어야하며, css와의 위치는 상관이 없으나 css를 먼저 가져오는 것이 퍼포먼스상 유리하다고 한다. 따라서, 아래의 태그를 <head> 안의 제일 아래에 배치해두면 된다.

<!--[if lt IE 9]>
  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
: 위의 조건문에서 IE9버전 이하의 버전인 경우 HTML5의 태그들을 인식하지 못하여 CSS를 적용하지 못하므로 인식할 수 있는 작업을 미리 해두고 있는 것이다. 만약 IE9이상 버전이거나 다른 브라우져면 위의 소스는 주석으로 인식하고 무시하게 된다.

* IE9이하 버전 수정한 것 확인
: 이제 IE9버전 이하에서도 잘 보이는지 확인해보자.
 

: 이제 IE8에서도 제대로 보여준다! 상단의 가로형 메뉴는 이렇게 아주 간단하게 HTML 몇 줄과CSS를 통해서 만들 수 있게 되었다.

* 메뉴 마무리
: 이제 각 a태그의 href에 메뉴별로 링크 시키고 싶은 페이지를 링크 시키면 된다. 첨부파일로 위의 구현 내용을 첨부하니 파일 내용을 참고하면 될 것이다.

<nav id="topMenu" >
 <ul>
  <li><a class="menuLink" href="http://unikys.tistory.com/category">LECTURES</a></li>
  <li>|</li>
  <li><a class="menuLink" href="http://unikys.tistory.com/guestbook">GUEST BOOK</a></li>
  <li>|</li>
  <li><a class="menuLink" href="http://unikys.tistory.com/tag">TAG CLOUD</a></li>
  <li>|</li>
  <li><a class="menuLink" href="http://unikys.tistory.com/media">MEDIA LOG</a></li>
  <li>|</li>
  <li><a class="menuLink" href="http://unikys.tistory.com/location">LOCATION LOG</a></li>
 </ul>
</nav>
 
* 정리 및 trouble shooting
 만약 li들이 나열되다가 아래로 내려온다면 부모 태그(nav)의 width와 height를 적절하게 설정한다.
 만약 하단의 내용들이 상단 메뉴 옆으로 올라온다면 nav의 height를 설정한다.
 메뉴의 폰트가 세로 정렬이 안되면 vertical-align:middle과 line-height를 적당한 높이로 설정한다
 만약 IE 낮은 버전에서 스타일이 깨진다면 html5shim을 추가한다.
 모든 IE 버전에서 스타일이 깨진다면 DOCTYPE을 제대로 선언한다.
 마우스오버가 동작 안한다면 .menuLink:hover 이렇게 붙여서 선언한다.
 CSS와 HTML만으로 마우스오버 가로형 메뉴를 아주 쉽게 만들 수 있다!
 정확한 픽셀 값(각 메뉴 칸별로 가로/세로 그리드 등)과 각 폰트/배경의 RGB 값이 중요.

HTML과 CSS로 드롭다운 메뉴 만들기

* 이번에는 HTML과 CSS로 드롭다운(드랍다운/drop down) 가로형 메뉴를 만드는 것을 해보자. 기존에는 플래시를 이용하거나 복잡한 자바스크립트를 사용해야했지만 이제는 CSS와 HTML만으로도 다양한 효과의 드랍다운 메뉴를 만들 수 있게 되었다. "물론 CSS3는 IE 사용자인 경우 10버전 이상에 한해서 멋지게 되는 것이지만 말이다. 다른 브라우져는 다 잘된다!"
* IE9이하 버전에서는 애니메이션 기능을 구현하려면 부득이하게 자바스크립트를 사용해야 한다.
* 이전 작업
: 전까지는 마우스오버 메뉴를 만들었었는데, 이번에는 드롭다운 메뉴를 만들어볼 것이다. 일단 지난번에 구현했던 메뉴를 이어서 사용하면 된다. 기존에 구현하던 소스는 아래 글의 맨 아래에 있다.
* 드롭다운 항목 추가하기
: 가장 먼저할일은 드롭다운의 서브 메뉴로 보여줄 항목들을 추가하는 것이다. 각 메뉴별로 마우스오버되면 보여줄 서브 메뉴의 항목들을 추가하고 <a> 태그를 추가해서 링크도 만들어두자. 각 상위 메뉴의 하위 메뉴 아래에 해당하는 메뉴들을 쭉 써주면 된다. 만약 하위 메뉴를 만들어주고 싶지 않다면 하위 메뉴를 추가 안 해줘도 된다. 위의 메뉴에서는 LECTURES에 하위 메뉴를 만들고 TAG CLOUD에 하위 메뉴를 만들고 싶으므로 해당 상위 메뉴의 아래에만 하위 메뉴를 만들었다.

<nav id="topMenu" >
 <ul>
  <li class="topMenuLi">
  <a class="menuLink" href="http://unikys.tistory.com/category">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이 플래시를 대체할 수 있느냐 하는 역할을 하고 있다. 하지만 현재는 국내에서 대부분의 점유를 차지하고 있는 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">LECTURES</a>
    <ul class="submenu">
    <li><a href="http://unikys.tistory.com/category/A" class="submenuLink longLink">강좌</a></li>
    <li><a href="http://unikys.tistory.com/category/B" class="submenuLink longLink">만들기</a></li>
    <li><a href="http://unikys.tistory.com/category/C" 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/A" class="submenuLink">자바스크립트</a></li>
    <li><a href="http://unikys.tistory.com/tag/B" 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 만으로 메뉴를 만들게 되면 확장과 수정도 아주 편하게 할 수 있다.
* 정리 및 trouble shooting
마우스 오버가 잘 안된다면 각 스타일의 hover를 확인한다.
하위메뉴가 다른 곳에 나타나면 부모의 position을 relative로, 하위메뉴의 위치를 position:absolute로 설정한다.
하위메뉴가 약간 옆에 나타난다면 ul과 li의 padding, margin을 0px로 설정한다.
각 상위별로 서로 다른 하위메뉴 수가 있다면 메뉴별로 id를 부여해서 해당 id 아래의 submenu 높이를 다르게 설정한다.
메뉴 전체를 가운데나 왼쪽으로 보내고 싶은데 float가 안먹히면 wrapper <div>를 하나를 만들어서 둘러 싼 다음 해당 wrapper <div> 의 위치를 변경하면 된다.
각 메뉴의 텍스트로 있는 <a> 태그 안의 텍스트에 <img> 태그를 위치하면 img src가 동일하게 동작할 것이다.
상위메뉴 hover 시 하위메뉴가 발생되고 마우스를 하위메뉴로 이동시에 상위메뉴 hover 설정값들이 없어진다면 자식 엘레멘트에서 이벤트가 발생하면 동일하게 부모로 이벤트를 전달해주기 때문에 상위메뉴의 자식 엘레멘트로 하지 않아서 그렇다.
상단 네비게이션 메뉴가 본문에 삽입한 pdf viewer페이지 뒤로 숨어 버린다면 일반적으로는 z-index를 pdf viewer보다 높게 설정하면 될텐데, pdf viewer의 스타일에 position:absolute 등으로 설정되어있다면 동일하게 상단 메뉴도 position:absolute 등을 설정해야 될수있다.
서브메뉴의 하이퍼링크를 다른데로 하면 스타일이 깨지는데 서브 메뉴를 누르면 화면안에서 이동하게 하고 싶다면 하나의 wrapper 태그를 두고 해당하는 태그를 가운데 정렬 또는 margin: auto등을 사용하면 된다.
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가 일치하거나 비슷해야한다.
상단 메뉴의 글씨 색이 흰색이 아니라 회색이 되는 경우도 다양한 원인이 있을 수 있는데, (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급으로 올려서 덮어씌워야한다

HTML과 CSS로 가로 드롭다운 메뉴 만들기
* 가로메뉴는 이전의 메뉴를 그대로 수정해서는 은근히 어려울 수 있어서 이 부분에 대하여 한번 더 정리해보고자 한다. 이번의 글의 목적은 HTML과 CSS만으로 가로로 떨어지는 드랍다운 메뉴를 만드는 것이다.
* 세로드랍다운메뉴 vs 가로드랍다운메뉴
: 세로메뉴와 가로메뉴는 그 사용하고자 하는 의도가 조금 다를 수 있다. 세로형은 특정 메뉴에 대해서만 하위메뉴가 있는 경우 유용하게 사용하는 경우가 많고, 모든 상위메뉴가 하위메뉴를 가지고 있게 되는 경우, 그리고 상단에 많은 넓이를 차지하지 않고 최대한 조금만 차지하도록 하고 싶은 경우에는 가로메뉴를 선택하여 사용하는 경우가 많다. 앞서 구현했던 세로메뉴에 모든 메뉴가 동일한 갯수의 하위 메뉴가 4~5개씩 있으면 사용자가 보기에 많이 정신 없고 가독성이 떨어질 수 있다는 위험성이 있다. 이 때문에 많은 하위메뉴가 있으면 세로드랍다운메뉴보다는 가로드랍다운메뉴가 더 좋을수도 있다.
: 기존의 세로메뉴와 가로메뉴의 사용자 관점이 아닌 개발자의 입장에서 가장 다른 점을 꼽으라면 가로메뉴를 구현할 수 있는 방법이 몇 가지가 있을 수 있다. 기존의 세로메뉴와 비슷하게 상위메뉴의 바로 아래에 작게 약간 떠다니는 느낌으로 나타나게 할수도 있고, 상위메뉴의 아래에 화면 전체적으로 나타나도록 하는 것도 가능할 것이다. 이번에는 간단하게 두 가지 HTML과 CSS만으로 구현하는 방법을 모두 살펴볼 것이다.
* HTML은 그대로 가져오기
: 이전에 구현하였던 세로드랍다운 메뉴의 HTML을 일단 그대로 가져오면 된다. CSS를 이용해서 구현하는 경우에는 이러한 HTML 구조를 그대로 사용하고, CSS만 변경해서 그 모양을 바꿀 수 있기 때문에 매우 유용하다. 이러한 이유 때문에 HTML의 구조와 CSS의 스타일 적용을 분리하는 것이 좋다는 것을 느낄 수 있다. 아래의 소스는 이전글에서 그대로 가져왔다.

<nav id="topMenu" >
 <ul>
  <li class="topMenuLi">
  <a class="menuLink" href="http://unikys.tistory.com/category">LECTURES</a>
    <ul class="submenu">
    <li><a href="http://unikys.tistory.com/category/A" class="submenuLink longLink">강좌</a></li>
    <li><a href="http://unikys.tistory.com/category/B" class="submenuLink longLink">만들기</a></li>
    <li><a href="http://unikys.tistory.com/category/C" 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/A" class="submenuLink">자바스크립트</a></li>
    <li><a href="http://unikys.tistory.com/tag/B" 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
  </li>
  <li>|</li>
  <li class="topMenuLi">
    <a class="menuLink" href="http://unikys.tistory.com/location">LOCATION LOG</a>
  </li>
  </ul>
</nav>
: 위의 상위/하위메뉴 구조는 그대로 가져가면서 이제 CSS만 수정해서 세로로 드랍다운이 나타나던것을 가로형으로 수정할 것이다.
* 드랍다운메뉴가 가로로 펼쳐지게 CSS 수정
: 먼저 기본의 CSS 중에서 사용할 수 있는 것은 상위 메뉴에 대한 CSS 부분이다. 이 부분은 그대로 가져와서 사용할 수 있다. 이전 글에서 가져오면 아래와 같다. 이후에는 이전의 내용에서 변경되는 부분들만 주석으로 설명을 달 것이다.

#topMenu {
 height: 30px;
 width: 850px;
 }
#topMenu ul { /* 메인 메뉴 안의 ul을 설정함: 상위메뉴의 ul+하위 메뉴의 ul */
 list-style-type: none;
 margin: 0px;
 padding: 0px;
 }
#topMenu ul li { /* 메인 메뉴의 ul 태그에 있는 li 태그의 스타일 적용(상위/하위메뉴 모두) */
 color: white;
 background-color: #2d2d2d;
 float: left;
 line-height: 30px;
 vertical-align: middle;
 text-align: center;
 position: relative;
 }
.menuLink, .submenuLink { /* 상위메뉴와 하위메뉴의 a 태그에 공통으로 설정할 스타일 */
 text-decoration:none;
 display: block;
 width: 150px;
 font-size: 12px;
 font-weight: bold;
 font-family: "Trebuchet MS", Dotum;
 }
.menuLink { /* 상위메뉴의 글씨색을 흰색으로 설정 */
 color: white;
 }
.topMenuLi:hover .menuLink { /* 상위메뉴의 li에 마우스오버 되었을 때 스타일 설정 */
 color: red;
 background-color: #4d4d4d;
 }
.longLink { /* 좀 더 긴 메뉴 스타일 설정 */
 width: 190px;
 }
: 그리고 달라지는 CSS는 바로 submenu가 이제 더이상 세로로 펼쳐지는 것이 아니라 가로로 펼쳐지기 때문에 높이에 대한 설정을 변경해주고, 가로에 대한 값도 변경해주면 된다. 변경한 내용은 아래에 표시를 하였다. 이렇게 간단하게 몇가지만 수정하고도 아주 간단하게 수정이 가능하다. 이렇게 수정한 결과는 아래와 같다.

.submenuLink { /* 하위메뉴의 a 태그 스타일 설정 */
 color: #2d2d2d;
 background-color: white;
 border: solid 1px black;
 margin-right: -1px; /* [변경] 위칸의 하단테두리와 아래칸의 상단테두리가 겹쳐지도록 설정 */
 }
.submenu { /* 하위메뉴 스타일 설정 */
 position: absolute;
 height: 0px;
 overflow: hidden;
 transition: height .2s;
 -webkit-transition: height .2s;
 -moz-transition: height .2s;
 -o-transition: height .2s;
 width: 574px; /* [변경] 가로드랍다운메뉴의 넓이 */
 }
.submenu li {
 display: inline-block;  /* [변경] 가로로 펼쳐지도록 설정 */
 }
.topMenuLi:hover .submenu { /* 상위메뉴에 마우스 올려논 경우 그안의 하위메뉴 스타일 설정 */
 height: 32px; /* [변경] 높이를 32px로 설정 */
 }
.submenuLink:hover { /* 하위메뉴의 a 태그의 마우스 오버 스타일 설정 */
 color: red;
 background-color: #dddddd;
 }
: 이렇게 구현한 결과는 아래와 같이 살펴볼 수 있다.

LECTURES | GUEST BOOK | TAG CLOUD | MEDIA LOG | LOCATION LOG
강좌 만들기 개발            자바스크립트 강좌 K100D
: 이렇게 구현하는 경우 주의할 점이 서브 메뉴가 펼쳐질 때 width: 574px로 설정해주었는데, 각각의 하위메뉴가 펼쳐지는 것이 다르다면, 각각의 하위메뉴에 아이디나 각각의 상위메뉴에 아이디를 부여해서 하위메뉴의 길이를 설정하는 것이 좋다. 또한 경우에 따라서는 전체 페이지보다 오른쪽으로 길이가 더 길어져버려서 옆으로 넘어가버리면 웹페이지가 커져서 가로 스크롤바가 생겨버리는 사태가 발생할 수 있다. 따라서 이 소스를 그대로 가져다 쓰면 안되고 페이지에 맞게 고쳐서 사용해야한다. 특히, 하위메뉴가 길어서 오른쪽으로 페이지가 넘어간다면 해당 하위메뉴의 left 스타일을 -100px 등과 같이 설정해서 넘어가지 않도록 하는 것이 좋다.
: 위의 드롭다운메뉴 같은 경우에는 하위메뉴가 있는 경우도 있고, 없는 경우도 있어서 각각의 상위메뉴 아래에 뜨도록 되어있는데, 이것을 조금 골고루 메뉴 펼쳐지는 경우 유용하게 전체 확장되도록 하면 아래와 같이 수정이 가능하다.
* 전체로 펼쳐지는 하위메뉴로 CSS 수정
: 이번에도 HTML은 그대로 활용이 가능하고 CSS만 변경하면 된다. CSS는 기존의 상위메뉴들에 position: relative를 설정했던 것을 nav로 옮겨주고, 각각의 하위메뉴들에는 left: 0;을 설정해줘서 nav의 시작 지점으로 위치가 오도록 하면 된다.

#topMenu {
 height: 30px;
 width: 850px;
 position: relative; /* [추가] 하위메뉴 시작 지점을 메뉴와 동일하게 설정하기 위함 */
 }
#topMenu ul { /* 메인메뉴 안의 ul을 설정함: 상위메뉴의 ul+하위메뉴의 ul */
 list-style-type: none;
 margin: 0px;
 padding: 0px;
 }
#topMenu ul li { /* 메인메뉴의 ul 태그의 li 태그의 스타일 적용(상위/하위메뉴 모두) */
 color: white;
 background-color: #2d2d2d;
 float: left;
 line-height: 30px;
 vertical-align: middle;
 text-align: center;
 -position: relative; /* [삭제] 해당 li 태그 내부의 top/left 포지션 초기화 */
 }
.menuLink, .submenuLink { /* 상위메뉴와 하위메뉴의 a 태그에 공통으로 설정할 스타일 */
 text-decoration:none;
 display: block;
 width: 150px;
 font-size: 12px;
 font-weight: bold;
 font-family: "Trebuchet MS", Dotum;
 }
.menuLink { /* 상위메뉴의 글씨색을 흰색으로 설정 */
 color: white;
 }
.topMenuLi:hover .menuLink { /* 상위메뉴의 li에 마우스오버 되었을 때 스타일 설정 */
 color: red;
 background-color: #4d4d4d;
 }
.longLink { /* 좀 더 긴 메뉴 스타일 설정 */
 width: 190px;
 }
.submenuLink { /* 하위메뉴의 a 태그 스타일 설정 */
 color: #2d2d2d;
 background-color: white;
 border: solid 1px black;
 margin-right: -1px;
 }
.submenu { /* 하위메뉴 스타일 설정 */
 position: absolute;
 height: 0px;
 overflow: hidden;
 transition: height .2s;
 -webkit-transition: height .2s;
 -moz-transition: height .2s;
 -o-transition: height .2s;
 width: 770px; /* [변경] 가로 드랍다운 메뉴의 넓이 */
 left: 0; /* [추가] 가장 왼쪽으로 하위메뉴 위치 설정 */
 }
.submenu li {
 display: inline-block;
 }
.topMenuLi:hover .submenu {
 height: 32px;
 }
.submenuLink:hover {
 color: red;
 background-color: #dddddd;
 }
: 이것을 구현해보면 아래와 같이 나타난다. 하위메뉴가 테두리가 있어서 약간 불만족스러운 디자인이기는 하지만 기능적으로는 잘 동작한다.

LECTURES | GUEST BOOK | TAG CLOUD | MEDIA LOG | LOCATION LOG
강좌 만들기 개발            자바스크립트 강좌 K100D
: 그러면 위와 같이 테두리가 있는 스타일을 조금 수정해서 아주 조금은 더 화면 전체로 하위가 내려오는 것과 같은 느낌을 주려면 아래와 같이 CSS를 수정하면 된다.
* 하위메뉴가 화면 전체로 오도록 수정
: 하위메뉴가 전체화면으로 오도록 수정하게 되면서 테두리를 없애고 그냥 화면 전체로 오도록 하는 것처럼 하고자 하면 아래와 같이 수정하면 된다. 이 때에 상위메뉴와 하위메뉴의 넓이는 임의로 780px로 설정하고 있으니, 각 웹페이지의 디자인된 넓이에 따라 그에 맞게 수정하면 될 것이다.

#topMenu {
 height: 30px;
 width: 770px; /* [변경] 하위메뉴와 동일하게 맞춤 */
 position: relative;
 background-color: #2D2D2D; /* [추가] 늘어난만큼 배경색도 보이도록 수정 */
 }
#topMenu ul { /* 메인메뉴 안의 ul을 설정함: 상위메뉴의 ul+하위 메뉴의 ul */
 list-style-type: none;
 margin: 0px;
 padding: 0px;
 }
#topMenu ul li { /* 메인메뉴안에 ul 태그안에 있는 li 태그의 스타일 적용(상위/하위메뉴 모두) */
 color: white;
 background-color: #2d2d2d;
 float: left;
 line-height: 30px;
 vertical-align: middle;
 text-align: center;
 -position: relative;
 }
.menuLink, .submenuLink { /* 상위메뉴와 하위메뉴의 a 태그에 공통으로 설정할 스타일 */
 text-decoration:none;
 display: block;
 width: 150px;
 font-size: 12px;
 font-weight: bold;
 font-family: "Trebuchet MS", Dotum;
 }
.menuLink { /* 상위메뉴의 글씨색을 흰색으로 설정 */
 color: white;
 }
.topMenuLi:hover .menuLink { /* 상위메뉴의 li에 마우스오버 되었을 때 스타일 설정 */
 color: red;
 background-color: #4d4d4d;
 }
.longLink { /* 좀 더 긴 메뉴 스타일 설정 */
 width: 190px;
 }
.submenuLink { /* 하위메뉴의 a 태그 스타일 설정 */
 color: #2d2d2d;
 background-color: #DDD;  /* [변경] 배경색 변경 */
 -border: solid 1px black; /* [삭제] 테두리 삭제 */
 -margin-right: -1px; /* [삭제] 공백 보정 삭제 */
 }
.submenu { /* 하위메뉴 스타일 설정 */
 position: absolute;
 height: 0px;
 overflow: hidden;
 transition: height .2s;
 -webkit-transition: height .2s;
 -moz-transition: height .2s;
 -o-transition: height .2s;
 width: 770px;
 left: 0;
 background-color: #DDD; /* [추가] 하위메뉴 전체에 배경색 설정 */
 }
.submenu li {
 display: inline-block;
 }
.topMenuLi:hover .submenu {
 height: 32px;
 }
.submenuLink:hover {
 color: red;
 background-color: #dddddd;
 }
: 이렇게 구현하면 아래와 같이 상위메뉴에 따라서 하위메뉴도 전체 화면을 차지하도록 하는 것이 가능하다. 이렇게 한 이후, 혹시 각 하위메뉴의 시작 지점을 바꿔주고 싶다면, 각 하위메뉴에 id나 class를 부여한 다음 left 값을 설정해주면 된다.


LECTURES | GUEST BOOK | TAG CLOUD | MEDIA LOG | LOCATION LOG
강좌 만들기 개발            자바스크립트 강좌 K100D
: 이후에는 각자의 웹페이지 디자인에 맞게 CSS를 수정하면서 맞춰 나가면 될 것이다.


마우스 오버 이미지 배너 만들기(CSS, 자바스크립트 등)
* 이번에는 마우스 오버 이미지 배너를 만드는 방법을 알아볼 것이다. 이러한 마우스 오버될 때 이미지가 변경되는 것은 다양한 방법들이 있는데, 이러한 방법들을 해당 태그의 중요도나 위치에 따라서 다르게 구현하는 방법들을 적용하면 UX가 향상된 홈페이지를 만들 수 있을 것이다. 만약 모든 경우에 오직 한가지 방법만 고집한다면 각 방법들의 적용 방법을 익혀서 필요에 따라서 사용한다면 아주 좋을 것이다.
* 마우스 오버 이미지
: 마우스오버 이미지는 다양하게 활용이 되고 있는데, 특별하게는 배너로 많이 사용되고 있다. 만약 '글씨색이나 배경색'이 바뀌는 배너에 이미지를 이용한 마우스 오버를 생각하고 있다면 최소 1번의 request, 또는 2번의 request를 만들어버리는 다소 비효율적인 구현 방법일 것이므로 먼저 이미지를 이용한 마우스 오버 배너가 반드시 필요한지 검토한 다음에 적용하는 것이 좋다. 그렇다면 다양한 마우스오버 배너를 구현하는 방법들에 대해서 살펴보자.
* CSS의 background를 기반으로 구현
: css를 기반으로 구현하게 되면 너무나 간단하게 구현이 가능하기 때문에 아주 쉽게 사용할 수 있는 방법이다. 먼저 이미지 배너를 넣을 곳에 해당 태그를 넣자.

    <div id="rightBanner"></div>
: 이렇게 기본 이미지와 마우스 오버 이미지를 보여줄 배너를 넣을 div를 만들었다. 정말 이게 끝이다. 그리고 나머지는 css로 '아주 간단하게' 끝이난다.

<style>
 #rightBanner {
  width: 250px;  /* 배너의 가로 사이즈 설정 */
  height: 167px;  /* 배너의 세로 사이즈 설정 *?
  background: url('http://hjkee.net/img/a1?original') no-repeat center;  /* 배너의 기본 이미지를 백그라운드로 설정 */
 }
 #rightBanner:hover {
  background: url('http://hjkee.net/img/a2?original') no-repeat center;  /* 배너의 마우스오버 이미지를 백그라운드로 설정 */
 }
</style>
: 이렇게 스타일을 설정하고 나면 해당 div는 백그라운드 이미지와 마우스오버 때 사용한 이미지를 가지게 된다.
: 끝. 그야말로 너무나 간단한 구현 방법이다. 하지만 이러한 방법은 위의 div에 마우스오버를 처음 실행하게 되면 그 단점이 나타나게 된다. 바로 hover로 설정한 이미지는 마우스오버가 되면 그때서야 브라우져에서 해당 이미지를 요청하여 다운받게 되므로 첫 마우스 오버에 약간의 깜박임이 생기게 된다. 물론 이러한 것도 해결방법이 다 있다. 이것의 가장 좋은 해결 방법은 CSS sprite를 이용하거나 pseudo selector의 content를 사용하는 방법이 있는데, CSS sprite는 이미지의 request 수를 줄일 수 있는 아주 좋은 최적화 방식이다. 하지만 웹의 타임라인을 살펴보면 이렇게 구현하는 방법의 단점을 또 발견할 수 있을 것이다. 만약 인터넷 속도가 느리다면 이러한 단점은 아주 쉽게 발견할 수 있다.


 

: 바로 순간적으로 css로 설정된 백그라운드 이미지는 다른 img로 로드되는 이미지들에 비해 우선순위가 떨어진다는 것이다. 다른 img로 설정한 이미지들이 먼저 로드되고나서야 뒤늦게 로드되는 것이다. 따라서, 이러한 CSS를 백그라운드로 사용하는 부분은 로드가 조금 느려도 되는 사이드바나 웹페이지의 아래부분에 있는 조금 늦게 떠도 되는 핵심적이지 않은 배너에 이렇게 쉬운 구현 방법을 사용하는 것이다. 그리고 이러한 로드가 느리다는 체감을 줄여주기 위하여 url이 로드되기 전에 보여줄 기본 백그라운드색을 해당 배너의 배경색과 일치하게 설정하는, 검은색 배너는 기본으로 검은색 바탕색, 흰색 배너는 기본으로 흰색 바탕색을 사용함으로써 UX를 향상시키는 방법을 사용한다.
* <img> 태그와 inline 자바스크립트를 기반으로 구현
: 아마 가장 많은 사람들이 사용하는 방법으로 마우스오버가 되면 <img> 태그의 src를 수정하고, 다시 마우스아웃이 되면 원래의 src로 다시 수정하는 방법이다. 이것은 자바스크립트로 다양하게 구현이 가능한데, 가장 쉽게는 그냥 인라인으로 만들어버리는 방법이 있을 것이다.

<img id="leftBanner" src="http://hjkee.net/img/a1?original" onmouseover="this.src='http://hjkee.net/img/a2?original'" onmouseout="this.src='http://hjkee.net/img/a1?original'"> </img>
: 이것도 어떻게 보면 한줄이면 된다. 아주 간단하다. 이것을 구현하면 바로 마우스 오버 이미지 배너가 탄생한다.


: 게다가 <img> 태그를 이용했기 때문에 css의 백그라운드를 이용하는 것보다 로드가 우선적으로 된다는 점이 매력적이다. 하지만 css sprite를 이용한 최적화가 안되기 때문에 최적화에는 다소 어려움이 있다. 어찌되었든 하나의 배너가 2개의 request를 사용하게 된다는 점, 그리고 이 역시 mouseover에서 설정하는 src가 처음에 마우스 오버를 할 때에는 깜박임이 생겨버리게 되는 것이 불만이다. 그리고 해당 src의 이미지들이 사이즈가 다르게 되면 어찌되었든 별도의 css를 설정해줘야한다는 점이 있다. (위의 예가 사이즈가 다른 경우 나타나는 현상이다. CSS로 설정이 필요한 것이다.) 하지만 이 모든 것 또한 다른 방법으로 해결이 가능하다. 이러한 방법들을 보기 전의 위의 inline 자바스크립트가 불만인 사람들을 위하여 별도의 자바스크립트로 구현해보도록 하자.
* <img> 태그와 자바스크립트를 기반으로 구현
: 어쩌면 위의 inline보다는 이렇게 구현하는 사람들이 더 많을지도 모른다. jquery를 사용해서 한다면 결국은 이 방법의 한가지 방식이 되는 것이다. 일단 기본 img 태그를 만들어두고 별도의 script 태그로 위의 onmouseover와 onmouseout을 뽑아내면 된다.

    <img id="centerBanner" src="http://hjkee.net/img/c1?original"></img>
: 그리고 해당 html의 맨 아래에다가 위의 태그 id를 호출하는 부분을 만들어주면 된다. 아래의 태그는 immediate function호출로 바로 실행하려면 body태그의 맨 아래 쯔음에 <script> 태그를 포함해서 추가하면 되고, onload이벤트에 호출하고자한다면 위치는 상관이 없으나, UX적인 향상을 위해서라면 모든 자바스크립트는 그대로 body 태그의 맨 아래에 놔두는 것이 좋다.

<script>
(function(d) {
    var img = d.getElementById("centerBanner");
    img.onmouseover = function () {
        this.src = "http://hjkee.net/img/d1?original";
    };
    img.onmouseout = function () {
        this.src = "http://hjkee.net/img/d2?original";
    };
}(document));
</script>
: 이는 위의 inline 자바스크립트로 구현한 것과 큰 차이는 없으나, 최근 웹개발의 트렌드에 따라가고 있는 구현 방법이다. MVVM모델과 비슷한 개념을 구현하기 위해서 HTML에는 오로지 뷰로서의 역할만을 시키도록 하는 것이 최근 트렌드이므로 inline으로 하기보다는 이렇게 구현할 것을 추천한다. 이렇게 구현한 결과는 아래와 같다.


: 많은 사람들이 사용하고 있을 이 방법 역시도 inline 자바스크립트와는 똑같이 처음으로 마우스오버를 하게 되면 깜빡이는 현상이 나타난다. 이것은 이미지의 용량이 커지면 더 크게 체감하게 되는데, 이 현상을 없애줄 다른 방법을 살펴보자.
* <img> 태그 2개와 자바스크립트를 기반으로 구현
: img태그를 통해서 이미지가 로드되기 시작하는 것은 html이 파싱되어 마우스오버의 src가 로드가 되는 시점부터 요청을 시작하기 마련이기 때문에 위의 방법들은 마우스오버가 되는 첫번째 시점에 다운로드가 되는 문제가 있다. 이러한 점이 바로 깜박임이 생겨버릴 수 있는 여지도 발생시키고, 인터넷이 느린 경우에는 그 시간이 점점 늘어나게 될 것이다. 이것을 해결하기 위해서는 <img> 태그를 2개 사용해서 미리 로드 시간 다음에 마우스 오버를 하는 경우 숨겨주는 방식이 유용하다. 이것을 구현하는 방법은 다양하지만, 아래의 방법이 일반적인 구현 방법이다.

: 바로 위와 같은 방식으로 2개의 이미지를 겹쳐놨다가 마우스오버가 되는 경우 앞의 <img>를 display:none 등으로 감추는 방식이다. 이것과 비슷한 방법으로는 아래와 같이 2개의 이미지의 앞뒤를 z-index를 수정함으로써 바꾸는 방법도 있다.

: 위의 방식을 응용하면 반투명한 오버랩 이미지도 쉽게 구현이 가능하므로 다양하게 응용이 가능할 것이다. 여기서는 첫번째 방법으로 구현하는 방법을 간단하게 해보자.

    <div id="bannerWrapper">
        <img id="frontImage" src="http://hjkee.net/img/d1?original"/>
        <img src="http://hjkee.net/img/d2?original"/>
    </div>
: 먼저 2개의 <img> 태그가 필요할 것이고, 해당 2개의 <img>태그를 겹치기 위해서 하나의 wrapper <div> 태그가 있으면 편리하다. 2개의 이미지를 겹치는 가장 간단한 방법은 wrapper <div> 태그의 css에 position: relative를 적용하고, 2개의 자식 <img>에는 position: absolute를 설정해주는 방법이다. position: absolute를 해주면 좋은 다른 이유는 바로 해당 설정을 한 태그들의 설정 값을 바꾼다고해서 DOM의 reflow가 일어나지 않기 때문에 성능상에도 다소 이점을 가져갈 수 있다는 점이다. 아래와 같이 css를 적용하면 쉽게 구현이 가능하다.

<style>
 #bannerWrapper {
  position: relative; /* 하위태그가 상대적인 위치를 가질 수 있도록 설정 */
  }
#bannerWrapper img {
  position: absolute;  /* img 태그들이 겹쳐질 수 있게, 다른 태그에 영향을 주지 않게 설정 */
  }
#bannerWrapper #frontImage {
  z-index: 1; /* 앞에 나올 이미지를 설정 */
  }
#bannerWrapper:hover #frontImage {
  display: none;  /* 마우스오버가 되면 앞에 나온 이미지를 숨김 */
  }
</style>
: 위의 #bannerWrapper:hover #frontImage 안의 display: none;를 z-index: -1로 수정하게 된다면 위의 2가지 css 적용 방법 중 2번째 방법이 된다. 하지만 z-index는 구버전 사파리에서 제대로 동작하지 않는 현상이 있으므로 그냥 display: none;을 하는 것이 다양한 브라우져의 호환을 고려할 때에는 속편할 것이다. 위의 구현 결과는 아래와 같다.


: 이러한 경우의 조심할 점이라면 position:relative으로 설정했으면, 해당 wrapper div의 width와 height css를 잘 설정해주지 않으면 그 아래에 오는 태그들이 겹치거나 마우스 오버의 범위가 틀어져버릴수도 있는 결과가 발생할 수 있으므로 조심해야한다. 여기서 또 더 개선을 시킬 수 있는 방법들은 아래의 img를 onload가 되고난 뒤에 추가하는 등 여러 방법들이 있는데, 이것보다 더 성능을 최적화하는 것은 당장은 고려할 필요는 없을 것이므로 일단 이정도로만 구현해도 마우스 오버에 대한 UX는 다소 향상 시킬 수 있다. 하지만 페이지 로드일 때 2개의 request가 생기는 것이 페이지 로드에 다소 영향을 줄 수 있다는 것이 불만일 수도 있다. 이 때에는 약간 새로운 방법으로 최적화도 가능하다.
* <div> 태그의 overflow:hidden과 <img> 태그 1개와 CSS 로 구현하기
: 아마 많은 웹개발자들은 이 방법에 대해서도 잘 모르고 있을 것인데, <img> 태그의 유용한 최적화 방법 중 하나로 웹성능최적화에 응용이 가능한 유용한 방법이다. CSS의 background로 이미지를 표시하는 경우에는 css sprite를 통해서 아주 쉽게 request를 줄일 수 있는 최적화가 가능하지만, background 이미지의 로딩이 페이지 뷰가 먼저 이루어지고나서 시작한다는 점에서 이미지 표시를 빠르게 해줘야하는 경우 이 방법이 css sprite를 활용하는 방법을 대신해서 사용할 수 있는 최적화 방법이다. 이것이 동작하는 방법은 아래와 같다.


: 위의 2개의 이미지를 겹치는 것과는 달리 2개의 이미지를 하나의 이미지로 이어 붙인 다음에 하나의 <img> 태그로 불러오고 wrapper div는 overflow: hidden를 설정해서 한번에 하나의 이미지만 보이게 하는 것이다. 그리고 마우스오버가 되면 이 <img> 태그의 위치를 위로 이동시켜서 아래쪽에 붙인 이미지를 표시하는 방식이다. 이것을 위해서는 일단 하나의 <div>태그와 하나의 <img>태그가 필요하다. 우선 아래와 같이 이미지를 하나로 이어서 붙였다. 위의 그림과 같은 구조로 가기 위해서 위아래로 붙였지만, 양옆으로 해도 무관하다.





: 그리고 이것을 나타내는 <img>태그 하나와 그 wrapper div태그 하나가 필요하다.

    <div id="verticalBannerWrapper">
        <img id="verticalBannerImg" src="http://hjkee.net/img/f1"/>
    </div>
: <img>태그 는 위의 이미지 하나만을 로드하기 때문에 페이지의 request는 하나가 되는 것이다. 그렇다면 이제 해당 div와 img 태그에 스타일을 적용해주면 된다. css는 위의 2개의 이미지를 겹치는 것과 비슷하게 wrapper <div>태그에는 relative를 주고 <img> 태그는 absolute 태그를 주지만, wrapper <div> 태그는 overflow:hidden과 함께 배너의 크기를 지정해주고, 마우스 오버인 경우에 <img> 태그의 top의 값을 변경시키는 것이 중요하다.

<style>
    #verticalBannerWrapper {
        overflow: hidden;  /* div의 높이/넓이보다 커지는 경우 보여주지 않도록 설정*/
        height: 400px;      /* 보여줄 배너의 높이 */
        width: 265px;      /* 보여줄 배너의 넓이 */
        position: relative; /* 내부의 태그가 상대적으로 움직일 수 있도록 설정 */
    }
    #verticalBannerImg {
        position: absolute; /* 위치 변경이 다른 태그에 영향을 주지 않도록 설정 */
    }
    #verticalBannerWrapper:hover #verticalBannerImg {
        top: -400px;    /* 마우스 오버가 됐을 때 img 태그를 400px만큼 올리도록 설정 */
    }
</style>
: 각각의 css들은 위의 설명도에서 나타내고 있는 것 그대로 동작할 수 있도록 제공해주고 있으므로 모든 스타일이 중요하다. 이렇게 구현하게 되면 아래와 같이 된다.






: 이러한 구현 방법을 사용하게 되면 2개가 필요했던 request를 하나로 줄임으로써 성능적인 향상을 다소 이룰 수 있게 되고, 마우스오버의 이미지도 첫 이미지를 로드할 때 하나로 묶여서 같이 로드되므로 마우스오버로 인한 깜박임도 없다. 이러한 배너가 하나라면 큰 차이는 없을지 모르지만, 배너가 여러개일수록 성능향상의 폭은 커진다. 물론 구현하는 홈페이지의 성능은 언제나 최적화하면 좋지만 만약 위처럼 구현해놓았는데 배너의 이미지가 자주 바뀐다면 위의 하나의 <img>태그에 들어갈 이미지를 매번 새로 생성해야 하기 때문에, 위의 방법으로 구현한다면 이러한 이미지 생성 작업은 매번 다소 번거로울 수 있을 것이므로 이미지가 잘 바뀌지 않을 배너에 위의 방법을 사용하는 것이 좋을 것이고, 만약 이미지의 사이즈가 크다면 초기의 이미지를 다운 받아야하는 사이즈가 2배가 되므로 다른 방법을 사용하는 것도 방법이다.
* 정리
: 다양한 마우스 오버 이미지 배너의 구현 방법들을 살펴봤는데, 각 이미지 배너의 구현 방법은 해당 배너의 중요도나 표시 우선순위 등에 따라서 다르게 구현하면 될 것이다.
중요하지 않은 aside 메뉴나 구석 메뉴의 마우스오버 이미지를 적용하면 - CSS background로 구현하는 것이 유리
배너를 조금 늦게 표시해주거나 첫 페이지뷰의 밖인 아래쪽에 있다면 - CSS background로 구현하는 것이 유리
반응형으로 브라우져 크기나 모바일에 따라 이미지를 다르게 하고 싶다면 - CSS background로 구현하는 것이 유리
빠르게 표시해줘야한다면 - <img> 태그로 구현하는 것이 유리

댓글목록

등록된 댓글이 없습니다.


Copyright © KISTORY.NET 2001 - 2025 기회근 개인 홈페이지 All rights reserved.
모바일버전