Современная, быстрая и удобная система управления сайтом

Шаблоны для новичков. Урок 16. Основы вёрстки с помощью LESS

Архив записейКомментарии: 3Просмотров: 3371

На сегодняшний момент существует два принципиально разных современных подхода к вёрстке сайта. Первый - основанный на css-фреймворке. В нём задаются какие-то базовые css-стили, классы которых указываются в соответствующих html-тэгах.

<div class="red">красный текст</div>
<div class="yellow">желтый цвет</div>

потому что в css-фреймворке уже определено, что

div.red {color: red;}
div.yellow {color: yellow;}

Простой пример, который показывает, что вебмастер пользуется уже готовыми css-стилями и не тратит время на их написание. Его работа заключается в том, чтобы модифицировать html-код. Но в этом и есть гиганский минус такого подхода.

Предположим, что у нас есть какой-то компонент, имеющий «типовую» html-схему:

<div class="mycomponent"><div class="wrap">
... вывод компонента ...
</div></div>

При использовании css-фреймворка нам придётся указывать дополнительные классы для div.mycomponent. Причём делать это постоянно, посколько в процессе создания шаблона, дизайн, размеры или расположение компонента могут поменяться. В итоге вебмастер всё-равно вынужден будет создать

div.mycomponent { свои стили }

чтобы собрать стили компонента в одном месте.

Совсем сложной будет ситуация с компонентами, состоящими из двух и более ячеек/блоков. Для примера рассмотрим, как предлагает оформлять такие вещи Twitter Bootstrap.

<div class="mycomponent"><div class="wrap">
	<div class="row">
		<div class="span4">...</div>
		<div class="span8">...</div>
	</div>
</div></div>

В этом примере ясно видно, что у нас появились три предопределенных класса: row, span4 и span8. Но, что делать, если мы решим поменять пропорции блоков или даже задать их фиксированной шириной, при том, что первый будет выровнен влево, второй - вправо? Согласно идеологии фреймворка, придется опять лезть в исходный html-код компонента и прописывать недостающе классы и менять существующие. И, опять же, всё-равно придётся создавать отдельные стили для div.mycomponent и его вложенных div-блоков.

Я не утверждаю, что использование css-фреймворков неприемлемо. Это в любом случае лучше, чем пользоваться хаотичной схемой верстки. Но css-фреймворк упрощает работу только в самых базовых аспектах, которые могут быть описаны 2-3 css-правилами, причем сделаны это точно для нужных элементов.

Недостатков css-фреймворков нет в верстке через LESS. Главное преимущество здесь в том, что вебмастер только один раз задаёт html-код, а дальше всю работу выполняет в less-файле.

Рассмотрим пример компонента с двумя ячейками, одна из которых выровнена влево, другая - вправо (например название сайта и строка поиска).

<div class="mycomponent"><div class="wrap">
	<div class="r1">... название сайта ...</div>
	<div class="r2">... поиск ...</div>
</div></div>

Теперь less-стили:

div.mycomponent {
	> div.wrap {
		padding: 10px;
	}
 	
	div.r1 {
		float: left;
		width: 60%;
	}
 
	div.r2 {
		float: right;
		width: 30%;
	}
}

В css это будет выглядеть так:

div.mycomponent > div.wrap { 
	padding: 10px; 
}
 
div.mycomponent div.r1 { 
	float: left; 
	width: 60%;
}
 
div.mycomponent div.r2 { 
	float: right; 
	width: 30%;
}

Давайте разберём этот пример внимательно.

В правиле «div.mycomponent > div.wrap» используется символ >, который указывает, что стиль будет применён к div.wrap, при условии, что он следует непосредственно за div.mycomponent. Если этот символ не указывать, то может получиться так, что в подблоке (div.r1 и div.r2) могут оказаться свои div.wrap и тогда стиль применится и к нему. Здесь это исключено.

С float мы уже разбирались - это делает плавающий блок. У блоков мы указываем ширину. Обратите внимание, что суммарную ширину я сделал не 100%, а 90%. То есть при полном заполнении блоков div.r1 и div.r2 между ними останется некоторое расстояние (в 10%), но при этом они окажутся выровненными по разным краям родительского блока.

Не двигайтесь дальше, пока не разберетесь с этим примером.

