Этот документ устарел в пользу БЭМ. Читайте историю создания БЭМ в клубе на Яру.

Вёрстка независимыми блоками

Презентация в PPT (1.1 Mb), PDF (0.9 Mb)

Вступление


Слайд 1: Приветствие


Добрый день, я Виталий Харисов. Я расскажу вам про вёрстку независимыми блоками.


Что такое блок


Прежде чем перейти к непосредственно независимым блокам, давайте определим, что такое блок вообще.


Рассмотрим типичную web-страницу (Слайд 2: Типичная страница):


Типичная страница (30 Кб)


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


Типичная страница с основными блоками (33 Кб)


Если в шапке выводится имя пользователя и в теле страницы тоже используется имя пользователя, мы получаем (Слайд 4: Типичная страница с именем пользователя) ещё один блок.


Типичная страница с блоком user (72 Кб)


Т.о. блоком будем называть (Слайд 5: определение блока) фрагмент страницы, который описывается своей разметкой и стилями.


Для интенсивно развивающихся проектов (Слайд 6: Необходим механизм) необходим механизм, облегчающий сборку шаблонов, позволяющий переставлять блоки на странице местами, быстро собирать страницы из уже имеющихся, повторно использовать блоки из одного проекта на другом.


Для этого была разработана техника "вёрстка независимыми блоками".


Вкраце, (Слайд 7: краткое опредение) это когда используется минимум глобальных стилей, каждый обособленный элемент страницы описывается своими стилями (стили дублируются, а не объединяются в случае необходимости), которые в идеале не пересекаются со стилями других блоков. Блоки могут вкладываться в другие блоки.


Условия независимости


При этом, каждый независимый блок удовлетворяет следующим условиям (Слайд 8: Условия независимости):


1) для описания элемента используется class, но не id
2) каждый блок имеет префикс
3) в таблице стилей нет классов вне блоков


Рассмотрим каждый пункт отдельно.


Не используем id в CSS, только class


Слайд 9: Используем только class


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


Даже такая, казалось бы, единственная вещь, как логотип или подвал.


Слайд 10: Пример неуникальности блоков


Пример дублирования шапки на Яру (381 Кб)


Слайд 11: Менять id на class дорого


Поскольку id в валидном документе может быть только один, то при необходимости добавления точно такого же элемента на страницу надо переписывать код на классы. Хотя кажется, что это трёхминутное дело, на самом деле это относительно дорогая операция, поскольку изменение кода в уже работающем проекте требует участия нескольких человек (разработчики, тестировщики) и времени на кодировние, тестирование и выкладку. Это уже не говоря о том, времени этого просто нет.


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


Каждый блок с префиксом


Слайд 12: Блок b-user


Для явного выделения блоков, элементу ограничивающему блок задаётся класс с префиксом (b-, h-, l- об этом ниже) и все стили этого блока описываются начиная от этого класса.


Рассмотрим на примере:


Блок b-user (22 Кб)


У нас есть блок "имя пользователя" (user), внешнему элементу которого задаётся класс b-user и все стили описываются начиная с этого класса.


В таблице стилей нет классов вне блоков


Слайд 13: Нет классов вне блоков


Вся страница разбивается на блоки, все стили должны относиться к какому-то блоку, не должно быть классов вне блоков.

Блоки простые и составные

Простые блоки


Теперь поговорим подробнее какие блоки бывают. Можно выделить два вида блоков: простые и составные.


Слайд 14: Простые блоки


Простой блок не может содержать других блоков, он неделим.


Простые блоки (47 Кб)


В простых блоках можно опираться на имена элементов, а не на классы.

Составные блоки


Слайд 15: Составные блоки


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


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


Слайд 16: Типы составных блоков


Составные можно разделить на два множества:


блоки для расположения (layout blocks) и для содержимого (content blocks).


layout, content (85 Кб)


Блоки для расположения желательно делать абсолютно независимыми, к чему мы плавно переходим.


Полная независимость: возможно ли и какой ценой?


