Главная/ HTML и CSS приемы | Обходим баги, находим интересные решения/ Navigation/ Выравнивание навигации из блоков по центру

Выравнивание навигации из блоков по центру

Дата публикации: 03.04.2009

Последнее обновление: 14.08.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;
}

Результат. Проверено в:

Заметка

Для более точного центрирования нужно убрать у последнего элемента отступ справа. Или же, если отступы для элементов навигации заданы слева, нужно убрать отступ у первого.

Теги: навигация