В less-коде отлично видна структура html-кода, но при этом у нас нет строгих зависимостей через css-классы, как это происходит в фреймворках. Приведеный пример компонента, кстати, будет почти типовым. Вот полный вариант, который можно использовать в своих шаблонах.

<div class="класс компонента"><div class="wrap">
	<div class="r1"> ... </div>
	<div class="r2"> ... </div>
	<div class="clearfix"></div>
</div></div>

«Класс компонента» пусть совпадает с именем файла по какой-то предопределённой схеме. Например в моём варианте компонент с названием сайта и строкой поиска - это ns-search. Файл - ns-search.php.

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

Теперь давайте рассмотрим вопрос использования миксов (миксинов, mixins).

В LESS существует два варианта - простые и параметизированные. Простые миксы по сути - обычные css-классы, которые могут повторяться многократно. Эдакое copy-paste. Вот пример:

.red {
	color: red;
}
 
.yellow {
	color: yellow;
}
 
div.header {
	.red;
}
 
div.footer {
	.yellow;
}

Этот код превратится в

.red {
	color: red;
}
 
.yellow {
	color: yellow;
}
 
div.header {
	color: red;
}
 
div.footer {
	color: yellow;
}

Но обратите внимание, что в результирующий css-код попадут и .red и .yellow. В некоторых случаях это действительно необходимо, но часто будут ситуации, когда это лишнее. Для этого используются параметизированные миксы.

Сравните less-код:

.red() {
	color: red;
}
 
.yellow() {
	color: yellow;
}
 
div.header {
	.red;
}
 
div.footer {
	.yellow;
}

Результирующий код будет:

div.header {
	color: red;
}
 
div.footer {
	color: yellow;
}

То есть микс со скобками выполняется только если его явно вызвать. Это как php-функция, где она вначале объявляется, а уже после используется.

В нашем примере компонента название сайта должно быть выведено каким-то шрифтом, цветом и т.п. Мы можем сделать несколько заготовок, а после произвольно подключать. Например:

.ns01() {
	color: red;
	.bold;
}
 
.ns02() {
	color: yellow;
	.bold;
	.italic;
}
 
