Хаки и Скрипты Next Generation CMS

Вкладки-Табы на CSS

irbees2008 irbees2008 Опубликовано - 4 - июня CSS
4449 - 0
  • Автор: --------------
  • Адаптировал: irbees2008
  • Уровень сложности исполнения: нужны навыки css hmlt

Известны 3 способа организации вкладок на чистом CSS — при помощи overflow, :checked и :target. Пристального рассмотрения заслуживают первые два из них.

Итак, как же сделать переключение табов на CSS? Как мы помним, CSS и HTML являются чисто описательными языками. якорь заставляет браузер найти место в документе, содержащее якорь, и прокрутить страницу до него.
Также мы вспоминаем, что CSS позволяет описывать контейнеры, которые по ширине и/или высоте меньше, чем содержимое в контейнере. А что происходит с содержимым, выходящим за границы контейнера? Если у контейнера установлен аттрибут overflow: hidden то такое содержимое не отображается. Получается маленькое «окно», через которое нам видна часть большего региона.

Эти два факта позволяют организовать вкладочный интерфейс. В заголовках вкладок мы расположим ссылки на якори. А сами якори расположим на содержимом вкладок. При этом блок, внутри которого находится содержимое вкладок («окно»), ограничим в размерах так, чтобы одновременно через него была видна только одна вкладка. Работать это будет следующим образом: когда мы нажимаем на ссылку в заголовке вкладки, браузеру нужно показать нам соответтсвующий ярлык. И он будет прокручивать вкладки так, чтобы запрашиваемый якорь оказался в «окне».

HTML код для вкладок будет выглядеть следующим образом:

Код:
<div class="notebook" id="notebook1">
<ul class="tabs">
<li><a href="#tab1-1">Первая</a></li>
<li><a href="#tab1-2">Вторая</a></li>
<li><a href="#tab1-3">И третья</a></li>
<li><a href="#tab1-4">Даже четвертая</a></li>
<li><a href="#tab1-5">И совсем уж пятая</a></li>
</ul>
<ul class="pages">
<li id="tab1-1">1</li>
<li id="tab1-2">2</li>
<li id="tab1-3">3</li>
<li id="tab1-4">4</li>
<li id="tab1-5">5</li>
</ul>
</div>
Каждая вкладка должна быть представлена уникальным идентификатором-якорем. В этом коде мы видим якори tab1-1, tab1-2, tab1-3, tab1-4, tab1-5. Когда вы добавляете на свой сайт новые вкладки, не забывайте давать им новые названия якорей.

CSS довольно прост. Сначала задаем базовые параметры внешнего вида:
Код:
.notebook > *, .notebook > * > * {
margin: 0;
padding: 0;
}
.notebook > .tabs, .notebook > .pages {
list-style: none;
overflow: hidden;
}
.notebook > .tabs a {
float: left;
}
Самое важное здесь заключается в установке значения overflow: hidden.
Горизонтальный список вкладок (вместо вертикального) формируется при помощи float: left.

Кстати, во фреймворках для отображения графического интерфейса виджет, формирующий вкладки, обычно называется notebook. Поэтому CSS-класс для нашей панели вкладок я тоже назвал notebook.

Затем придадим нашим вкладкам привычный вид:
Код:
.notebook > .tabs > li > * {
border-left: 1px gray solid;
border-top: 1px gray solid;
}

.notebook > .tabs > li:last-child > * {
border-right: 1px gray solid;
}

.notebook > .pages {
border: 1px gray solid;
}

.notebook > .tabs {
font-family: Georgia;
font-size: 12px;
line-height: 30px;
height: 30px;
}

.notebook > .tabs a {
background: #eee;
padding: 0 10px;
text-decoration: none;
height: 30px;
}

.notebook > .tabs a:hover {
background: #ddd;
}
В этом фрагменте интерес представляет то, как формируется обводка заголовков вкладок. Для каждой ссылки мы включаем отображение левой и верхней границы. Т.к. ссылки состыковываются вплотную друг к другу, у нас получается правильная обводка каждой ссылки. Но для последней ссылки нам надо закрыть дыру с правой стороны, поэтому при помощи селектора li:last-child мы выбираем последнюю ссылку и включаем у ней правую границу. Для профи это всё очевидно, но для новичков, не очень хорошо знакомых с селекторами, будет полезно разобраться в этом примере.

Также мы тут задаём внешний вид текста этих ссылок — шрифт, размер и т.п.

