Меню для сайта. Часть 2: горизонтальные меню без JavaScript.

Меню для сайта. Часть 2: горизонтальные меню без JavaScript.

Это вторая часть из серии постов на тему «Меню для сайта». Первую часть можно почитать здесь. В этой части пойдет речь о сложных горизонтальных меню, то есть когда один элемент меню имеет свои подменю. Примером такого меню может быть стандартное меню, которое используется в окнах операционных систем Windows (Файл, Правка, Вид…).

В этом посте, также как и в предыдущем, будут рассмотрены меню, построенные без использования JavaScript, то есть исключительно при помощи HTML и CSS (не пугайтесь, в следующих постах Я обязательно расскажу о меню с использованием JavaScript). Такой подход имеет один большой плюс — меню будут работать даже с выключенным или блокированным JavaScript.

Горизонтальное двухуровневое меню 1

Вот такое меню должно получится:

Горизонтальное двухуровневое меню

Данное меню будем делать на основе меню из 2 примера предыдущего поста, то есть простого горизонтального меню. HTML-разметку страницы изменим, добавив в нужных нам местах между закрывающим тегом </a> и закрывающим тегом </li> разметку для второго уровня меню.

Разметка для второго уровня меню

<li><a href="#">Уроки</a>
    <ul>
        <li><a href="#">Урок 1</a></li>
        <li><a href="#">Урок 2</a></li>
        <li><a href="#">Урок 3</a></li>
        <li><a href="#">Урок 4</a></li>
        <li><a href="#">Урок 5</a></li>
    </ul>
</li>

Теперь при наведении на пункт «Уроки» у нас будет появляться второй уровень со списком уроков. Я добавил второй уровень для пунктов «Уроки» и «Примеры».

Схематичное изображение меню
Схематичное изображение меню

Теперь вся HTML-разметка страницы имеет следующий вид:

Файл index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Делаем меню вместе</title>
<link rel="stylesheet" type="text/css" href="style.css" >
</head>
<body>
<ul id="navbar">
    <li><a href="#">Блог</a></li>
    <li><a href="#">Уроки</a>
        <ul>
            <li><a href="#">Урок 1</a></li>
            <li><a href="#">Урок 2</a></li>
            <li><a href="#">Урок 3</a></li>
            <li><a href="#">Урок 4</a></li>
            <li><a href="#">Урок 5</a></li>
        </ul>
    </li>
    <li><a href="#">Скачать</a></li>
    <li><a href="#">Примеры</a>
        <ul>
            <li><a href="#">HTML</a></li>
            <li><a href="#">CSS</a></li>
            <li><a href="#">JavaScript</a></li>
            <li><a href="#">PHP</a></li>
            <li><a href="#">MySQL</a></li>
        </ul>
    </li>
    <li><a href="#">Форум</a></li>
</ul>
</body>
</html>

Опишем стили, чтобы второй уровень меню появлялся только при наведении на родительский элемент из первого уровня. То есть когда мышка не наведена на родительский элемент, второй уровень (дочерний список) должен быть скрыт. Это реализуется следующим образом:

Скрытие дочернего списка

ul#navbar li ul{
    display:none;
}

А в момент, когда курсор над родительским элементом отобразить второй уровень:

Отображение дочернего списка

ul#navbar li:hover ull{
    display:block;
}

Для того чтобы, появляющийся новый уровень появлялся под первым уровнем, нам необходимо для первого уровня дописать свойство position:relative;, а для второго уровня position:absolute;. Теперь второй уровень позиционируется отсносительно первого и перекрывает его при наведение на родительские элементы. Чтобы этого не происходило опустим второй уровень на высоту первого уровня: top:30px, а также зададим z-index:10; , чтобы появляющийся дочерний список не оказался под другими элементами, расположенными ниже нашего меню (в данном примере ниже параграфа).

Стили для второго уровня

ul#navbar li ul{
    display:none;		/* скрываем второй уровень */
    list-style:none;
    position:absolute;          /* задаем абсолютное позиционирование */
    top:30px;  		/* отступ сверху */
    z-index:10;		/* "подымаем" над остальными элементами*/
}
ul#navbar li:hover ul{
    background:#1b64dc;
    border:0px;
    display:block;
    float:none;
    margin:0px auto;
    padding:0px;
    width:500px;
}

