Интернет магазин шабонов
Форма входа

Статьи сайта

CSS наших дней

Лучшие практики стилизации элементов сейчас можно выразить следующими тезисами:
  • Старайтесь стилизовать элементы так, чтобы их визуализация не ломалась при перемещении их в другое место. Из этого принципа следует, что стоит минимизировать использование составных селекторов (например, вида header p a).
  • Используйте пространства имён, чтобы минимизировать вероятность конфликтов правил относящихся к разным элементам. Это приводит к длинным именам, но избавляет от кучи проблем в будущем.


Итак, какие возможности для привязки стилей к элементам у нас есть сейчас? У любого элемента есть следующие характеристики:
  • Имя элемента
  • Идентификатор
  • Набор классов
  • Набор атрибутов
  • Набор свойств


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

Имя элемента


Код
<my-task-list>
  <my-task-card>
  <my-task-card-title>Write HTML</my-task-card-title>
  <my-task-card-estimate>1 hour</my-task-card-estimate>
  </my-task-card>
  <my-task-card>
  <my-task-card-title>Write CSS</my-task-card-title>
  <my-task-card-estimate>2 hours</my-task-card-estimate>
  </my-task-card>
  <my-task-card>
  <my-task-card-title>Write JS</my-task-card-title>
  <my-task-card-estimate>10 hours</my-task-card-estimate>
  </my-task-card>
</my-task-list>

Код
my-task-list {
  display: flex;
  flex-direction: column;
}

my-task-card {
  display: inline-flex;
  margin: .5rem;
  padding: .5rem;
  border: 2px solid gray;
  border-radius: .5rem;
}

my-task-card-title {
  margin: .5rem;
  font-weight: bolder;
  flex: 1 1 auto;
}

my-task-card-estimate {
  margin: .5rem;
  font-weight: lighter;
}

http://liveweave.com/XjrwY5

Как видим, код CSS получился довольно простым, но длинные имена тегов весьма перегружают HTML. Кроме того, имена элементов отлично подходят для указания имени блока, но совершенно не позволяют добавлять элементу модификаторов (например, чтобы как-то выделить завершённые или важные задачи). Но самая главная проблема кастомизированных имён элементов в том, что иногда имя элемента должно быть строго определённым. Например, элемент video для вставки видео на страницу, или элемент a для создания гиперссылки.

Данный способ стилизации почти не используется ввиду упомянутых ограничений. Лишь новички и энтузиасты от web components практикуют эту технику.

Идентификаторы


Код
<div id="my-task-list">
  <a id="my-task-card" href="#task=1">
  <div id="my-task-card-title">Write HTML</div>
  <div id="my-task-card-estimate">1 hour</div>
  </a>
  <a id="my-task-card" href="#task=2">
  <div id="my-task-card-title">Write CSS</div>
  <div id="my-task-card-estimate">2 hours</div>
  </a>
  <a id="my-task-card" href="#task=3">
  <div id="my-task-card-title">Write JS</div>
  <div id="my-task-card-estimate">10 hours</div>
  </a>
</div>

Код
#my-task-list {
  display: flex;
  flex-direction: column;
}

#my-task-card {
  display: inline-flex;
  margin: .5rem;
  padding: .5rem;
  border: 2px solid gray;
  border-radius: .5rem;
  text-decoration: inherit;
  color: inherit;
}

#my-task-card-title {
  margin: .5rem;
  font-weight: bolder;
  flex: 1 1 auto;
}

#my-task-card-estimate {
  margin: .5rem;
  font-weight: lighter;
}

http://liveweave.com/ccrFOf

Код CSS почти не изменился — мы лишь добавили решётки перед именами. Код HTML стал гораздо легче за счёт отсутствия повторения длинных имён. Имена тегов теперь могут быть произвольными, так что мы с лёгкостью превратили карточки задач в гиперссылки, ведущие на страницы с подробностями по этим задачам. Тем не менее, у нас по прежнему нет поддержки модификаторов. И кроме того, идеологически не верно иметь на одной странице несколько элементов с одинаковым идентификатором, хотя это ничего и не ломает.

Раньше идентификаторы пользовались популярностью для стилизации, но сейчас их полностью вытеснили классы.

Классы


Код
<div class="my-task-list">
  <a class="my-task-card my-task-card_important my-task-card_completed" href="#task=1">
  <div class="my-task-card-title">Write HTML</div>
  <div class="my-task-card-estimate">1 hour</div>
  </a>
  <a class="my-task-card my-task-card_completed" href="#task=1">
  <div class="my-task-card-title">Write CSS</div>
  <div class="my-task-card-estimate">2 hours</div>
  </a>
  <a class="my-task-card" href="#task=1">
  <div class="my-task-card-title">Write JS</div>
  <div class="my-task-card-estimate">10 hours</div>
  </a>
</div>

Код
.my-task-list {
  display: flex;
  flex-direction: column;
}

.my-task-card {
  display: inline-flex;
  margin: .5rem;
  padding: .5rem;
  border: 2px solid gray;
  border-radius: .5rem;
  text-decoration: inherit;
  color: inherit;
}

.my-task-card_important {
  border-color: red;
}

.my-task-card_completed {
  opacity: .5;
}

.my-task-card-title {
  margin: .5rem;
  font-weight: bolder;
  flex: 1 1 auto;
}

.my-task-card-estimate {
  margin: .5rem;
  font-weight: lighter;
}

http://liveweave.com/qZDyzV

Изменения как в CSS, так и в HTML — незначительные, но классов на один элемент можно навешивать куда больше одного, чем мы и воспользовались, дополнительно раскрасив важные и завершённые задачи. Правда, за счёт пространств имён, такие модификаторы довольно сильно раздувают HTML.

99% кода сейчас в вебе написано на классах, тем не менее есть решение лучше..

Атрибуты


Код
<div my-task-list>
  <a my-task-card="important completed" href="#task=1">
  <div my-task-card-title>Write HTML</div>
  <div my-task-card-estimate>1 hour</div>
  </a>
  <a my-task-card="completed" href="#task=2">
  <div my-task-card-title>Write CSS</div>
  <div my-task-card-estimate>2 hours</div>
  </a>
  <a my-task-card href="#task=3">
  <div my-task-card-title>Write JS</div>
  <div my-task-card-estimate>10 hours</div>
  </a>
</div>

Код
[my-task-list] {
  display: flex;
  flex-direction: column;
}

[my-task-card] {
  display: inline-flex;
  margin: .5rem;
  padding: .5rem;
  border: 2px solid gray;
  border-radius: .5rem;
  text-decoration: none;
  color: inherit;
}

[my-task-card~=important] {
  border-color: red;
}

[my-task-card~=completed] {
  opacity: .5;
}

[my-task-card-title] {
  margin: .5rem;
  font-weight: bolder;
  flex: 1 1 auto;
}

[my-task-card-estimate] {
  margin: .5rem;
  font-weight: lighter;
}

http://liveweave.com/8ddncZ

Код CSS усложнился незначительно, зато HTML, не смотря на поддержку модификаторов, стал куда более простым. Тут мы используем специальный селектор, который буквально означает "применить такие-то стили к элементу, у которого в таком-то атрибуте, среди разделённых пробелом слов, есть такое-то".

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

Свойства


Браузеры представляют довольно ограниченный набор свойств, которые мы можем использовать в CSS через псевдоклассы. Например, мы можем добавить подсветку карточки при наведении курсора:
Код
[my-task-card]:hover {
  border-color: steelblue;
  box-shadow: 0 0 .5rem rgba(0,0,255,.25);
  opacity: 1;
}

К сожалению набор псевдоклассов никак от нас не зависит, поэтому, если, например, нам потребуется выделить карточку текущей открытой задачи, то нам уже придётся использовать модификатор:
Код
[my-task-card]:not([my-task-card~=current]):hover {
  border-color: steelblue;
  box-shadow: 0 0 .5rem rgba(0,0,255,.25);
  opacity: 1;
}

[my-task-card~=current] {
  background: #eee;
  border: none;
}

Получилась довольно хитрая логика и это ещё цветочки — в некоторых случаях тут получаются зубодробительные выражения. Кроме того, во время разработки мы не можем вывести карточку во всех возможных состояниях — приходится открывать страницу и возюкать мышью, проверяя, что всё работает как следует. Поэтому, если есть такая возможность, то лучше вообще отказаться от использования псевдоклассов в пользу модификаторов, контролируемых из JS:
Код
[my-task-card~=hover] {
  border-color: steelblue;
  box-shadow: 0 0 .5rem rgba(0,0,255,.25);
  opacity: 1;
}

[my-task-card~=current] {
  background: #eee;
  border: none;
}

Код
<div my-task-list>
  <a my-task-card="important completed" href="#task=1">
  <div my-task-card-title>Write HTML</div>
  <div my-task-card-estimate>1 hour</div>
  </a>
  <a my-task-card="completed" href="#task=2">
  <div my-task-card-title>Write CSS</div>
  <div my-task-card-estimate>2 hours</div>
  </a>
  <a my-task-card="current" href="#task=3">
  <div my-task-card-title>Write JS</div>
  <div my-task-card-estimate>10 hours</div>
  </a>
</div>

<div my-task-list>
  <a my-task-card="hover important completed" href="#task=1">
  <div my-task-card-title>Write HTML</div>
  <div my-task-card-estimate>1 hour</div>
  </a>
  <a my-task-card="hover completed" href="#task=2">
  <div my-task-card-title>Write CSS</div>
  <div my-task-card-estimate>2 hours</div>
  </a>
</div>

http://liveweave.com/1GJrUM

Тут мы вывели карточки задач во всех возможных состояниях, так что одним взглядом можем легко окинуть их все. Как написать JS, который будет менять модификаторы по необходимой логике — вопрос отдельный и во многом зависит от предпочитаемого вами фреймворка.

На этом наш небольшой обзор техник стилизации подходит к концу. Расскажите в комментариях, каких принципов вы придерживаетесь при вёрстке и как бы заверстали описанный в статье пример.

Источник: https://habrahabr.ru/post/307824/
Добавлять комментарии могут только зарегистрированные пользователи.