Пользователь
0,1
рейтинг
21 октября 2013 в 19:44

Разработка → Несколько советов less-разработчику tutorial

Зачастую, создавая less-файлы (что, впрочем, касается и других препроцессоров css), мы гонимся за красотой и элегантностью less-кода, когда как частенько забываем про скомпилированный css-код. Иногда это влечет за собой критичные последствия, когда объем конечного css возрастает в раз, а код становится совершенно нечитаемым.

Disclaimer
1) Эта статья подойдет как для SASS/SCSS-разработчиков, так и для CSS-писателей.
2) Приведенные примеры кода не идентичны, но в большинстве случаев взаимозаменяемы и написаны для иллюстрации советов.

1) Не делайте слишком длинных вложений


Когда мы пишем обычный css-код, обычно не получается такой проблемы. Врядли мы напишем перед css-свойствами цепочку из 10 элементов. А вот с древовидной структурой less-кода, такое вполне вероятно. Упрощайте свои «лесенки» кода. Выделяйте отдельные блоки и выносите их. Особенно это касается универсальных классов и id. Длинные цепочки селекторов утяжеляют файл стилей, затрудняют его чтение, порой объем css-файл может увеличиваться из-за излишней вложенности в два раза.
Плохо Хорошо
#root {
	max-width: 1200px;
	margin: 0 auto;
	.wrapper {
		padding: 1rem;
		.cart {
			background: #eee;
			h1 {
				font-size: 2rem;
				margin: 1rem 0 2rem;
				&#green-header {
					color: green;
				}
			}
			.good {
				border: 0.1rem solid #ccc;
			}
			input {
				border: 1px solid #ccc;
				&.error {
					background: #99ffff;
				}
			}
		}
	}
}
			

#root {
	max-width: 1200px;
	margin: 0 auto;
	.wrapper {
		padding: 1rem;
	}
}
#green-header {
	color: green;
}
input.error {
	background: #99ffff;
}
.cart {
	background: #eee;
	h1 {
		font-size: 2rem;
		margin: 1rem 0 2rem;
	}
	.good {
		border: 0.1rem solid #ccc;
	}
}
			


Посмотреть скомпилированный css-код
Плохо Хорошо
				#root {
				  max-width: 1200px;
				  margin: 0 auto;
				}
				#root .wrapper {
				  padding: 1rem;
				}
				#root .wrapper .cart {
				  background: #eee;
				}
				#root .wrapper .cart h1 {
				  font-size: 2rem;
				  margin: 1rem 0 2rem;
				}
				#root .wrapper .cart h1#green-header {
				  color: green;
				}
				#root .wrapper .cart .good {
				  border: 0.1rem solid #ccc;
				}
				#root .wrapper .cart input {
				  border: 1px solid #ccc;
				}
				#root .wrapper .cart input.error {
				  background: #99ffff;
				}
				

				#root {
				  max-width: 1200px;
				  margin: 0 auto;
				}
				#root .wrapper {
				  padding: 1rem;
				}
				#green-header {
				  color: green;
				}
				input.error {
				  background: #99ffff;
				}
				.cart {
				  background: #eee;
				}
				.cart h1 {
				  font-size: 2rem;
				  margin: 1rem 0 2rem;
				}
				.cart .good {
				  border: 0.1rem solid #ccc;
				}
				




2) Опасайтесь селекторов через запятую


Если мы поставим в начале вложения селекторов (из примера выше) два или более селекторов через запятую, то все-все правила продублируются столько раз, сколько мы поставили селекторов вначале. Говоря об оптимизации веса получившегося css-файла, можно судить о десятках килобайт. Особенно опасно использовать селекторы через запятую, когда они вложены уже в селекторы, которые так же оформлены через запятую. Один из тяжелых случаев представлен ниже
Плохо Хорошо
form.type {
	&#typeAddress,
	&form#typeReview {
		textarea {
			background: #eee;
		}
		table {
			td {
				&.value {
					padding: 1rem;
				}
				&.title {
					padding: 0.5rem 1rem;
					margin: 0.5rem 0;
				}
				&.value, &.title {
					background: #eee;
					color: #444;
					a {
						text-decoration: none;
						padding: 0 0.4rem;
					}
					b {
						color: #ccc;
					}
					p {
						border-left: 0.25rem solid #ece;
					}
				}
				&.result {
					padding: 1rem 0;
					background: green;
				}
			}
		}
	}
}
			

