Ранее я уже говорил о причинах, побудивших меня сделать меню на чистом CSS без использования JavaScript. Борясь с IE6, у меня получилась красивая версия вертикального меню — его реализация оказалась проще. Теперь обещанное горизонтальное меню.
Требования, которые я поставил:
Разметка для тестового примера была взята из этой статьи (которая и сподвигла меня на написание своего меню). В предыдущей статье код пришлось немного переработать (а всё из-за необходимости поддерживать IE6), и именно эту переработанную версию кода мы будем использовать.
<li>
<a href="#">Renaissance<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tbody><tr><td><![endif]-->
<ul>
<li><a href="#">Brunelleschi</a></li>
<li><a href="#">Alberti</a></li>
<li><a href="#">Palladio</a></li>
<li><a href="#">Michelangelo</a></li>
<li><a href="#">Bramante</a></li>
</ul>
<!--[if lte IE 6]></td></tr></tbody></table></a><![endif]-->
</li>
<li>
<a href="#">Art Nouveau<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tbody><tr><td><![endif]-->
<ul>
<li><a href="#">Mackintosh</a></li>
<li><a href="#">Guimard</a></li>
<li><a href="#">Horta</a></li>
<li><a href="#">van de Velde</a></li>
</ul>
<!--[if lte IE 6]></td></tr></tbody></table></a><![endif]-->
</li>
<li class="on">
<a href="#">Modern<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tbody><tr><td><![endif]-->
<ul>
<li><a href="#">Sullivan</a></li>
<li><a href="#">Le Corbusier</a></li>
<li><a href="#">Mies</a></li>
<li><a href="#">Gropius</a></li>
<li><a href="#">Yamasaki</a></li>
</ul>
<!--[if lte IE 6]></td></tr></tbody></table></a><![endif]-->
</li>
<li>
<a href="#">Postmodern<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tbody><tr><td><![endif]-->
<ul>
<li><a href="#">Venturi</a></li>
<li><a href="#">Eisenman</a></li>
<li><a href="#">Stern</a></li>
<li><a href="#">Graves</a></li>
<li><a href="#">Gehry</a></li>
</ul>
<!--[if lte IE 6]></td></tr></tbody></table></a><![endif]-->
</li>
<li>
<a href="#">Digital<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tbody><tr><td><![endif]-->
<ul>
<li><a href="#">Xenakis</a></li>
<li><a href="#">Lynn</a></li>
<li><a href="#">Diller+Scofidio</a></li>
<li><a href="#">Zellner</a></li>
<li><a href="#">Hadid</a></li>
</ul>
<!--[if lte IE 6]></td></tr></tbody></table></a><![endif]-->
</li>
</ul>
Таблица стилей для браузеров, поддерживающих CSS 2.1:
list-style: none;
margin: 0;
padding: 0;
}
#menu {
display: block;
width: 100%;
position: relative;
}
#menu li {
float: left;
height: 2em;
line-height: 2em;
}
#menu li a {
float: left;
border: 1px solid red;
vertical-align: middle;
padding: 0 .5em;
width: 100px;
}
#menu li ul {
display: none;
position: absolute;
top: 2em;
left: 0;
margin-top: 1px;
width: 100%;
background: #FFF;
height: auto;
}
#menu li.on ul, #menu li:hover ul {
display: block;
z-index: 10;
}
#menu li:hover ul {
z-index: 100;
}
#menu li li a {
display: block;
border: 1px solid red;
vertical-align: middle;
padding: 0 .5em;
}
Презентационные стили:
margin-left: -1px;
}
#menu li ul li + li {
margin-left: -1px;
}
#menu li a {
outline: 0;
text-decoration: none;
}
#menu li.on {
background: yellow;
}
#menu li:hover a, #menu li a:hover, #menu li a:hover a {
background: #EEE;
}
#menu li ul li:hover, #menu li ul li a:hover {
background: #EAFBFC;
}
Более детально это всё объяснено в предыдущей статье.
Теперь будем лечить IE6. У меня этот процесс занял несколько часов, но результат стоил того — оно работает!!!
overflow-x: hidden; /* Скрыть побочный эффект следующего исправления */
}
* html #menu li ul {
display: block;
z-index: 1;
margin-top: 2px;
overflow: visible;
/* Это исправляет неверное определение ширины - абсолютное значение width: 100% без этих строк было бы равно ширине родительского <a> */
padding-right: 1000em;
margin-right: -1000em;
}
* html #menu li.on a table,
* html #menu li a:hover table
{
visibility: visible;
}
* html #menu li.on a table ul {
z-index: -1; /* Ключевое исправление - без него меню правильно работать не будет. Предназначено для исправления последствий многочисленных багов в реализации z-index. Благодаря этому исправлению, все li a:hover table, находящиеся перед li.on table, будут нормально отображаться (не будут перекрываться li.on table) */
}
* html #menu li a:hover table ul {
z-index: 100;
}
* html #menu li a:hover {
position: static;
}
/* У таблицы теперь статическая позиция. Абсолютное/относительное позиционирование вносит ужасный бедлам в и без того глючную реализацию z-index в IE6. */
* html #menu table {
border-collapse: collapse;
visibility: hidden;
}
Замечания по реализации:
- Из-за плохой поддержки
z-index
Ишаком возможны проблемы сborder-top/bottom
у крайних правых элементов меню; - Из-за того, что пришлось использовать overflow-x, CSS не валидируется в рамках спецификации CSS 2.1 (но проходит валидацию CSS 3).
Тестовая страница лежит здесь.
А почему не Sliding doors with a drop line?
На самом деле все просто: во-первых, у меня используется на несколько списков меньше (Stu Nicholls использует 2n списков, я — n+1).
Во-вторых, в отличие от sliding doors, в данном случае не обязательно точно знать ширину каждого элемента меню. У меня это реализовано гораздо проще
В-третьих, собственный код всегда гораздо понятнее.
Весьма нестандартный подход. Конечно, для IE6 теряется весь семантичный смысл, но для него, вообще, много чего теряется…
Надеюсь, и IE6 скоро потеряется…
Довели бы в Micro$oft IE8 до ума, получился бы очень даже неплохой браузер. А IE7 и так уже вытесняет шестого Ишака.