Посты с тэгом «tabs»

  • Верстка табов с помощью <dl>

    Когда-то возникла необходимость сделать табы на странице. Это довольно типовая задача, поэтому, чтобы не изобретать велосипед, полез в Гугл посмотреть, как народ делает. Все реализация, которые я увидел, выглядели довольно стандартно, примерно так:

    <div class="tabs">
    	<ul class="nav">
    		<li>Tab 1</li>
    		<li>Tab 2</li>
    		<li>Tab 3</li>
    		<li>Tab 4</li>
    		<li>Tab 5</li>
    	</ul>
    
    	<ul class="content">
    		<li>Tab content 1</li>
    		<li>Tab content 2</li>
    		<li>Tab content 3</li>
    		<li>Tab content 4</li>
    		<li>Tab content 5</li>
    	</ul>
    </div>
    

    То есть два независимых списка, в одном заголовки, во втором — содержимое.

    Лично меня такая структура не устраивает, главным образом из-за того, что отсутствует семантическая связь между заголовком и содержимым. Хоть я и не страдаю наркозависимостью верстать все «валидно и семантично» ради респекта и уважухи гиков, тут отсутствие четкой связи было все-таки недостатком. Во-первых, данные из бэкэкнда придется выводить в два цикла (сначала заголовки, а потом контент), а не одним. Это хоть немного, но увеличивает объем кода и явно не добавляет производительности. Во-вторых, клиентский скрипт для переключения табов тоже будет больше и сложнее, особенно с учетом того, что на странице может быть несколько блоков с табами.

    Решил попробовать избавиться от этих проблем, а заодно размять мозги 🙂 При выборе структуры элементов первым делом выбор пал на <dl>-список, который как нельзя лучше подходит для этой задачи. Думаю, не я первый решил попробовать сделать табы с помощью этого списка. Вот что у меня получилось.

    Чтобы приведенный пример не стал очередным источником бездумного копи-пэйста, давайте рассмотрим, за счет чего это работает.

    Предположим, у нас есть набор элементов, которым указан float: left:

    stage12

    А что будет, если одному из элементов этой последовательности указать float: right?

    stage21

    Уже неплохо: элементы, следующие за <dd>, встали ровно за предыдущими. Но нам нужно, чтобы содержимое таба растягивалось на всю ширину, поэтому прописываем этому элементу width: 100%:

    stage31

    Как и ожидалось, элемент разорвал поток. Размышляем так: если элемент прижат к правому краю контейнера, значит при изменении ширины будет изменяться левый край элемента (то есть <dd> растет справа налево). Значит, нам нужно подавить влияние левого края элемента. Сделать это можно с помощью margin-left: -100%:

    stage41

    Осталось сместить элемент вниз, сделать это можно с помощью margin-top:

    stage5

    Вот и все. По умолчанию все <dd>-элементы скрываем с помощью display: none, выбранному элементу говорим display: block. Скрипт переключения табов на jQuery выглядит совсем уж просто:

    $(function(){
    	$('dl.tabs dt').click(function(){
    		$(this)
    			.siblings().removeClass('selected').end()
    			.next('dd').andSelf().addClass('selected');
    	});
    });
    

    Способ получился не супергибким (есть привязка к точному размеру закладки таба), однако позволяет решать большинство подобных задач.

    Метки: , ,