form.type {
	textarea {
		background: #eee;
	}
	table {
		td {
			background: #eee;
			color: #444;
			padding: 1rem;
			a {
				text-decoration: none;
				padding: 0 0.4rem;
			}
			b {
				color: #ccc;
			}
			p {
				border-left: 0.25rem solid #ece;
			}
			&.title {
				padding: 0.5rem 1rem;
				margin: 0.5rem 0;
			}
			&.result {
				padding: 1rem 0;
				background: green;
			}
		}
	}
}
			


Посмотреть скомпилированный css-код
Плохо Хорошо
form.type#typeAddress textarea,
form.typeform#typeReview textarea {
  background: #eee;
}
form.type#typeAddress table td.value,
form.typeform#typeReview table td.value {
  padding: 1rem;
}
form.type#typeAddress table td.title,
form.typeform#typeReview table td.title {
  padding: 0.5rem 1rem;
  margin: 0.5rem 0;
}
form.type#typeAddress table td.value,
form.typeform#typeReview table td.value,
form.type#typeAddress table td.title,
form.typeform#typeReview table td.title {
  background: #eee;
  color: #444;
}
form.type#typeAddress table td.value a,
form.typeform#typeReview table td.value a,
form.type#typeAddress table td.title a,
form.typeform#typeReview table td.title a {
  text-decoration: none;
  padding: 0 0.4rem;
}
form.type#typeAddress table td.value b,
form.typeform#typeReview table td.value b,
form.type#typeAddress table td.title b,
form.typeform#typeReview table td.title b {
  color: #ccc;
}
form.type#typeAddress table td.value p,
form.typeform#typeReview table td.value p,
form.type#typeAddress table td.title p,
form.typeform#typeReview table td.title p {
  border-left: 0.25rem solid #ece;
}
form.type#typeAddress table td.result,
form.typeform#typeReview table td.result {
  padding: 1rem 0;
  background: green;
}
				

form.type textarea {
  background: #eee;
}
form.type table td {
  background: #eee;
  color: #444;
  padding: 1rem;
}
form.type table td a {
  text-decoration: none;
  padding: 0 0.4rem;
}
form.type table td b {
  color: #ccc;
}
form.type table td p {
  border-left: 0.25rem solid #ece;
}
form.type table td.title {
  padding: 0.5rem 1rem;
  margin: 0.5rem 0;
}
form.type table td.result {
  padding: 1rem 0;
  background: green;
}
				




3) Миксины


Создавайте миксины чаще

Если вы пишете код и возникает ощущение deja vu, смело добавляйте миксин. Это значительно сэкономит время в последующих проектах. Не пытайтесь сразу сделать миксин идеальным, с кучей параметров. Он должен быть простым и понятным. Впоследствии вы будете его расширять и делать более универсальным.

Используйте параметризацию миксинов

Любой миксин, который вы используете, можно запараметризовать. Во-первых, это удобно. Во-вторых, это экономит получившийся результат в css.
Когда мы добавляем миксин, пусть это будет оформление кнопки, а далее простыми css-свойствами меняем ему размеры или цвет, то в скомпилированном css в селекторе будут сначала правила, описанные в миксине, а затем уже те, которые вы описали. Получается ненужное дублирование css-свойств. Избежать этого можно, вставляя значения параметров в миксин: так миксин скомпилируется сразу с нужными параметрами. И не забывайте ставить параметрам значения по умолчанию.
Плохо Хорошо
@color-btn: #ea186e;
@color-txt: #000;
.btn-flat() {
	display: inline-block; 	text-align: center;	text-decoration: none;

	margin: 1rem 0;
	padding: 0.5rem 1rem;
	background: @color-btn;
	color: @color-txt;
	border: 0.1rem solid darken(@color-btn,15%);
}

#root {
	a.btn {
		.btn-flat;
	}
	button {
		.btn-flat;
		background: #ccc;
		color: #303;
		padding: 0.75rem 1.5rem;
		margin: 1.5rem 0;
		border: 0.2rem solid darken(#ccc,15%);
	}
}
			

@color-btn: #ea186e;
@color-txt: #000;
.btn-flat(@bgcolor: @color-btn, @color: @color-txt, @pad: 1rem) {
	display: inline-block; 	text-align: center;	text-decoration: none;
	
	margin: @pad 0;
	padding: @pad/2 @pad;
	background: @bgcolor;
	color: @color;
	border: @pad/10 solid darken(@bgcolor,15%);
}

