Сайт вебмастера

Пример создания универсального LESS-микса для табов (вкладок)

24-06-2012Время чтения ~ 6 мин.CSS, HTML, LESS, SASS 20224

В MaxSite CMS 0.73 с помощью плагина Tabs можно задавать табы прямо в тексте. Делается это довольно просто с помощью bb-кодов.

[tabs]
 
[tab=Один]
текст первый
[/tab]
 
[tab=Два]
текст второй
[/tab]
 
[tab=Три]
текст третий
[/tab]
 
[/tabs]

В default-шаблоне уже присутствуют базовые css-стили для табов, правда они довольно невзрачные.

Покажу как можно улучшить вид табов и сделать универсальный микс, который можно использовать в разных шаблонах. Результат может быть таким.

Устройство табов

Вначале нужно определить из каких HTML-элементов состоит блок табов. Можно заглянуть в сам плагин, исходный код страницы, а можно воспользоваться «Исследовать элемент» в FireFox. Без разницы какой вариант выбрать, нужно лишь «вычленить» все тэги и их классы.

В нашем случае структура будет такой:

<div class="tabs">
	<ul class="tabs-nav">
		<li class="elem tabs-current"><span>Один</span></li>
		<li class="elem"><span>Два</span></li>
		<li class="elem"><span>Три</span></li>
	</ul>
	
	<div class="clearfix"></div>
	
	<div class="tabs-box">текст первый</div>
	<div class="tabs-box">текст второй</div>
	<div class="tabs-box">текст третий</div>
</div>

В общем понятно. Есть общий блок, список навигации и блоки содержимого. Теперь, нам нужно перенести эту структуру в less-стиль. Если это сделать, то при верстке стилей мы сразу будем видеть кто за что отвечает.

Кроме структуры, есть смысл сразу задать и некоторые действия, например :hover для подсветки.

div.tabs {
	ul.tabs-nav { // навигация
	
		li.elem { // пункт навигации
 
			&:hover { // при наведении
			}
		}
		
		li.tabs-current { // текущий пункт
		
			&:hover { // при наведении
			}
		}
	}
	
	div.tabs-box { // содержимое каждого элемента
	}
}

То есть этот та же самая структура, только я добавил :hover для элементов навигации.

Теперь нужно настроить css-стили под выбранный дизайн. Описание каждого правила несколько выходит за рамки данной статьи, поэтому я сразу приведу готовый вариант.