Слайд 17: Полная независимость


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


Чтобы достичь полной независимости блока достаточно выполнять два условия:


1) никогда не опираться на элементы, только на классы.


.b-user b -> .b-user .first-letter


2) всем классам внутри блока давать имена начинающиеся с имени этого блока


.b-user .first-letter -> .b-user-first_letter


Фактически, в этом случае все имена классов на странице будут уникальными и конфликта стилей не будет.


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


Слайд 18: Конфликт имён


Конфликт имён (7 Кб)


Слайд 19: Разрешение конфликта имён


Устранение конфликта имён (11 Кб)


Однотипность кода


Слайд 20: Однотипность кода


Перейдём к такой важной теме, как однотипность кода.


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


Слайд 21: Пример однотипности кода


Однотипноть кода, абстрактный блок (62 Кб)


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


Модификация блоков

Модификация от контекста


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


Слайд 22: Модификация от контекста
Слайд 23: Модификация от контекста


b-newsb-page-index b-news
Новости на внутренней странице (20 Кб)Новости на главной странице (7 Кб)

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


Модификация постфиксом

Изменение конкретного блока


Слайд 24: Изменение конкретного блока


Так что же делать, если надо изменить внешний вид одного и того же блока или сделать несколько однотипных блоков?


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


Например, если у нас есть блок новостей (b-news) и нам надо реализовать его модификацию для индексной страницы, мы к b-news добавляем index и получаем b-news-index, который добавляем вторым классом в элемент.


b-newsb-news b-news-index
Новости на внутренней странице (20 Кб)Новости на главной странице (7 Кб)

В этом случае стили b-news-index дополняют стили у b-news. b-news может использоваться отдельно, а вот b-news-index нет.


Если проводить аналогии с ООП, то это наследование от конкретного класса.


Изменение абстрактного блока


Рассмотрим ещё одно применение модификации блока.


Слайд 25: Изменение абстрактного блока


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


Однотипноть кода, абстрактный блок (62 Кб)


В этом примере b-info это абстрактный блок, задающий общее поведение, а b-info-news, b-info-meteo и b-info-other это конкретные блоки.


Если проводить аналогии с ООП, то это наследование от абстрактного класса.


Префиксы блоков


И в заключение рассмотрим какие бывают префиксы блоков.

Префикс b- (block)


Слайд 26: Префикс b-


Наиболее используемый префикс, почти все блоки описываются используя его.


Префикс h- (holster)


Слайд 27: Префикс h-


Если нам надо задать отступы у группы блоков или разные отступы у одного и того же блока на разных страницах, то удобнее всего использовать для этого элемент-обёртку.


Слайд 28: Пример h-


Пример holster 1 (7 Кб)


Пример holster 2 (8 Кб)


Т.е. если у нас есть три блока b-info и у каждого из них должен быть отступ слева на одной странице 1em, а на другой 8%, то лучше всего не вводить модификаторы и не делать модификарию от контекста, а обернуть эту группу блоков в h-info и задать отступ этому блоку. Блоки-обёртки можно точно так же модифицировать постфиксом, как и обычные блоки.


Префикс l- (layout)


Слайд 29: Префикс l-


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


 (64 Кб)


Префикс g- (global)


Слайд 30: Префикс g-


С префиксом g- описываются глобальные модификаторы, которые могут быть добавлены к любому элементу. Вводить их надо очень аккуратно, вообще необходимость в них очень маленькая.


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


Слайд 31: Пример g-active


Пример g-active (17 Кб)


Как ещё один пример, можно привести модификатор g-hidden, которй скрывает текущий элемент, например, он может использоваться из скрипта.


При этом, если везде в скрипте используется добавление и удаление класса g-hidden, а не непосредственное оперирование inline-стилями, то в случае необходимости можно заменить display: none на position: absolute; left: -9999px;


Заключение


Это всё, что я хотел бы вам сегодня рассказать по этой теме. Спасибо за внимание. Готов ответить на любые вопросы.


vitaly@yandex-team.ru