#root {
	a.btn {
		.btn-flat;
	}
	button {
		.btn-flat(#ccc, #303, 1.5rem);
	}
}
			


Посмотреть скомпилированный css-код
Плохо Хорошо
#root a.btn {
  display: inline-block;  text-align: center;  text-decoration: none;

  margin: 1rem 0;
  padding: 0.5rem 1rem;
  background: #ea186e;
  color: #000000;
  border: 0.1rem solid #a60f4d;
}
#root button {
  display: inline-block;  text-align: center;  text-decoration: none;

  margin: 1rem 0; /* Это свойство "перебито" нижним */
  padding: 0.5rem 1rem; /* Это свойство "перебито" нижним */
  background: #ea186e; /* Это свойство "перебито" нижним */
  color: #000000; /* Это свойство "перебито" нижним */
  border: 0.1rem solid #a60f4d; /* Это свойство "перебито" нижним */

  background: #ccc;
  color: #303;
  padding: 0.75rem 1.5rem;
  margin: 1.5rem 0;
  border: 0.2rem solid #a6a6a6;
}
				

#root a.btn {
  display: inline-block;  text-align: center;  text-decoration: none;

  margin: 1rem 0;
  padding: 0.5rem 1rem;
  background: #ea186e;
  color: #000000;
  border: 0.1rem solid #a60f4d;
}
#root button {
  display: inline-block;  text-align: center;  text-decoration: none;

  margin: 1.5rem 0;
  padding: 0.75rem 1.5rem;
  background: #cccccc;
  color: #330033;
  border: 0.15rem solid #a6a6a6;
}
				




Хороший миксин — небольшой миксин

Собирайте миксины как кубики. Видите повторяющиеся куски кода, используйте миксин. Многие css-свойства имеют вендорные префиксы, поэтому для каждого подобного свойства добавляйте миксин с параметром @arguments. А затем их уже вкладывайте в другие миксины.
Используйте миксины для свойств, имеющих вендорные префиксы — экономьте свое время.
@pad: 0.5rem;
@bpad: @pad/5;
@color-back: #fff;
@color-btn: maroon;
.border(@color: #ccc) {
	border: @bpad solid @color;
}
.gradient(@c1,@c2){
  background: @c1;
  background: -moz-linear-gradient(top,  @c1 0%, @c2 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,@c1), color-stop(100%,@c2));
  background: -webkit-linear-gradient(top,  @c1 0%,@c2 100%);
  background: -o-linear-gradient(top,  @c1 0%,@c2 100%);
  background: -ms-linear-gradient(top,  @c1 0%,@c2 100%);
  background: linear-gradient(to bottom,  @c1 0%,@c2 100%); 
}
.btn(@padding: @pad) {
	padding: @padding/2 @padding;
	display: inline-block;
	text-align: center;
	text-decoration: none;
}
.btn-simple(@color: @color-btn) {
	.btn;
	.border(darken(@color,7%));
	.gradient(lighten(@color,3%), darken(@color,3%));
	color: @color-back;
	color: lighten(@color,40%);
	&:hover {
		.gradient(darken(@color,3%), darken(@color,8%));
		color: lighten(@color,50%);
	}
	&:active {
		.gradient(darken(@color,15%), darken(@color,15%));
		color: lighten(@color,10%);
		.border(darken(@color,25%));
	}
}
			


4) Используйте свой шаблон


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

5) Используйте переменные


Переменные для размеров, для цвета. Это помогает придерживаться сетке и выравниванию элементов.
Я использую для задания размеров блоков и отступов единицы rem, они хороши тем, что не зависят от размера родительского шрифта. Таким образом, горизонтальные отступы становятся одинаковыми, даже если мы меняем размер шрифта. А в дополнение, задав изменение размера шрифта от разрешения экрана для тега html, все размеры пропорционально увеличатся. Такое применяется для планшетов: текст и отступы там должны быть чуть больше по сравнению с «телефонным» масштабом. (работает в современных браузерах, ie9+)