Теперь файл стилей выглядит следующим образом.

Файл style.css

html, body{
    background:#C0C0C0;		/* фон страницы */
    margin:0px auto;        /* выравнивание по центру */
    padding:0px;            /* обнуление полей */
}
ul#navbar{
    border:0;
    border-left:1px solid white;
    height:30px;            /* высота списка */
    list-style:none;        /* отменяем маркер для списка */
    margin:20px auto;       /* выравниваем меню на странице */
    padding:0px;            /* обнуление полей */
    width:500px;            /* задаем ширину меню */
}
ul#navbar li,
ul#navbar li a{
    display:block;
    float:left;
    position:relative;
}
ul#navbar li a{
    background:url(bg.png) repeat-x 0 0; /* фон элемента меню */
    border:1px solid white;
    border-left:0;
    color:white;               /* цвет текста */
    font:normal 16px arial;    /* описываем шрифт */
    height:18px;               /* задаем высоту для элемента */
    margin:0px;
    padding:5px 0;
    text-align:center;         /* текст в ячейке "по центру" */
    text-decoration:none;      /* отмена декораций */
    width:99px;
}
ul#navbar li a:hover,
ul#navbar li:hover a{
    background:url(bg.png) repeat-x  0px -30px;
}
ul#navbar li ul{
    display:none;				/* скрываем второй уровень */
    left:0px;				/* это нужно только для ИЕ, в других браузерах работает и без этого */
    list-style:none;
    position:absolute;          /* задаем абсолютное позиционирование */
    top:30px;  					/* отступ сверху */
    z-index:10;					/* "подымаем" над остальными элементами*/
}
ul#navbar li:hover ul{
    background:#1b64dc;
    border:0px;
    display:block;
    float:none;
    margin:0px auto;
    padding:0px;
    width:100px;
}
ul#navbar li ul li,
ul#navbar li:hover ul li a{
    display:block;
    float:none;
}
ul#navbar li:hover ul li a{
    background:#1b64dc;
    border:0;
    color:white;
    font-size:12px;
    font-weight:normal;
    height:20px;
    line-height:20px;
    padding:0px;
    margin:0;
    text-align:center;
    white-space:nowrap;
    width:100px;
}
ul#navbar li:hover ul li a:hover{
    background:#ef007c;
}

Продолжим рассмотрение горизонтальных меню.

Горизонтальное двухуровневое меню 2

Горизонтальное двухуровневое меню

Это довольно распространенный вариант меню, его можно встретить на многих сайтах и интернет ресурсах. Но большинство из них работает благодаря JS-коду, реже они реализованы на Flash’е. Я же хочу показать как это меню можно реализовать на «голом» HTML и CSS.
Ну что ж, перейдем от слов к действию. Чтобы не изобретать велосипед, возьмем за основу меню из предыдущего примера. Основное отличие от предыдущего состоит в том, что второй уровень в первом примере инлайновый (display:inline;), теперь же нам нужен блочный список без обтекания у элементов, чтобы они выстроились вертикально. Для этого нужно записать в css-файл следующее:

ul#navbar li ul li,
ul#navbar li:hover ul li a{
    display:block;
    float:none;
}

Теперь элементы выстраиваются вертикально, но по прежнему прижимаются к левому краю списка, а не к левому краю родительского элемента. Почему? Да потому что элементы первого уровня у нас тоже инлайновые, для этого мы сделаем их блочными, но обтекание оставим.

ul#navbar li,
ul#navbar li a{
    display:block;
    float:left;
}

После этих и еще некоторых незначительных изменений (ширина списка второго уровня стала 100px вместо 500px, уменьшил поля вокруг элементов a) список стилей стал выглядить следующим образом:

Файл style.css для «Горизонтальное двухуровневое меню 2»

