Выравнивание навигации из блоков по центру
Дата публикации: 03.04.2009
Задача
Есть навигация (список ul). Каждый элемент списка (li) — блочный. Количество элементов навигации заранее не известно. Список в виде строки (li имеют свойство float: left/right), для того чтоб навигация была в одну строку. Нужно выровнять эту навигацию по середине родителя
Имеем следующий HTML:
<div class="parent">
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li>3</li>
<li><a href="#">4</a></li>
</ul>
</div>
и CSS:
.parent {
width: 100%;
text-align: center; /*пытаемся выровнять содержимое по центру */
padding: 20px 0;
background: #6699FF; /* для наглядности обозначаем родителя */
float: left; /* чтоб высота родителя была с учетом плавающих потомков */
}
ul {
list-style: none;
font-size: 12px;
margin: 0 auto;
padding: 0;
}
li {
float: left; /* выстраиваем блочные элементы в ряд */
margin-right: 4px;
width: 23px;
height: 19px;
overflow: hidden;
text-align: center;
color: #fff;
font-weight: bold;
position: relative; /* для удобного размещения ссылки внутри */
background:url(images/testFonNeactiv.png); /* фоновая картинка текущей страницы*/
cursor: default;
padding-top: 3px;
}
li a {
color: #fff;
text-decoration: none;
position: absolute;
top: 0;
left: 0;
display: block;
background:url(images/testFonActiv.png);
text-align: center;
width: 23px;
height: 22px;
padding-top: 3px;
}
Как видно на примере обычное выравнивание блока по центру относительно родителя в этом случае не срабатывает, т.к. нет четко заданной ширины блока навигации.
Решение
Для решения этой проблемы используем конструкцию:
<div class="parent">
<span><!--или любой другой элемент уровня inline (строчный)-->
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
</span>
</div>
CSS:
.parent {
width: 100%; /* ширина нужна, только если блок плавающий (float) */
text-align: center; /* обязательно делаем выравнивание по центру */
float: left; /* в данном примере float нужен чтобы высота блока была с учетом плавающего содержимого */
padding: 20px 0;
background: #6699FF;
}
ul {
display: table; /* элемент типа таблицы имеет ширину, зависящую от содержимого */
width: auto; /* для уверенности что ширина будет зависеть от содержимого*/
margin: 0 auto; /* устанавливаем отступ слева и справа в auto */
list-style: none;
font-size: 12px;
padding: 0;
}
* html .parent span {/*хак для IE6, который не понимает display: table*/
display: inline-block;
}
*:first-child+html .parent span {/*хак для IE7, который не понимает display: table */
display: inline-block;
}
li {
float: left;
margin-right: 4px;
width: 23px;
height: 19px;
overflow: hidden;
text-align: center;
color: #fff;
font-weight: bold;
position: relative;
background:url(images/testFonNeactiv.png);
cursor: default;
padding-top: 3px;
}
* html li {
height: 22px;
}
li a {
color: #fff;
text-decoration: none;
position: absolute;
top: 0;
left: 0;
display: block;
background:url(images/testFonActiv.png);
text-align: center;
width: 23px;
height: 22px;
padding-top: 3px;
}
Результат. Проверено в:
В боевых условиях лучше использовать условные комментарии вместо хаков.
HTML код не пройдет проверку корректности (валидацию), т.к. элементы уровня inline (строчные) не могут содержать элементы уровня блок (блочные). Заменить в этом коде <span> на блочный элемент (например <div>) не получится — в IE навигация останется прижата влево.
Альтернативное решение (валидный код)
Если отказаться от использования списка, можно сделать и по стандартам:
HTML:
<div class="parent">
<span>
<a href="#">1</a>
<a href="#">2</a>
<b>3</b>
<a href="#">4</a>
</span>
</div
CSS:
.parent {
width: 100%;
text-align: center;
padding: 20px 0;
background: #6699FF;
}
span {
font-size: 12px;
margin: 0 auto;
padding: 0;
width: auto;
display: table;
}
* html .parent span {
display: inline-block;
}
*:first-child+html .parent span {
display: inline-block;
}
a, b {
float: left;
margin-right: 4px;
width: 23px;
height: 19px;
overflow: hidden;
text-align: center;
color: #fff;
font-weight: bold;
background:url(images/testFonActiv.png);
padding-top: 3px;
display: inline;
}
* html a, * html b {
height: 22px;
}
b {
background:url(images/testFonNeactiv.png);
cursor: default;
}
Результат. Проверено в:
Заметка
Для более точного центрирования нужно убрать у последнего элемента отступ справа. Или же, если отступы для элементов навигации заданы слева, нужно убрать отступ у первого.