Подытожим


  • Не гонитесь за чистотой less-кода, следите за тем, как он будет компилироваться
  • Не увлекайтесь древовидной вложенностью селекторов
  • Пользуйтесь перечислением селекторов с осторожностью, и только там, где это действительно неободимо
  • Добавляйте переменные везде, где только можно.
  • Используйте rem, если того позволяет поддержка браузеров для проекта. Так вы избавитесь от проблемы с разными отступами у блоков и подгонкой значений (не забывайте про поддержку браузерами)
  • Составляйте миксины как кубики: двигайтесь от простых, заменяющих одно-два свойств, до сложных, включающих в себя другие миксины.
  • Создавайте параметризированные миксины везде, обязательно задавая значения по умолчанию
  • Используйте миксины для кнопок, элементов интерфейса, вендорных свойств


Разумеется, многие вещи можно оптимизировать через специальные сокращатели и минимизаторы css, но мы должны писать качественный код!
Павел Щеголев @Carduelis
карма
0,0
рейтинг 0,1
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (14)

  • +1
    Длинные цепочки селекторов утяжеляют файл стилей, затрудняют его чтение

    Я думал что если использовать sass/less то нет необходимости читать скомпилированный файл.
    А чтобы небыло соблазна что-нибудь там исправить компилирую в упакованом виде.
    • +1
      Например, когда мы смотрим в инспектор хрома, файрбаг или иной другой инструмент, то каша из тегов
      form.type#typeAddress table td.value b,
      form.typeform#typeReview table td.value b,
      form.type#typeAddress table td.title b,
      form.typeform#typeReview table td.title b {
        color: #ccc;
      }
      form.type#typeAddress table td.value p,
      form.typeform#typeReview table td.value p,
      form.type#typeAddress table td.title p,
      form.typeform#typeReview table td.title p {
        border-left: 0.25rem solid #ece;
      }
      


      … очень затруднит дебаг, особенно, если это чужой проект.

      Разумеется, есть специальные расширения, например, для веб-инспектора, позволяющие понимать less
      • +2
        source maps
    • 0
      Здесь даже не в чтении дело, а в производительности рэндеринга страницы. Мы взяли себе за правило — максимум 3 глубины вложенности и только «дети»:
      .container {
         // styles
      
          > .sub { }
          > .foo {
               > .bar {}
          }
      }
      

      • 0
        На самом деле браузеры справляются практически со всеми селекторами одинаково быстро, если конечно на странице не сотни тысяч элементов.

        Минус длинных селекторов — это лишние килобайты кода.
        • +1
          На самом деле вы ошибаетесь. Есть огромная разница между '.foo .bar' и '.foo > .bar'. И первый вариант использовать нельзя — первое производительность, второе чрезмерное размытие контекста. Вот небольшой тест на jsperf. На «вебкитах» разница существенная. И это учитывая, что браузер лишь один элемент сопоставляет с одним селектором. И не сложно прикинуть, как картина будет выглядеть при рендеринге, когда будет просто сотни элементов и сотни селекторов.
          • 0
            Разница конечно есть, но на общем фоне это работает достаточно быстро. Я веду к тому, что мы часто, наблюдая разницу в производительности, зацикливаемся на этом не принимая во внимание общую производительность системы.
            • 0
              Согласен, Style Recalculation на фоне Script Evaluation / Parse HTML занимает довольно мало времени. (Ну по крайней мере, тот css который у нас в приложениях). Но уверяю вас, что если зацикливаться на таких вещах, то и вся система в целом будет производительной, отзывчивой и приятной. Из этого происходит стиль программиста — если он не обращает на такие вещи внимания, то зачастую и на многие другие также не будет обращать внимания. Собственно именно из этого возникают все разговоры, что вэб приложения, особенно под мобильные устроиства, «тормознутые». Мы видим совсем иную картину — оказывается можно писать быстрые и сложные мобильные вэб-приложения.

              Архитектурный недостаток '.foo .bar' пока умолчим.
              • +1
                Смею предположить, сам не раз сталкивался, что на моб. устройствах веб-приложения чаще тормозят от длинных репеинтов, что вызвано неэффективным использованием некоторых CSS свойств. Перфекционизм — отличная черта для разработчика, но иногда мы готовы тратить часы на то, что в действительности, в свете производительности современного железа, уже не так важно ;) В любом случае длинные селекторы зло, по многим причинам.
    • 0
      А как по мне, то чтение затрудняется в самом лесс файле
  • 0
    ++ использовать lesshat.
  • –3
    Учите БЭМ
  • 0
    Я крайне не люблю вложенные правила из-за худшей читаемости. Можно поспорить когда блоки простые, но как правило блок нулевого уровня редко влазит в один экран.
  • +1
    Ого, Less-разработчик! Так и до HTML-архитектора недалеко :)

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