Ну и наконец задаем фиксированные размеры для вкладок и для контейнера вкладок, что в итоге и даст нам возможность прокрутки:
Код:
#notebook1 > .pages, #notebook1 > .pages > li {
width: 500px;
height: 200px;
}
Обратите внимание: в предыдущих правилах CSS я использовал имя класса notebook, а в правиле, задающем размеры — идентификатор notebook1. Дело в том, что правила для класса notebook относятся к любой панели вкладок, а правила для указания размеров — «к вот этой конкретной» панели. У вас в одном документе может использоваться несколько панелей с вкладками, и для каждой панели вы, вероятно, захотите указать собственные размеры. В то время как остальные правила CSS остаются для них общими.

Данный способ организации вкладок удобен тем, что вы можете не только переключать вкладки в пределах страницы, но и легко сослаться на нужную вкладку с другой страницы. Можно поставить ссылку из другого документа, содержащую якорь нужной вкладки, и при переходе по такой ссылке страница откроется на заданной вкладке.

С другой стороны, как я уже выше отметил, если содержимое страницы не умещается на один экран, страница будет дергаться при переключении вкладок. Если вы делаете что-то типа веб-приложения, в котором возможность прокрутки страницы вообще не предполагается, то такой способ вам вполне подойдёт. Если у вас вкладки расположены в нижней части страницы (например, в футере под содержимым статей блога), то тоже всё нормально — дергания не будет, т.к. дальше прокручивать страницу некуда.

Также к недостаткам переключения вкладок overflow-способом можно отнести невозможность «правильным образом» сделать выделение заголовка текущей вкладки. Как вы заметили, в примерах выше все табы выглядят одинаково, независимо от того, какая вкладка открыта. Под правильным способом я подразумеваю способ, которые делается через CSS, без необходимости добавлять дополнительные элементы в html-код.

Тем не менее, существует хоть и «неправильный», но вполне рабочий способ добиться визуальной индикации текущей вкладки. У этого способа есть только одно ограничение: точная ширина заголовков вкладок должна быть нам известна заранее.

Посмотрим — что у нас изменяется при переключении вкладок? Изменяется только видимая область в прокручиваемом «окне». Значит, у нас единственный выход: элементы оформления, показывающие активную вкладку, должны быть привязаны к содержимому вкладки.

Возьмём панель с 4-мя вкладками. В начало содержимого каждой вкладки добавим div, содержащий 4 тега p. (Тегов должно быть по числу вкладок. Если у вас будет 5 вкладок, ставьте по 5 тегов p.)
Код:
<div class="notebook" id="notebook4">
<ul class="tabs">
<li><a href="#tab4-1">Первая</a></li>
<li><a href="#tab4-2">Вторая</a></li>
<li><a href="#tab4-3">Третья</a></li>
<li><a href="#tab4-4">Четвертая</a></li>
</ul>
<ul class="pages">
<li id="tab4-1">
<div class="page-top-border"><p></p><p></p><p></p><p></p></div>
1
</li>
<li id="tab4-2">
<div class="page-top-border"><p></p><p></p><p></p><p></p></div>
2
</li>
<li id="tab4-3">
<div class="page-top-border"><p></p><p></p><p></p><p></p></div>
3
</li>
<li id="tab4-4">
<div class="page-top-border"><p></p><p></p><p></p><p></p></div>
4
</li>
</ul>
</div>
Эти теги p мы вытянем в горизонтальную линию, и они будут служить границей, отделяющей заголовки вкладок от содержимого вкладок. Т.к. в таком случае граница не непрерывна, а состоит из отдельных сегментов, мы можем влиять на оформление этих сегментов из CSS.

Пишем CSS. Сначала часть, привязанная к классу notebook (т.е. общая для любых панелей вкладок):
Код:
.notebook > .pages > li > .page-top-border
{
margin: 0px;
padding: 0px;
border: none;
}

.notebook > .pages > li > .page-top-border > p
{
height: 1px;
background: gray;
float: left;
margin: 0px;
padding: 0px;
border: none;
}
Думаю, этот код понятен. Размещаем теги p в линию, задаем им высоту в 1 пиксель и серый цвет фона (такой же, как у границ вкладок).

Это еще не всё, что относится к классу notebook. Вот самая интересная часть магии:
Код:
.notebook > .pages > :nth-child(1) > .page-top-border> :nth-child(1),
.notebook > .pages > :nth-child(2) > .page-top-border> :nth-child(2),
.notebook > .pages > :nth-child(3) > .page-top-border> :nth-child(3),
.notebook > .pages > :nth-child(4) > .page-top-border> :nth-child(4)
{
background: inherit !important;
}
Опять же, если вы плохо знакомы с селекторами CSS, вам стоит разобраться, что тут происходит. До этого в правилах CSS мы задали серый цвет фона для p. В этом коде мы настройки фона выборочно отключаем обратно.

