Но ближе к сути... По причине необходимости вернулся к поиску рабочего варианта выпадающего меню на основе CSS - и такое решение было достаточно быстро найдено, что совершенно не удивительно учитывая многолетнюю историю
Решения
Для начала возьмем совершенно обыкновенную разметку ниспадающего меню, на большинстве современных сайтов можно найти идентичные варианты:
<ul class="menu">И сотворим примерное работающее меню с помощью CSS:
<li>
<a href="#" title="Main">Main</a>
<ul>
<li><a href="#" title="Services">Services</a></li>
<li><a href="#" title="Products">Products</a></li>
<li><a href="#" title="Job">Job</a></li>
</ul>
</li>
<li>
<a href="#" title="Portfolio">Portfolio</a>
<ul>
<li><a href="#" title="Projects">Projects</a></li>
<li><a href="#" title="Styles">Styles</a></li>
<li><a href="#" title="Private clients">Private clients</a></li>
</ul>
</li>
<li>
<a href="#" title="FAQ">FAQ</a>
<ul>
<li><a href="#" title="Q&A">Q&A</a></li>
<li><a href="#" title="Wiki">Wiki</a></li>
</ul>
</li>
</ul>
a {Решение стандартное и опять таки в тех или иных вариациях используется часто, но оно не работает в IE6... А справляются с этим следующим образом:
color:#555;
}
a:hover {
color:#000;
}
.menu {
list-style:none;
margin:0;
padding:0;
}
.menu li {
position:relative;
float:left;
margin:0;
padding:0.2em 1em;
}
.menu li:hover {
background:#CCC;
}
.menu ul {
display:none;
position:absolute;
left:0;
top:1.5em;
list-style:none;
margin:0;
padding:0;
background:#EEE;
}
.menu ul li{
float:none;
}
.menu li:hover ul{
display:block;
}
Первое решение:
Идея состоит в том, что для всех современных брайзеров будут обрабатываться hover события для li элементов, что является естественным решением, а для IE6 будет привязываться специальный обработчик, который будет менять классы у li элементов. Таким образом в CSS придется одинаково описывать стиль представления для события наведение (:hover) и для класса с аналогичным названием (.hover).
В этом случае верстка не изменяется, но расширяется СSS:
.menu li:hover,
.menu li.hover{
background:#CCC;
}
.menu li:hover ul,
.menu li.hover ul,{
display:block;
}
И добавляется js-обработчик. А следовательно, и само решение становиться зависимым от JavaScript:
menuEventer = function() {
if (document.all && document.getElementsByTagName) {
var elements = document.getElementsByTagName("LI");
for (var i=0; i < elements.length; i++) {
elements[i].onmouseover=function() {
this.className+=" hover";
}
elements[i].onmouseout=function() {
this.className=this.className.replace(" hover", "");
}
}
}
}
window.onload = menuEventer;
Такой не сложный обработчик заставляет работать меню, но такое решение, найденное в свое время Патриком Гриффитс и Даном Уэбб, нельзя назвать красивым...
Второе решение:
Второе решение частично вытекает из первого и связно с тем, что возможно избавиться от ручного расширения css и добавления js-обработчиков, но по сути оно является аналогичным. Основывается оно на использование скриптов поведения подключаемых через css-свойство behavior. Найти подобный скрипт не сложно, а разработчику достаточно только включить новое правило в css:
body {
behavior: url("csshover3.htc");
}
Такое решение так же заставляет IE6 работать и является куда более элегантным, однако зависимость от JavaScript по-прежнему осталась...
Третье решение:
Третье решение основано на специфическом изменении верстки, которое позволило бы использовать hover для элемента a. При этом ясно, что зависимость от JavaScript уйдет и может получиться интересное решение.
Идея верстки состоит в том, чтобы вложить в элемент a все подменю (элемент ul) с его ссылками:
<ul class="menu">В таком случае изменив CSS следующим образом можно было бы ожидать нормальное решение:
<li>
<a href="#" title="Main">Main
<ul>
<li><a href="#" title="Services">Services</a></li>
<li><a href="#" title="Products">Products</a></li>
<li><a href="#" title="Job">Job</a></li>
</ul>
</a>
</li>
<li>
<a href="#" title="Portfolio">Portfolio
<ul>
<li><a href="#" title="Projects">Projects</a></li>
<li><a href="#" title="Styles">Styles</a></li>
<li><a href="#" title="Private clients">Private clients</a></li>
</ul>
</a>
</li>
<li>
<a href="#" title="FAQ">FAQ
<ul>
<li><a href="#" title="Q&A">Q&A</a></li>
<li><a href="#" title="Wiki">Wiki</a></li>
</ul>
</a>
</li>
</ul>
a {
color:#555;
}
a:hover {
color:#000;
}
.menu {
list-style:none;
margin:0;
padding:0;
}
.menu li {
float:left;
margin:0;
}
.menu a {
display:block;
position:relative;
padding:0.2em 1em;
}
.menu a:hover {
background:#CCC;
}
.menu a ul {
display:none;
position:absolute;
left:0;
top:1.5em;
list-style:none;
margin:0;
padding:0;
background:#EEE;
}
.menu a ul li{
display:block;
float:none;
}
.menu a:hover ul {
display:block;
}
Это решение во-первых, является не валидным решением, а во-вторых, ни один современный браузер подобного сделать не даст и будет исправлять верстку до первоначального варианта. Однако с некоторыми проблемами IE6 это проглотит, правда может вылетать через некоторое время после активного пользования "таким" меню.
Обойти такую проблему можно еще более страшным изменением верстки, вложить все вложенное меню в таблицу, а уже таблицу вложить в ссылку первого уровня (^_^ знаю, pepelsbey на меня нет):
<ul class="menu">А CSS подправив следующим образом:
<li>
<a href="#" title="Main">Main
<table><tr><td>
<ul>
<li><a href="#" title="Services">Services</a></li>
<li><a href="#" title="Products">Products</a></li>
<li><a href="#" title="Job">Job</a></li>
</ul>
</td></tr></table>
</a>
</li>
<li>
<a href="#" title="Portfolio">Portfolio
<table><tr><td>
<ul>
<li><a href="#" title="Projects">Projects</a></li>
<li><a href="#" title="Styles">Styles</a></li>
<li><a href="#" title="Private clients">Private clients</a></li>
</ul>
</td></tr></table>
</a>
</li>
<li>
<a href="#" title="FAQ">FAQ
<table><tr><td>
<ul>
<li><a href="#" title="Q&A">Q&A</a></li>
<li><a href="#" title="Wiki">Wiki</a></li>
</ul>
</td></tr></table>
</a>
</li>
</ul>
a {
color:#555;
}
a:hover {
color:#000;
}
.menu {
list-style:none;
margin:0;
padding:0;
}
.menu li {
float:left;
margin:0;
height:1%;
position:relative;
}
.menu a {
display:block;
padding:0.2em 1em;
}
.menu a:hover {
background:#CCC;
}
.menu a table {
display:none;
position:absolute;
left:0;
top:1.5em;
}
.menu a table ul {
list-style:none;
margin:0;
padding:0;
}
.menu a ul li{
float:none;
display:block;
margin:0;
padding:0;
}
.menu a:hover table {
display:block;
background:#EEE;
}
Однако в результате получается, что такое "специфическое" решение нормальные браузеры и IE6 понимают и обрабатывают, а вот более IE7 и выше уже не понимают...
Последнее решение:
Идея этого решения, собственно на котором я и остановился, состоит в объединении естественного решения для нормальных браузеров и специфического решения для IE6. Такое объединение позволяет организовать механизм условных комментариев (conditional comments), поддерживаемый в браузерах Internet Explorer.
Изменяем верстку с использованием условных комментариев:
<ul class="menu">Для современных браузеров оставляем изначальную верстку, а для IE6 переопределяем правила:
<li>
<a href="#" title="Main">Main
<!--[if gte IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->
<ul>
<li><a href="#" title="Services">Services</a></li>
<li><a href="#" title="Products">Products</a></li>
<li><a href="#" title="Job">Job</a></li>
</ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>
<li>
<a href="#" title="Portfolio">Portfolio
<!--[if gte IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->
<ul>
<li><a href="#" title="Projects">Projects</a></li>
<li><a href="#" title="Styles">Styles</a></li>
<li><a href="#" title="Private clients">Private clients</a></li>
</ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>
<li>
<a href="#" title="FAQ">FAQ
<!--[if gte IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->
<ul>
<li><a href="#" title="Q&A">Q&A</a></li>
<li><a href="#" title="Wiki">Wiki</a></li>
</ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>
</ul>
.menu li {Замечу, что эти правила также подключаются к странице через условные комментарии, что избавить современные браузеры от загрузки не нужных правил.
position: relative;
padding:0;
height:1%;
}
.menu li a {
display:block;
padding:0.2em 1em;
}
.menu li a:hover {
background:#CCC;
}
.menu a ul {
background:none;
}
.menu a ul li{
display:inline;
}
.menu a:hover ul {
display:block;
background:#EEE;
}
Таким образов, получаем кроссбраузерное решение, которое можно значительно усложнить, что продемонстрировал Stu Nicholls.
Конец ретроспективе, возвращаемся в будущее! ^_^
И не стыдно использовать СТОЛЬКО условных комментариев в html-коде?
ОтветитьУдалитьТолько behaviour: url(.htc);!
Не стыдно, так как это оправданно... С behavior есть серьезная зависимость от js и настроек безопасности IE.
ОтветитьУдалитьБольшое количество условных комментариев скрашивается более универсальным решением в целом...