Логин:

Пароль:

Форумы
Общие вопросы
Document Object Model
Обсуждаем конференцию
Web Usability (test)

Общие вопросы

dhtml menu: links (Большая Статья)

> Горизонтально расположенное меню с выпадающими вертикально сабменю.
>
> Страница 100%-width, в беспорядке на ней разбросаны пункты меню - нужно сделать так, чтобы при разных разрешениях и ресайзингах, сабменю оставались привязанными к parent menu item...

Ага... Не Знаю, Понял Ли Я Совсем Правильно, Но Меня Пробило На Большую Теоретическую Статью По Поводу Меню. А То, Вот, Тут Недалеко Уже Идет Дискуссия По Этому Поводу. Видимо, Тема "Созрела".

Вступление.
Лично Меня Во Всеразличных Коммерческих И Полукоммерческих HierMenus-Подобных Решениях Удручают 2 Вещи:
1. Придумывается Новый, Совершенно Ни На Что Не Похожий API Для Создания Менюшки. Именно Целый API Для Всего Лишь Менюшки.
2. Делаются Попытки Поддерживать Огромное Число Браузеров, Что Неимоверно Раздувает Код И Создает Впечатление, Что Для Создание Меню Нужно Владеть Навыками Программирования.
Поэтому Сейчас Здесь Я Попытаюсь Описать Технологию Создания Простого В Пониманиии И Развитии Меню, Основанную На Нормальных Web-Стандартах. Опять Озвучу Свой Принцип: Я Всегда Изначально Делаю Любую Вещь, Чтобы Она Соответствовала W3C-шным Рекомендациям, А Потом Доделываю До Совместимости С IE, Так Как Он - ОЧЕНЬ Сильно Распространенный Браузер.

HTML.
Начну С Того, Что Меню Должно Быть Описано Тегами <UL>. Именно _Должно_, По Следующим Причинам:
1. Любое Меню - Это По Своей Сути Список Пунктов. Возможно, Иерархический. В HTML Для Описания Списков Существуют Специальные Элементы: UL, OL, DL. Поскольку Меню Не Является Ни Списком Определений (Definition List), Ни Порядковым Списком Действий, Который Надо Переделать Один За Другим (Ordered List), То Ничего Другого Не Остается, Как Использовать Простой Неупорядоченный Список - Unordered List, То Есть UL. Это - Выбор UL, А Не Div Или Table - Довольно Важный Аспект, Но Подробное Обоснование Я Писать Не Буду. Кому Интересно, Поищите Google'ом "Semantic Markup", "HTML Semantic".
2. При Отсутствии В Браузере Поддержки CSS И JavaScript Такое Меню Будет Доступно В Виде Простого Иерархического Списка. Чего Не Скажешь О Решениях На Таблицах И Div'ах.
3. Если Потом Захочется Перевести Свою Страницу На XHTML2, То Там Надо Будет Только Заменить <UL> На <NL> - Новый Элемент, Специально Предназначенный Для Навигационных Иерархий.

Итак, Получаем Приблизительно Такую Структуру Меню:
<UL Id=Menu>
<LI>
<H1>Пункт 1</H1>
<UL>
<LI><A HRef="./">Подпункт 1.1</A>
<LI><A HRef="./">Подпункт 1.2</A>
</UL>
<LI>
<H1>Пункт 2</H1>
<UL>
<LI><A HRef="./">Подпункт 2.1</A>
<LI><A HRef="./">Подпункт 2.2</A>
<LI><A HRef="./">Подпункт 2.3</A>
</UL>
</UL>