Селектор
Код:
.notebook > .pages > :nth-child(1)
выбирает первую вкладку на панели вкладок. Затем продолжение этого селектора
Код:
.page-top-border> :nth-child(1)
выбирает первый тег p в нашем блоке, служащем границей. Аналогично следующая строка выбирает второй сегмент границы на второй вкладке. Затем третий сегмент границы на третьей вкладке. Таких строк нужно в CSS добавить столько, сколько максимально у вас предполагается вкладок в пределах одного набора вкладок.

Теперь допишем стили, специфичные для конкретной панели:
Код:
#notebook4 > .pages {
border-top: none;
}

#notebook4 > .pages, #notebook4 > .pages > li {
width: 400px;
height: 150px;
box-sizing: border-box;
}

#notebook4 > .tabs > li > a,
#notebook4 > .pages > li > .page-top-border > p {
width: 100px;
box-sizing: border-box;
}
Во-первых, мы отключаем показ верхней границы для контейнера вкладок — border-top: none. Вместо этого у нас будет наша граница из отдельных сегментов.

Затем мы задаём размеры панели вкладок, ширину заголовков вкладок и сегментов границы. Важно, чтобы ширина вкладок и сегментов совпадала.

Свойство box-sizing: border-box указывает, что реальные размеры нужно считать с учетом ширины отступов и границ. (Без этого свойства браузер добавляет размеры отступов и границ к заданной в CSS ширине и высоте блоков.)

Исходный код CSS целиком:

Код:
.notebook > *, .notebook > * > * {
margin: 0;
padding: 0;
}
.notebook > .tabs, .notebook > .pages {
list-style: none;
overflow: hidden;
}
.notebook > .tabs a {
float: left;
}

.notebook > .tabs > li > * {
border-left: 1px gray solid;
border-top: 1px gray solid;
}

.notebook > .tabs > li:last-child > * {
border-right: 1px gray solid;
}

.notebook > .pages {
border: 1px gray solid;
}

.notebook > .tabs {
font-family: Georgia;
font-size: 12px;
line-height: 30px;
height: 30px;
}

.notebook > .tabs a {
background: #eee;
padding: 0 10px;
text-decoration: none;
height: 30px;
}

.notebook > .tabs a:hover {
background: #ddd;
}

#notebook1 > .pages, #notebook1 > .pages > li {
width: 500px;
height: 200px;
}

#notebook1 > .pages {
text-align: center;
line-height: 200px;
font-size: 150px;
}

#tab1-1 { background: #d81; }
#tab1-2 { background: #8d1; }
#tab1-3 { background: #1d8; }
#tab1-4 { background: #18d; }
#tab1-5 { background: #81d; }

#notebook2 > .pages, #notebook2 > .pages > li {
width: 320px;
height: 320px;
}

#notebook3 > .pages, #notebook3 > .pages > li {
width: 300px;
height: 250px;
}

#notebook3, #tab2-1 > img, #tab2-2 > img {
padding: 5px;
}

.notebook > .pages > li > .page-top-border
{
margin: 0px;
padding: 0px;
border: none;
}

.notebook > .pages > li > .page-top-border > p
{
height: 1px;
background: gray;
float: left;
margin: 0px;
padding: 0px;
border: none;
}

.notebook > .pages > :nth-child(1) > .page-top-border> :nth-child(1),
.notebook > .pages > :nth-child(2) > .page-top-border> :nth-child(2),
.notebook > .pages > :nth-child(3) > .page-top-border> :nth-child(3),
.notebook > .pages > :nth-child(4) > .page-top-border> :nth-child(4)
{
background: inherit !important;
}

#notebook4 > .pages {
border-top: none;
}

#notebook4 > .pages, #notebook4 > .pages > li {
width: 400px;
height: 150px;
box-sizing: border-box;
}

#notebook4 > .tabs > li > a,
#notebook4 > .pages > li > .page-top-border > p {
width: 100px;
box-sizing: border-box;
}

Можешь почитать и вот эту статейку " Много-уровневое адаптивное меню"

Опрос

Ваше мнение

Какой поисковой системой пользуетесь?
Результаты

Последние комментарии

Теги

Anything in here will be replaced on browsers that support the canvas element

Статистика

  • Caйту: 4401 день
  • Новостей: 566
  • Комменты: 257
  • Зарегистрированно : 662
  • Онлайн всего: [1]
  • Гости: [1]
  • Были сегодня : [2] Яндекс, Google
  • SQL запросов: 33
  • Генерация страницы: 0.778сек
  • Потребление памяти: 6.149 Mb 
  •   Яндекс.Метрика