CSS

Резиновое меню

Сделать резиновое меню, которое занимает всю доступную ширину родителя. При этом первый пункт располагается у левого края, последний — у правого и расстояния между пунктами одинаковые.



Требования

все пункты должны быть в одну строку;
универсальность: число пунктов и длина текста в каждом за ранее не известна, количество слов в пункте может быть разным;
семантический код: меню должно быть обычным списком;
без использования javascript.

Проблема

Задача казалось бы несложная, но для ее решения обычно применяется таблица или javascript. Проэмулировать для этой задачи таблицу с помощью display: table/table-cell не выходит, по крайней мере кроссбраузерно. Вот и имеем 21 век на дворе, HTML5, CSS3, а такое меню реализовываем «костылями». Но решение все-таки нашлось.

Решение

Основная фишка — это применение свойства text-align: justify, которое позволяет растянуть текст на всю ширину родителя. Одна важная особенность — такое выравнивание сработает, если текста будет больше, чем на одну строку. Вторая особенность — слова будут растягиваться независимо от того в разных они пунктах или в одном. Но все в принципе решаемо:
HTML
	<ul>
	<li><a href="#">Главная</a></li>
	<li><a href="#">Собираем</a></li>
	<li><a href="#">Следим</a></li>
	<li><a href="#">Без цензуры</a></li>
	<li><a href="#">Учимся</a></li>
	<li><a href="#">Справочники</a></li>
	</ul>


CSS
	ul {
	    text-align: justify;
	    overflow: hidden; /* нужно чтобы обрезать разные побочные эффекты приема */
	    height: 20px; /* нужна чтобы устранить один побочный эффект, но иногда можно обойтись без нее */
	    cursor: default; /* растянутый текст justify приведет к тому что почти вся плашка меню будет иметь cursor: text */
	    margin: 50px 100px 0 100px;
	    background: #CCCCCC;
	    padding: 5px;
	}
	li {
	    display: inline; /* чтобы пункты меню выступали в роли текста */
	}
	li a {
	    display: inline-block; /* чтобы не разрывались слова в пунктах меню */
	    color: #0000CC;
	}
	a:hover {
	    color: #ff0000;
	}
	ul:after { /* эмуляция дополнительной строки, чтобы сработал justify */
	    content: "1";
	    margin-left: 100%;
	    height: 1px;
	    overflow: hidden;
	    display: inline-block;
	}

Для IE6 и 7 потребуется дополнительный код:
CSS
	ul {
	    z-index: expression(runtimeStyle.zIndex = 1, insertAdjacentHTML('beforeEnd&apos, '<li class="last"></li>'));
	}
	ul .last {
	    margin-left: 100%;
	}
	* html ul { /* need ie6 only */
	    height: 30px;
	}

Проверено в:
IE 6-8
Firefox 3.6
Opera 10.5
Safari 5
Chrome 6

Недостатки

«раздутый» CSS-код;
не получится сделать по обычному активный пункт меню (<li class="active">текущий пункт</li>) из-за того, что теперь слова в пункте будут разрываться (если, конечно, слов в пункте больше, чем одно). Решить можно добавлением тега, обрамляющего текст, с правилами аналогичными ссылке. Например так: <li class="active"><span>текущий пункт</span></li>;
из-за overflow могут быть проблемы, если понадобится выпадающие подменю — придется код под такую задачу подгонять.
Теги:
Резиновое меню
Добавлено: 16 Августа 2013 09:39:39 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...