Небольшой Комментарий По Поводу <H1>. Он Означает, Что, Например "Пункт 1" - Это Загловок Подменю "Подпункт 1.1, Подпункт 1.2". А Так Оно И Есть По Сути (Хотя Признаюсь, Что Он Здесь Удачно Появился Не Из Теоретических Соображений, А Чтобы Избежать Небольшой Неопределенности При Позиционировании Подменю CSS'ом. Об Этом - Дальше).

Раскладка.
Все Позиционирование, Оформление, И Скрытие-Раскрытие Меню Определяется CSS'ом. Описываю По Шагам:

1. Само Меню По Условиям Задачи Располагаем Статически:

#Menu {Margin:0; Padding:0;}

Забегая Вперед, Скажу, Что Margin'ы И Padding'и Я Везде Убираю В Нуль, Так Как В Разных Браузерах Для UL И LI Здесь Очень Разные Умолчания.

2. Пункты Главного Меню Надо Показать Простыми Блоками (А Не List-Item'ами С Кружочками), И Расположить Их Горизонтально:

#Menu LI {Display:Block; Float:Left; Margin:0; Padding:0;}

3. Предыдущее Правило, Однако, Затронет ВСЕ Элементы <LI> Внутри Меню, И В Подменю Тоже. Хотя, В CSS2 Есть Нормальное Средство Для Избежания Такого Эффекта: Можно Было Бы Написать Правило #Menu>LI, И Оно Подходило Бы Только Для Детей Первой Вложенности. Но, WinIE Такой Селектор Не Поддерживает, Поэтому Мы Им Пользоваться Не Будем. Вместо Этого, Мы Напишем Новое Правило, Которое Просто Переопределит Поведение Пунктов Второй И Больше Вложенности:

#Menu LI UL LI {Float:None;}

Замечу, Что Свойства Display, Margin И Padding Наследуются Тут Из Второго Правила, Поэтому Я Их Не Пишу.

4. Дальше Надо Указать Для Всех Вложенных Подменю, Что Они По Умолчанию Невидимы:

#Menu LI UL {Display:None; Margin:0; Padding:0;}

5. А Видимыми Они Должны Стать При Наведении Мышки На Верхний Пункт. Наведение Мышки В CSS Описывается Селектором :Hover. Однако, WinIE Не Поддерживает Этот Селектор Ни Для Чего, Кроме Элементов <A>. Поэтому, Для Описания Выпадания Меню Я Использую Два Правила. Одно - Стандартное, Другое - Для Совместимости - С Использованием Специально Придуманного Для Этого Случая Класса, Которым Мы Потом Будем Управлять Скриптом.

#Menu LI:Hover UL,
#Menu LI.Hover UL {Display:Block; Position:Absolute;}

Опять Маленькое Замечание, Не Обязательное К Пониманию. Если Помните, Я Раньше Писал, Что Элемент H1 Нужен, Чтобы Избежать Проблем С Позиционированием. Они Возникают Именно Из-За Вот Этого Position:Absolute. То Есть, Если Сделать Просто:

<LI>
Пункт 1
<UL>
</UL>

И Повесить UL Абсолютно, То Не Совсем Понятно, Где Он Будет Висеть - Справа Или Снизу. Если Бы Он Был Позиционирован Не Абсолютно, А Статически, То, Одназначно, Висел Бы Снизу (Могу Описать Подробней, Если Интересно). А Вот Если Сделать Так:
<LI>
<H1>Пункт 1</H1>
<UL>
</UL>

То Статический <H1> Займет Все Горизонтальное Место В Потоке, A <UL> Начнется Уже Четко Снизу.

Итак, Это ВСЕ, Что Касается Раскладки Меню CSS'ом. В Браузерах, Которые Поддерживают :Hover (Mozilla, Opera7), Оно Начнет Работать Уже Прямо Сразу. Для Internet Explorer'а Же Надо Будет Написать Очень Коротенький Скрипт, Который Будет Имитировать Это Поведение С Помощью Назначения Класса .Hover По OnMouseOver И Убирания По OnMouseOut:

<Script Type="text/javascript">
var Menu=document.getElementById('Menu');
for(var i=0;i<Menu.childNodes.length;i++)
with(Menu.childNodes[i])
if(nodeName=='LI'){
onmouseover=function(){this.className='Hover';};
onmouseout=function(){this.className='';};
}//if
</Script>

Комментарии Нужны?

Оформление.
Самое Последнее, Что Я Вчера Не Поленился Сделать, Это Поиграться С Подсветками, Шрифтами, Курсорами И Рамками. Подробно Описывать Не Буду, Это Просто Примерное Оформление:

#Menu {Background-Color:Gray; Color:White;
Font-Family:Verdana, Sans-Serif; Font-Size:10pt;
Line-Height:1.25em; Height:1.45em;}
#Menu LI H1 {Font-Size:10pt; Font-Weight:Normal;
Margin:0; Padding:0.1em 1em 0.1em 0.5em;
Cursor:Default;}
#Menu LI:Hover H1,
#Menu LI.Hover H1 {Background-Color:#AAA; Color:Black;}

#Menu LI UL {Background-Color:#EEE; Color:Black;
Border:Solid Gray; Border-Width:0 1px 1px 1px;}
#Menu LI UL LI A {Text-Decoration:None; Color:Black; Padding:0 0.5em;}
#Menu LI UL LI A:Hover {Background-Color:#AAA; Color:Black;}

Работающий Пример Здесь: http://SoftwareManiacs.Org/menu.htm

Заключение.
Это Не Идеальная Картинка (Впрочем, И Не "Обычная Женщина" Тоже). Например, Здесь Не Решены Вопросы Размещения Подменю Более Глубоких Уровней. Однако, Идею Этот Пример Показывает. Так Что, Дальнейшие Обсуждения Очень Приветствуются.

> Ммм, запомню... а вы педант! :-)

Я Маньяк :-)
СообщениеАвторДата
гость21.02.2003 00:58
ц08.03.2006 16:10
Leechy22.02.2003 03:22
Guest03.03.2003 19:19
гость22.02.2003 14:38
Maniac21.02.2003 11:39
гость22.02.2003 14:38
Maniac23.02.2003 18:11
05.04.2010 20:06
artz27.04.2009 16:13
гоша26.02.2003 21:24
Maniac27.02.2003 11:31
гоша27.02.2003 12:42
Leechy27.02.2003 20:13
гоша28.02.2003 12:18
PROnya27.02.2003 17:15
гость24.02.2003 20:28
Nick25.02.2003 03:02
Maniac25.02.2003 11:42
Андрей М.26.02.2003 12:08
Андрей М.26.02.2003 12:08
Maniac26.02.2003 12:40
Гость26.02.2003 14:44
Maniac26.02.2003 14:50
Nick26.02.2003 02:06
Maniac26.02.2003 02:12
Nick26.02.2003 06:15
Maniac26.02.2003 11:51
PROnya21.02.2003 10:03
гость22.02.2003 14:42