div.tabs {
	
	ul.tabs-nav { // навигация
		
		margin-left: 10px;
		
		li.elem { // пункт навигации
			margin: 0 2px 0 0;
			padding: 0 15px;
			color: white;
			.bold;
			.background_gradient(darken(#5A85DD, 30%), #5A85DD);
			.box_shadow_inset(0, -2px, 5px, darken(#5A85DD, 30%));
			
			&:hover { // при наведении
				.background_gradient(lighten(#5A85DD, 3%), lighten(#5A85DD, 1%));
			}
		}
		
		li.tabs-current { // текущий пункт
			
			color: darken(#F2F2F2, 60%);
			
			.background_gradient(darken(#F2F2F2, 10%), #F2F2F2);				
			.box_shadow_inset(0, 3px, 3px, darken(#F2F2F2, 30%));
			
			&:hover { // при наведении
				color: darken(#F2F2F2, 70%);
				.background_gradient(darken(#F2F2F2, 30%), #F2F2F2);
			}
		}
	}
	
	div.tabs-box { // содержимое каждого элемента
		background: #F2F2F2;
		.border_radius(5px);
		.box_shadow(0, 0, 3px, darken(#F2F2F2, 30%));
	}
}

Часть стилей сделана обычными css-правилами, а часть с помощью миксов. Я рекомендую завести свой вариант helpers.less и подключать его в каждом своём шаблоне. Со временем можно собрать большую коллекцию интересных и полезных миксов. Если же микс предназначен только для какого-то отдельного блока, то его лучше вынести в отдельный файл. Например для меню это может быть menu.less, а для табов tabs.less.

В данном варианте я использую несколько миксов. Приведу их полностью.

// полужирный
.bold()
{
	font-weight: bold;
}
 
// линейный градиент
.background_gradient (@startColor: #555, @endColor: #333)
{
    background-color: @endColor;
    background-repeat: repeat-x;
    background-image: -khtml-gradient(linear, left top, left bottom, from(@startColor), to(@endColor));
    background-image: -moz-linear-gradient(top, @startColor, @endColor);
    background-image: -ms-linear-gradient(top, @startColor, @endColor);
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, @startColor), color-stop(100%, @endColor));
    background-image: -webkit-linear-gradient(top, @startColor, @endColor);
    background-image: -o-linear-gradient(top, @startColor, @endColor);
    background-image: linear-gradient(top, @startColor, @endColor);
    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor));
}
 
// внутренняя тень 
.box_shadow_inset(@x: 0, @y: 0, @feather: 0, @bcolor: #000) 
{
	box-shadow: inset @x @y @feather @bcolor;
	-moz-box-shadow: inset @x @y @feather @bcolor;
	-webkit-box-shadow: inset @x @y @feather @bcolor;
}
 
// тень блока
.box_shadow(@x, @y, @blur: 3px, @color:#888) 
{
	-o-box-shadow: @arguments;
	-webkit-box-shadow: @arguments;
	-moz-box-shadow: @arguments;
	box-shadow: @arguments;
}

// скругление углов 
.border_radius(@radius)
{
	-webkit-border-radius: @radius;
	-moz-border-radius: @radius;
	border-radius: @radius;
}

Теперь отдельное внимание обращу на функции darken() и lighten(). Это встроенные функции LESS: первая отдаёт цвет темнее указанного на NN%, вторая - светлее. Я использую эти функции, чтобы не вычислять (снимать пипеткой) цвета градиентов. Если внимательно посмотреть на код табов, то видно, что используются лишь несколько базовых цветов. Остальные могут быть вычисленны на их основе.

Делаем микс

Теперь, когда код табов объяснён, приступим непосредственно к созданию микса. Я сделал отдельный файл tabs.less где разместил микс .tabs.

.tabs
{
	тут наш код табов
}

В основном less-файле шаблона используем так:

// табы 
@import url('tabs.less');
.tabs;

Вводим переменные/аргументы

Теперь было бы неплохо сделать так, чтобы можно было произвольно менять цвета. Самый простой вариант - это заменить все явно указанные цвета на аргументы/переменные микса. По коду видно, что у нас всего четыре основных цвета:

  • фон элементов навигации
  • фон содержимого и текущего таба
  • цвет текста таба
  • цвет текста текущего таба

Дальше, нужно просто заменить цвета соответствующими переменными. Привожу сразу готовый код микса.

.tabs(
	@nav_tab: #5A85DD, // основной цвет табов
	@box_bg: #F2F2F2, // фон содержимого
	@nav_text: white, // цвет текста табов
	@box_text: gray // цвет текста текущего таба
)
{
	div.tabs {
		
		ul.tabs-nav { // навигация
			
			margin-left: 10px;
			
			li.elem { // пункт навигации
				margin: 0 2px 0 0;
				padding: 0 15px;
				color: @nav_text;
				.bold;
				.background_gradient(darken(@nav_tab, 30%), @nav_tab);
				.box_shadow_inset(0, -2px, 5px, darken(@nav_tab, 30%));
				
				&:hover { // при наведении
					.background_gradient(lighten(@nav_tab, 3%), lighten(@nav_tab, 1%));
				}
			}
			
			li.tabs-current { // текущий пункт
				
				color: @box_text;
				
				.background_gradient(darken(@box_bg, 1%), @box_bg);				
				.box_shadow_inset(0, 3px, 3px, darken(@box_bg, 30%));
				
				&:hover { // при наведении
					color: darken(@box_text, 30%);
					
					.background_gradient(darken(@box_bg, 3%), @box_bg);
				}
			}
		}
		
		div.tabs-box { // содержимое каждого элемента
			background: @box_bg;
			.border_radius(5px);
			.box_shadow(0, 0, 3px, darken(@box_bg, 30%));
		}
	}
	
} // .tabs

Использовать можно так:

.tabs(red, gold, khaki);

Еще вариант:

.tabs(Lime, Chartreuse, Palegreen);

Серый вариант:

.tabs(gray, silver, whitesmoke);

Ещё вариант с указанием цвета текста текущего таба.

.tabs(#1E90FF, #4169E1, #BBC5E5, #F0FFF0);

Несколько дизайнов в одном миксе

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

Первый вариант. Если дизайны сильно различаются, то для микса .tabs следует придумать подмиксы.

.tabs
{
	.design1(агрументы микса)
	{
		div.tabs {
			...
		}
		
	}
	
	.design2(агрументы микса)
	{
		div.tabs {
			...
		}
		
	}
}

Использовать так:

.tabs > .design1();

Второй способ немного сложней и больше подходит под настройку «типового» дизайна. Также вводятся подмиксы, только с «функциональным» разделением. Например микс .base() будет выводить только положения элементов, размеры, отступы. Для градаций использовать другой микс, для цветов - третий и т.п. Использовать его нужно примерно так:

.tabs > .base(); // основа
.tabs > .color(указываем основные цвета);
.tabs > .gradient(); // если используются градиенты
.tabs > .shadow(); // если используются тени
.tabs > .font(bold); // какие-то параметры шрифта

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

Несколько табов с разными дизайнами одновременно

Задача довольно распространённая: задать сразу несколько оформлений одного микса. Скажем в записи используются три таба с разными базовыми цветами: красный, зеленый и синий. Мы же можем задать ведь только один вариант...

На помощь прийдет военная хитрость. :) Мы обрамим в тексте записи табы отдельным DIV, и микс применим уже к нему.

[tabs]
... первый таб ...
[/tabs]
 
[div(tabs-green)]
	[tabs]
	... второй таб ...
	[/tabs]
[/div]
 
[div(tabs-blue)]
	[tabs]
	... третий таб ...
	[/tabs]
[/div]

Я задал DIV с помощью bb-кодов, но это не принципиально. Главное, чтобы каждый блок табов оказался в своём контейнере.

Теперь используем:

// дефолтное оформление
.tabs(red);
 
// зеленый вариант
div.tabs-green {
	.tabs(green);
}
 
// синий вариант
div.tabs-blue {
	.tabs(blue);
}

LESS полностью взял всю работу на себя и расставил вложенные css-правила как положено. Удобно, не так ли?

Похожие записи
Комментарии (2) RSS
1 Паша 2012-06-26 23:53:15

Такой вот вопрос:

Я делал свой шаблон на основе каркаса createa_new_template, мне что-то не понятно, там как бы less не подключён, так вот как его подключить чтобы замутить сие чудо?


2 Admin 2012-06-27 08:55:42 admin

Основнее описания в ридми-файле.

Или вики: http://wiki.max-3000.com/pmwiki.php?n=Main.Template-default-less