.ns03() {
	color: #555;
	.bold;
	.text_shadow(1px, 1px, 3px, #111);
}

Дальше используем:

...
	div.r1 {
		float: left;
		width: 60%;
		.ns02;
	}
...

В коде миксов я использовал хелперы из default-шаблона (см. css/less/include/helpers.less).

Примеры немного натянутые, поскольку слишком простые, но главное уловить суть. В более сложном варианте, особенно если используются браузерные префиксы данный подход будет более эффективен (см. например микс .box_shadow).

Вернёмся к Twitter Bootstrap, как достаточно популярному фреймворку. Если вы посмотрите его less-код (да, он написан на LESS!), то увидите, что в нём практически все миксы простые, а не параметизированные. В итоге в конечный css-код содержит гиганское количество ненужного хлама. Если бы разработчики фреймворка предложили верстать сайты через LESS (как это они сами делают), то вебмастеру было бы удобней указывать стили через предопределённые миксы, не завязываясь на css-классы.

Например в Bootstrap есть простой микс .btn. Чтобы его использовать вебмастер должен в html-коде указывать:

<button class="btn">Кнопка</button>

Если бы микс был параметизированным, то верстка никак не затрагивала бы html-код, поскольку вся переместилась в less-код.

<button>Кнопка</button>
 
div.компонент-или-блок {
	button {
		.btn;
	}
}

Чтобы изменить вид кнопки уже не нужно лезть в html-код - просто правим стили в одном файле.

Почему я на этом останавливаюсь так подробно? К сожалению css-фреймворки рассчитаны строго на ленивых вебмастеров, которые не хотят научиться нормальной и качественной вёрстке. В таких фреймворках много откровенно «левого» кода. Например зачем в .btn правило «margin-bottom: 0;»? Видимо где-то возник «косяк» и разработчики добавили это правило, поскольку оно нарушало их «дизайн». В вашем же шаблоне это правило может быть совершенно не нужным, или даже ошибочным. А чужие «косяки» в свой шаблон переносить как минимум глупо.

Параметизированные миксы могут принимать параметры. В этом случае вёрстка станет ещё удобней. Классический пример - микс .border_radius(). Он определён так:

.border_radius(
	@radius_top_left, 
	@radius_top_right, 
	@radius_bottom_right, 
	@radius_bottom_left)
{
	-webkit-border-radius: @arguments;
	-moz-border-radius: @arguments;
	border-radius: @arguments;
}

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

.border_radius(5px, 5px, 10px, 10px);

Микс сгенерирует кроссбраузерный код.

По аналогии с .btn, можно было бы придумать микс, только принимающий какие-то параметры, вроде основного цвета, цвета текста, размеров и т.п. Тогда при вёрстке указываем нужные значения и получаем практически произвольные кнопки. Рассмотрим для затравки такой пример.

Исходный html-код:

<button class="bt1">Button 1</button> 
<button class="bt2">Button 2</button> 
<button class="bt3">Button 3</button>

Классы я указал разные, чтобы как-то идентифицировать кнопки. Они произвольны.

Стили зададим через микс, который принимает параметры: базовый цвет фона, цвет текста и высота кнопки.

.btn(@bg_color, @text_color, @height: 30px) 
{
	... тут будут стили ..
}

Соответственно микс вызываем для каждой кнопки:

button.bt1 {
	.btn(red, white, 30px);
}
 
button.bt2 {
	.btn(green, #C2F3C2, 40px);
}
 
button.bt3 {
	.btn(#0082CC, white, 50px);
}

То есть это один микс, только с разными параметрами.

Готовые кнопки

Теперь сам микс.

.btn(@bg_color, @text_color, @height: 30px) 
{
	// высота кнопки
	height: @height;
	
	// цвет текста
	color: @text_color;
	
	// градиент
	.background_gradient (@bg_color, darken(@bg_color, 10%));
	
	// тень для текста
	.text_shadow(1px, -1px, 1px, darken(@text_color, 60%));
	
	// границы
	border: 1px solid @bg_color;
	border-top: 1px solid lighten(@bg_color, 10%);
	border-bottom: 1px solid darken(@bg_color, 20%);
	
	// скругление углов
	.border_radius(5px, 5px, 5px, 5px);
	
	// внутренний отступ
	padding: 0 (@height / 2);
	
	// внешняя тень кнопки
	.box_shadow(0, 0, 2px, #777);
	
	// курсор
	cursor: pointer;
	
	// поведение при наведении
	&:hover {
		// меняем только градиент
		.background_gradient (darken(@bg_color, 10%), darken(@bg_color, 10%));
	}
}

Обратите внимание, что параметр @height задан с дефолтным значением. Это значит, что микс можно вызывать без указания высоты кнопки, и она автоматом будет равна 30px.

В миксе я использую разные хелперы из дефолтного шаблона. Если вы используете свои, то переписать будет несложно.

Кратко о некоторых моментах.

LESS-функция darken() делает цвет темнее на указанное значение. Функция lighten() - противоположная - делает цвет светлее. Внутренний отступ padding я сделал вычисляемым от высоты кнопки: слева и справа = высота делённая на 2.

Запись &:hover преобразуется в .btn:hover. То есть & преобразуется в имя «родительского класса».

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

С его помощью также можно изменить стиль каких-то элементов MaxSite CMS, например для кнопки отправки комментария можно указать:

button.comments_submit {
	.btn(#58B158, white);
}

В общем экспериментировать можно сколько угодно.

««« Урок 17 | Урок 15 »»»

Комментариев: 3 RSS

1Аноним28-10-2012 08:28

Автор, у вас неординарный подход к верстке. Смысл указывать классу элемент блока div, когда итак понятно, что это блочный элемент + зачем выбирать первый уровень вложенности, когда можно обойтись без знака ">"? Все это не является правилом хорошего тона, и обзор кода Вашего, извините, равносилен миксоскопии.

2Аноним28-10-2012 08:42

Я рад, что обзор моего кода у вас вызывает сексульное возбуждение. :red: Свои статьи я, конечно делаю не ради этого, ну да ладно, хоть какая-то польза для вас. :lol:

3Ярик15-06-2019 04:33

Смысл указывать классу элемент блока div, когда итак понятно, что это блочный элемент + зачем выбирать первый уровень вложенности, когда можно обойтись без знака ">"

неужели непонятно, что это всего лишь пример...

Оставьте свой комментарий!

Комментарий будет опубликован после проверки

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)