html, body{
    background:#C0C0C0;		/* фон страницы */
    margin:0px auto;        /* выравнивание по центру */
    padding:0px;            /* обнуление полей */
}
ul#navbar{
    border:0;
    border-left:1px solid white;
    height:30px;            /* высота списка */
    list-style:none;        /* отменяем маркер для списка */
    margin:20px auto;       /* выравниваем меню на странице */
    padding:0px;            /* обнуление полей */
    position:relative;
    width:500px;            /* задаем ширину меню */
}
ul#navbar li{
    display:block;
    float:left;
}
ul#navbar li a{
    background:url(bg.png) repeat-x 0 0; /* фон элемента меню */
    border:1px solid white;
    border-left:0;
    color:white;               /* цвет текста */
    display:block;             /* меняем тип отображения */
    float:left;                /* обтекание */
    font:normal 16px arial;    /* описываем шрифт */
    height:18px;               /* задаем высоту для элемента */
    margin:0px;
    padding:5px 0;
    text-align:center;         /* текст в ячейке "по центру" */
    text-decoration:none;      /* отмена декораций */
    width:99px;
}
ul#navbar li a:hover,
ul#navbar li:hover a{
    background:url(bg.png) repeat-x  0px -30px;
}
ul#navbar li ul{
    display:none;				/* скрываем второй уровень */
    list-style:none;
    left:0px;
    position:absolute;          /* задаем абсолютное позиционирование */
    top:30px;  					/* отступ сверху */
    z-index:10;					/* "подымаем" над остальными элементами*/
}
ul#navbar li:hover ul{
    background:#1b64dc;
    border:0px;
    display:block;
    float:none;
    margin:0px;
    padding:0px;
    width:500px;
}
 
ul#navbar li:hover ul li a{
    background:#1b64dc;
    border:0;
    color:white;
    display:inline;
    font-size:12px;
    font-weight:normal;
    height:30px;
    line-height:30px;
    padding:0px;
    margin:0;
    text-align:center;
    white-space:nowrap;
    width:100px;
}
ul#navbar li:hover ul li a:hover{
    background:#ef007c;
    text-decoration:underline;
}

HTML-разметка страницы осталась такой же как в первом примере этого поста.

Улучшенние двухуровневого меню

Далее хочу показать как можно улучшить выше расмотренное меню «Горизонтальное двухуровневое меню 1». Допустим во втором уровне нам нужно выводить не просто ссылки на подпункты, а к примеру форму, картинки или просто некоторый текст.

Для реализации задуманного вместо списка UL поместим блок, один DIV, который будет невиден когда мышка не над элементом первого уровня и будет виден когда курсор находится над родителем. По сути все остается как и в первом меню, просто меняем список UL на блок DIV, в котором и будем отображать контент вместо элементов списка, то есть нам нужно изменить HTML-разметку нашего файла. Зададим вложенному блоку идентификатор block.

Примерная структура улучшенного меню

ul id="navbar">
  <li><a href="#">А</a>
    <div id="block">
        <p>Здесь текст</p>
    </div>
  </li>
  <li><a href="#">Б</a>
    <div id="block">
        <img src="img.jpg">
    </div>
  </li>
  ...
  <li><a href="#">Я</a>
    <div id="block">
        <ul>
            <li>Я</li>
            <li>Яб</li>
            ...
            <li>Яхтинг</li>
        </ul>
    </div>
  </li>
</ul>

Думаю суть ясна. Я не стал приводить в посте исходную разметку страницы, так как она давольно массивная и вставлять её в пост было б не уважительно по отношению к Вам.

Кроссбраузерность

Примеры из данного поста не будут работать в браузерах Internet Explorer 6 и ниже, так как эти браузеры воспринимают событие :hover, только для ссылок, т.е. li:hover — не работает в браузере IE 6 и ниже. Примеры были протестированы на кроссбраузерность в следующих браузерах:

  • Google Chrome 4.1.249
  • Internet Explorer 7 и Internet Explorer 8
  • Mozilla Firefox 3.5.8
  • Opera 9.62 и Opera 10.10
  • Safari 4.0.5

Послесловие

В последнем примере при наведении на букву «Н» в блоке под меню отображается форма. Идея с размещением формы в таком блоке — это скорей показательный пример нежели пример реального использования, так как такая форма не совсем удобна для заполнения. Всплывающие поля автозаполнения предлагают выбрать элементы для заполнения из списка и когда пользователь передвигает мышь для выбора элемента, то наш блок теряет «фокус» и скрывается.

Скачать исходники

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *