It's easy to write CSS code, but it is hard to scale and support it"

(Ben Frain)

What the problems might be?

1. Количество CSS на проекте всегда увеличивается — становится сложнее поддерживать.

 

2. «Плохие техники» CSS: повторения, плохая группировка, малопонятные связи между элементами.

 

3. Обычный CSS сложно понять без контекста (того HTML, к которому он применяется).

 

4. CSS поощряет переопределения свойств, что сильно осложняет поддержку кода.

 

5. Часть CSS-свойств наследуются.

 

6. Свойства одного элемента могут быть описаны в удаленных друг от друга местах кода.

Web is a semantic sphere.

Методология 

учение о  методах, способах и стратегиях исследования предмета.

Проще

подход или общепринятый набор правил

 

Или

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

Золотые правила

  1. Весь код проекта должен выглядеть так, словно он написан одним человеком, вне зависимости от количества разработчиков.
  2. Делать нужно настолько просто, насколько возможно. Но не проще.
  3. Любой инструмент при бездумном использовании может выстрелить в ногу.

Методологии CSS

1. OOCSS

Объектно ориентированный CSS. Николь Салливан. 2009.

 

2. SMACSS

Scalable and Modular Architecture for CSS. Джонатан Снук. 2011. 

3. БЭМ 

Блок, Элемент, Модификатор. Виталий Харисов. 2009 (АНБ — 2007). Модификация Николаса Галлахера.

OOCSS

ФЕВРАЛЬ 2009

Объектно ориентированный CSS.

Первая попытка систематизировать написание CSS.

Цели: возможность повторного использования, минимум трудозатрат при изменении, меньший объём кода. Значимая веха, но пройденная.

В этот подход заложены две основные идеи:

  • Разделение структуры и оформления
  • Разделение контейнера и контента (содержимого)

1. Выделение общих визуальных особенностей

#button {
width: 200px;
padding: 10px;
border: solid 1px #ccc;
background: linear-gradient(#ccc,#222);
box-shadow: rgba(0,0,0,.5) 2px 2px 5px;
}
#box {
width: 400px;
overflow: hidden;
border: solid 1px #ccc;
background: linear-gradient(#ccc,#222);
box-shadow: rgba(0,0,0,.5) 2px 2px 5px;
}
#button {
width: 200px;
padding: 10px;
}
#box {
width: 400px;
overflow: hidden;
}
/* А вот это уже объект: */
.style-skin {
border: solid 1px #ccc;
background: linear-gradient(#ccc,#222);
box-shadow: rgba(0,0,0,.5) 2px 2px 5px;
}

2. Разделение стилей обёрток и стилей содержимого

/* Такого не должно быть по OOCSS: */
.header .social-widget {
width: 250px;
}

Если использовать .social-widget вне указанного родителя, он станет другой ширины (придётся дописывать стили).

Предостережения OOCSS

1. Избегайте использования id для стилизации.

2. Избегайте использования селекторов потомков.

3. Избегайте !important

4. Не следует добавлять к селекторам по типу ( h2 {...} ) селекторы классов

Преимущества OOCSS

1. Получаем объект — класс для повторного использования — уменьшается дублирование кода (малый размер CSS- файла).

 

2. Отредактировав объект, получится изменить стили всех элементов, к которым он применён.

Недостатки OOCSS

1. Отредактировав объект, получится изменить стили всех элементов, к которым он применён. С более прицельным изменением будут проблемы.

2. Необходимость сопроводительной документации (иначе код становится малопонятным для других разработчиков).

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

4. HTML раздувается из-за большого количества классов у каждого элемента (6-10 штук — легко).

5. Имена классов отдельных элементов страницы не уникальны (возможны наложения стилей).

SMACSS

ОКТЯБРЬ 2011

Scalable and Modular Architecture for CSS.

Документация:

Основная цель подхода — уменьшение количества кода и на упрощение поддержки кода.
 

Предлагает разделять все CSS-классы на несколько типов: основа (базис), структура (каркас), модуль (группа элементов), состояние, тема.

Джонатан предложил разделить стили на 5 частей (в порядке включения их в документ)

Основа

Структура

Модуль

Состояние

Тема

Основа,структура, модуль,состояние,тема

Основа (Base) — это CSS-сброс и стилизация тегов

/* Тут подключим CSS-reset */
body, form {
font: 16px/18px Arial, sans-serif;
}
a {
color: #039;
}
a:hover {
color: #03F;
}

Основа,структура, модуль,состояние,тема

Структура (Layout) — классы для указания размеров, позиционирования, обтеканий, блочности (и модульные сетки).

#header, #article, #footer {
width: 960px;
margin: auto;
}
#sidebar {
float: right;
}
.l-right-block {
float: right;
}

К названию классов добавляется префикс l- .

Основа,структура, модуль,состояние,тема

Модуль — это более дискретная часть страницы (карусель, диалог, виджет)

.module > h2 {
padding: 5px;
}
.module span {
padding: 5px;
}

Префиксы к названию классов не добавляются. Нужна независимость модуля от контекста.

Подробнее — в первоисточнике.

Основа,структура, модуль,состояние,тема

Состояние (State) — описание любого состояния, отличающегося от умолчания.

.tab { /* Это МОДУЛЬ */
background-color: purple;
color: white;
}

.is-tab-active { /* Это СОСТОЯНИЕ */
background-color: white;
color: black;
}

К названию классов добавляется префикс is-

Допустимо оправданное использование !important.

Основа,структура, модуль,состояние,тема

Тема — набор правил, определяющих внешнее оформление любых элементов (цвета текста и фона, оформительские изображения). 

/* module-name.css */
.module {
border: 1px solid;
}

Используются редко — только когда проект имеет несколько тем оформления.

/* module-theme.css */
.module {
border-color: blue;
}

Достоинства SMACSS

1. Контроль распределён по 4-5-и плоскостям (основа, структура, модуль, состояние,тема). Модифицируя один уровень, не влияем на другой.

Недостатки SMACSS

1. Нет, хорошая техника.

Оба метода не строгие.

Не дают АНБ.

БЭМ

Блок. Элемент.Модификатор.

АВГУСТ 2007

Документация:

БЭМ

Блоки должны быть абсолютно независимы.

Преимущества

Простота освоения: 2 главных правила:

1. «Нет селектора вне класса» и «избегаем вложенных селекторов»; 2 правила в написании (об этом ниже).

2. Самодокументируемость (по имени CSS-класса ясно что это такое).

3. Независимость блоков. А значит:

• Предсказуемость работы кода, нет пересечений имён.

• Реиспользуемость блоков (произвольное количество раз в разных местах, произвольная вложенность блоков друг в друга). Быстро создаём новые компоненты из существующих.

• Поддержка (модификация, расширение) — это просто и безопасно.

• Возможность собирать собственные библиотеки компонентов.

Проблемы, решаемые в БЭМ

Проблема 1. Зависимость компонента от его родителя

Непрозрачная зависимость одного блока от другого — непредсказуемость поведения.

Везде:

.selector {color: red}

Но в каком-то месте:

.parent .selector {color: green}

И если потом потребуется поменять:

.selector {color: blue}

Придётся потрать некоторое время на понимание того, почему цвет изменился не везде.

А теперь представьте, что селектор состоит из 4-х частей...

В БЭМ такого каскада нет вовсе. Или есть, но, максимум, двусоставной.

Проблемы, решаемые в БЭМ

Проблема 2. Сложные и специфические селекторы.

Чем сложнее и/или специфичнее селектор,тем больше он привязан к HTML.

Есть выпадающее меню:

#nav ul li ul li {...}

А если потребуется выпадающее меню там, где нет родителя #nav ?

.parent .selector {color: green}

В БЭМ каскад избегается (хотя и допустим).

Используемые в БЭМ селекторы — только классы.

Проблемы, решаемые в БЭМ

Проблема 3. Слишком общие имена классов.

Общие имена классов создают вероятность повторов и неочевидных наследований стилей.

<div class="block">
<h3 class="title">Заголовок</h3>
<div class="contents">
Контент
</div>
</div>
<style>
.block {...}
.block .title {...}
.block .contents {...}
</style>

Разве можно быть уверенным, что где-то в другом месте не появятся:

.title {...}
.contents {...}

Наложение стилей → БОЛЬ

В БЭМ каждое имя селектора уникально.

Проблемы, решаемые в БЭМ

Проблема 4. Непонятность CSS без контекста (HTML).

Даже если сейчас Вы работаете над проектов в одиночку, это не значит, что потом не появятся другие разработчики. И, что куда важнее, Вы можете вернуться к проекту через n*месяцев и уже ничего о нем не помнить.

SbcPstW { /* что это??? */
...
}
/* Это обёртка подвала поста в блоге */
/* По БЭМ: */
.post {...}
...
.post__footer-wrap {...}
.post__footer-date {...}
.post__footer-tags {...}

В БЭМ каждое имя селектора указывает на его применение в HTML.

Помнить всегда: Методология должна служить Вам, а не Вы методологии.

Как делать БЭМ

Как делать БЭМ

(модификация Николаса Галлахера)

Блок — независимый элемент страницы с собственным смыслом.

Элемент — составная часть блока, имеющая смысл только внутри блока.

Модификатор — модификация внешнего вида или поведения блока (или элемента).


.page-header /* блок */

.page-header--tali /* модификатор блока */

.page-header__slogan /* элемент */

.page-header__slogan--big /* модификатор элемента */

Главные принципы

1. Селектор — только класс.

2. Избегаем каскада (но, иногда, можно).

3. Элементы отделяем __ в имени класса.

4. Модификаторы отделяем -- в имени класса. 

1. Минимум глобальных стилей (сброс/нормализатор + типографика).

2. Минимум тегов, не покрытых классами.

3. Осторожно используем дочерний селектор ( > ), последовательность ( + ), псевдоклассы ( :nth-child ).

4. Никогда не стилизуем по id

5. Избегаем тегов в селекторах.

6. Избегаем классов-не-блоков ( .red , .float-left ...)

Дополнительно (нюансы и следствия):

Блок

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

  • Имя класса должно отвечать на вопрос «Зачем нужен этот блок?» (а не описывать его внешний вид).
  • Сложные блоки собираем из простых. Только если нужный блок нельзя собрать из уже готовых (или получить модификацией готовых), создаём новый блок.
  • Блок независим от окружения (может быть размещён в любой части страницы и не сломается при этом).
  • У разных блоков не должно быть общих классов (и в CSS — не группируем общие правила, а копируем их). Примеры: «шапка» сайта, кнопка, главная навигация, пагинация, запись в блоге, блок товара в списке товаров

Блок - вложенная структура

Блоки могут быть вложены в любые другие блоки.

Например, блок head может включать логотип (logo), форму поиска (search) и блок авторизации (auth).

Блок - свободное перемещение

Блоки могут быть вложены в любые другие блоки.

Например, блок head может включать логотип (logo), форму поиска (search) и блок авторизации (auth).

Блок - повторное использование

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

Элемент

Составная часть блока, которая не может использоваться в отрыве от него.

Например, пункт меню вне контекста блока меню не используется, значит является элементом.

  • Это часть блока, которая вне этого блока не имеет смысла и не может быть использована.
  • CSS-класс элемента формируется так: класс-блока__класс-элемента
  • Могут отсутствовать (часть элементов не являются обязательными, в блоке может не быть элементов).
  • Примеры: пункты основной навигации, заголовочная часть записи в блоге, ссылка пагинации.

Как понять где элемент,а где вложенный блок?

ЭТО может потребоваться вне родителя?

Да, может — это блок.

Нет,тольно внутри родителя — это элемент.

Частая ошибка

В имени элемента пишут два сегмента __ . Не надо так.

 

В БЭМ плоская структура Блок → Элемент, максимально независимая от разметки.

Модификатор

БЭМ-сущность, определяющая внешний вид, состояние и поведение блока или элемента.

Использование модификаторов опционально.

По своей сути модификаторы похожи на атрибуты в HTML. Один и тот же блок выглядит по-разному благодаря применению модификатора.

Например, внешний вид блока меню (menu) может меняться в зависимости от примененного модификатора.

Модификатор

Дополнительный класс, изменяющий внешний вид блока (или элемента, если добавлен к элементу).

CSS-класс модификатора формируется так: класс-блока--название-модификатора Даёт возможность блокам выглядеть по-разному на разных страницах или в разных частях страницы.

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

 

 

У одного блока (элемента) может быть несколько модификаторов. Можно модифицировать элементы от модификатора блока (это делает код неочевидным!).

Избегайте модифицировать вложенные блоки от модификатора блока-родителя.

<div class="header--big"> — неправильно.
<div class="header header--big"> — правильно.

Как не делать в БЭМ

 

  • Не используйте имена классов наподобие header__search__button , вне зависимости от реальной иерархии элементов, в имени класса должен быть только один сегмент __ .

  • Не используйте префикс .b- для классов блоков.

  • Не используйте элементы блока без самого блока: Класс .gallery__item должен встречаться только внутри блока .gallery

  • Не используйте классы-модификаторы без тех классов, которые они модифицируют: Класс .gallery--large не должен встречаться без класса .gallery

  • Избегайте избыточного сокращения — имя CSS-класса должно говорить о том, какому элементу дан этот класс. .g__it — плохо, .gallery__item — хорошо. Используйте лаконичные, но понятные названия классов, подумайте о простом и коротком словаре сокращений.

Критика БЭМ

1. Отсутствие классов, обобщающих разные блоки (одинаковые правила дублируются). Как следствие независимости блоков. Нужны ли такие объединения?

 

2. Нужно писать классы у всех тегов. У всех? Недостаток ли это? Большие и маленькие проекты.

 

3. Длинные названия классов. Которые сами по себе документируют вёрстку. С препроцессорами — идеально.

 

4. Использование в названии классов сегментов __ и -- , длинные имена классов. Некоторым это кажется уродливым.

Каким инструментом пользоваться — решать вам

Верстка по БЭМ

Questions?

Немного об анатомии шрифта

Шрифт состоит из глифов - векторных форм каждой буквы или символа. Поэтому размер файла шрифта зависит от двух переменных: количества глифов в шрифте и сложности их векторных контуров.

Например, Open Sans, один из самых популярных веб-шрифтов, содержит 897 глифов, включая латинские, греческие и кириллические символы.

Форматы шрифтов

Сегодня в Интернете используются четыре формата контейнеров шрифтов: EOT, TTF, WOFF и WOFF2

К сожалению, несмотря на возможность выбора, не существует единого формата, который работает во всех браузерах.

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

  • Используйте WOFF 2.0 в тех браузерах, которые его поддерживают.
  • Добавьте WOFF для большинства браузеров.
  • Применяйте TTF в устаревших браузерах Android (для версий до 4.4).
  • Добавьте EOT для поддержки устаревших версий IE (до IE9). 

Создание семейства шрифтов с помощью @font-face

В каждом объявлении @font-face указано название семейства шрифтов, которые действует как логическая группа из нескольких объявлений, характеристик шрифта, например стиля, толщины и интервала, и дескриптора src, который определяет список расположений шрифта в порядке важности.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'), 
       url('/fonts/awesome.woff') format('woff'),
       url('/fonts/awesome.ttf') format('ttf'),
       url('/fonts/awesome.eot') format('eot');
}

@font-face {
  font-family: 'Awesome Font';
  font-style: italic;
  font-weight: 400;
  src: local('Awesome Font Italic'),
       url('/fonts/awesome-i.woff2') format('woff2'), 
       url('/fonts/awesome-i.woff') format('woff'),
       url('/fonts/awesome-i.ttf') format('ttf'),
       url('/fonts/awesome-i.eot') format('eot');
}

/*Использование:*/

.class-name {
 font-family: 'Awesome Font';
 font-size: 14px;
}

Если нужно взять шрифты с Google Fonts, но подключать их со своего хоста

— превосходный сервис, который и шрифты даст скачать, и покажет код как их оптимальнее всего подключать.

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

  1. Браузер читает разметку страницы и определяет, какие варианты шрифтов нужны для отрисовки текста.

  2. Браузер проверяет, не установлены ли нужные шрифты на устройстве.

  3. Если файла нет на устройстве, браузер читает список внешних расположений:

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

  5. Если указание на формат отсутствует, браузер скачивает ресурс.

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

Note: Порядок, в котором указаны варианты шрифтов, имеет значение, потому что браузер выбирает первый поддерживаемый шрифт. Таким образом, если вы хотите, чтобы современные браузеры использовали WOFF2, укажите его до WOFF, и т. д.

Must read:

http://nicothin.pro/page/webfonts-min  — оптимизация шрифтов 

BEM

By Elizabeth Anatskaya