can3p: (Default)
can3p ([personal profile] can3p) wrote2010-04-27 12:35 am
Entry tags:

Горизонтальное css-меню

Для сайта fistashki.org потребовалось доработать меню для обеспечивания корректной работы выпадающих подменю. При этом пункты, над которыми наводилась мышь, должны были подсвечиваться зеленым цветом, в том числе и пункт меню, соответствующий текущей странице, который в обычном состоянии должен был быть черным. Кроме того, в раскрывающемся списке ширина пунктов должна определяться по ширине самого длинного пункта меню.

Работа была произведена, меню работает в ie6-8, FF 2.0+, opera 9.6+, safari 4 и chrome 4 (две последние версии указаны такими просто потому, что под рукой не было более ранних версию браузеров для проверки).

Изначально хотел описать создание меню по шагам с остановками на всех встреченных багах, но прошел месяц, и могу только наметить общие технические приемы, которые были применены.

И да, поиск в интернете показал, что это чуть ли не единственная реализация, которая стабильно правильно работает в IE8! Продолжительные аплодисменты, переходящие в бурные овации.

Проще всего дело обстоит с современными браузерами, в них все работает сразу как и предполагается, основной интерес представляют различные explorer’ы.

IE8 отличается интересной интерпретацией :hover. Интересность заключается в глюках, когда дочерний элемент позиционируется визуально рядом с родительским, на котором применяется правило :hover. Логичное поведение состоит в том, чтобы правило :hover начинало действовать при наведении мыши на родительский элемент и продолжало действовать, когда мышь идет по дочерним элементам, но ie8 думает иначе. Глядя с высоты сегодняшнего дня фикс кажется магическим:

.menu .pages a:hover+li
{
    display: block;
}

Магия хотя бы в том, что элемент li никак не может оказаться на одном уровне подчинения с a.

Касательно выравнивания фона раскрывающегося меню – всем firefox и webkit-браузеры успешно приняли такой подход: оборачивающему блоку назначается float: left; дочерним float:left совместно с width:100% и white-space:nowrap для текста внутри. В результате оборачивающий блок сжимается до размера самого широкого дочернего блока, а короткие внутренние элементы до этой ширины растягиваются. В ie8 ширина всех блоков принималась минимальной, в ie6 блоки растягивались на весь экран. Для решения этой проблемы был написан .htc файл, который подключался через behavior. Основной плюс этого свойства в том, что оно рассчитывается один раз при загрузке страницы. htc-скрипт перебирает список и вручную выставляет ширину по самому широкому элементу. Т.к. при назначенном display:none; размеры блока не считаются, то все подменю спрятаны при помощи абсолютного позиционирования, что на самом деле сработало только во благо и автоматически убрало множество багов позиционирования относительного, о которых можно было бы еще много чего написать.

Определенно какие-то хитрости еще применялись  для того, чтобы текущий пункт выделялся черным, но при наведении все равно становился зеленым вместе с подпунктами, а так же в тех местах, где подменю должно  перекрывать очаровательные галочки, появляющиеся под элементами меню первого уровня. Все это предлагается пытливому читателю для самостоятельного разбора и изучения.

Само меню можно посмотреть здесь: http://test.dpetroff.ru/cssmenu/index.html


Оригинал: http://blog.dpetroff.ru/tech/horizontal-css-menu