Этот документ устарел в пользу БЭМ. Читайте историю создания БЭМ в клубе на Яру.
Презентация в PPT (1.1 Mb), PDF (0.9 Mb)
Слайд 1: Приветствие
Добрый день, я Виталий Харисов. Я расскажу вам про вёрстку независимыми блоками.
Прежде чем перейти к непосредственно независимым блокам, давайте определим, что такое блок вообще.
Рассмотрим типичную web-страницу (Слайд 2: Типичная страница):
На этой странице явно можно выделить (Слайд 3: Типичная страница с блоками) как минимум четыре зоны, каждая из которых обособлена от других и описывается своей разметкой и стилями.
Если в шапке выводится имя пользователя и в теле страницы тоже используется имя пользователя, мы получаем (Слайд 4: Типичная страница с именем пользователя) ещё один блок.
Т.о. блоком будем называть (Слайд 5: определение блока) фрагмент страницы, который описывается своей разметкой и стилями.
Для интенсивно развивающихся проектов (Слайд 6: Необходим механизм) необходим механизм, облегчающий сборку шаблонов, позволяющий переставлять блоки на странице местами, быстро собирать страницы из уже имеющихся, повторно использовать блоки из одного проекта на другом.
Для этого была разработана техника "вёрстка независимыми блоками".
Вкраце, (Слайд 7: краткое опредение) это когда используется минимум глобальных стилей, каждый обособленный элемент страницы описывается своими стилями (стили дублируются, а не объединяются в случае необходимости), которые в идеале не пересекаются со стилями других блоков. Блоки могут вкладываться в другие блоки.
При этом, каждый независимый блок удовлетворяет следующим условиям (Слайд 8: Условия независимости):
1) для описания элемента используется class, но не id
2) каждый блок имеет префикс
3) в таблице стилей нет классов вне блоков
Рассмотрим каждый пункт отдельно.
Слайд 9: Используем только class
В развивающемся проекте (развивающийся = не тот, который сделали один раз и забыли) постоянно происходит переосмысление внешнего вида и функциональности и никогда нельзя быть увереным, что элемент, который казалось бы встречается на странице только один раз завтра не будет встречаться много.
Даже такая, казалось бы, единственная вещь, как логотип или подвал.
Слайд 10: Пример неуникальности блоков
Слайд 11: Менять id на class дорого
Поскольку id в валидном документе может быть только один, то при необходимости добавления точно такого же элемента на страницу надо переписывать код на классы. Хотя кажется, что это трёхминутное дело, на самом деле это относительно дорогая операция, поскольку изменение кода в уже работающем проекте требует участия нескольких человек (разработчики, тестировщики) и времени на кодировние, тестирование и выкладку. Это уже не говоря о том, времени этого просто нет.
Если id нужен для использования из скрипта, добавляем его отдельно, в стилях не используем.
Слайд 12: Блок b-user
Для явного выделения блоков, элементу ограничивающему блок задаётся класс с префиксом (b-, h-, l- об этом ниже) и все стили этого блока описываются начиная от этого класса.
Рассмотрим на примере:
У нас есть блок "имя пользователя" (user), внешнему элементу которого задаётся класс b-user и все стили описываются начиная с этого класса.
Слайд 13: Нет классов вне блоков
Вся страница разбивается на блоки, все стили должны относиться к какому-то блоку, не должно быть классов вне блоков.
Теперь поговорим подробнее какие блоки бывают. Можно выделить два вида блоков: простые и составные.
Слайд 14: Простые блоки
Простой блок не может содержать других блоков, он неделим.
В простых блоках можно опираться на имена элементов, а не на классы.
Слайд 15: Составные блоки
Составной блок содержит другие блоки. В составных блоках нельзя опираться на имена элементов, только на классы.
При использовании простых блоков существует опасность, что завтра он станет составным. Использовать простые блоки надо очень осторожно или не использовать совсем.
Слайд 16: Типы составных блоков
Составные можно разделить на два множества:
блоки для расположения (layout blocks) и для содержимого (content blocks).
Блоки для расположения желательно делать абсолютно независимыми, к чему мы плавно переходим.
Слайд 17: Полная независимость
Можно ли достить полной независимости блоков, чтобы одни блоки не влияли на другие при любом расположении? Да, можно, но за всё надо платить.
Чтобы достичь полной независимости блока достаточно выполнять два условия:
1) никогда не опираться на элементы, только на классы.
.b-user b -> .b-user .first-letter
2) всем классам внутри блока давать имена начинающиеся с имени этого блока
.b-user .first-letter -> .b-user-first_letter
Фактически, в этом случае все имена классов на странице будут уникальными и конфликта стилей не будет.
Но это сильно раздувает HTML код и полная независимость всех блоков на странице не оправдана. Поэтому для внутренних классов у блока используем обычные имена, а конфликты этих имён разрешаем в рабочем порядке, например, делая внешний блок полностью независимым.
Слайд 18: Конфликт имён
Слайд 19: Разрешение конфликта имён
Слайд 20: Однотипность кода
Перейдём к такой важной теме, как однотипность кода.
Однотипные по семантике блоки (дизайн у них может быть разным) надо стараться завёрстывать однотипно. Это облегчает чтение и понимание кода, а так же позволяет легче делать новые блоки на основе уже существующих.
Слайд 21: Пример однотипности кода
На этой картинке представлены три блока различающиеся дизайном, но свёрстанные похожим образом: у каждого блока есть заголовок и или абзац, или список внутри.
Один и тот же блок может видоизменяться в зависимости от того, в какой составной блок он помещён. Например, блок новостей на внутренних страницах сайта может содержать расширенную информацию, а на главной странице (где места всегда не хватает) укороченый вариант.
Слайд 22: Модификация от контекста
Слайд 23: Модификация от контекста
b-news | b-page-index b-news |
Но модификация от контекста привязывает блок к какой-то определённой странице или расположению на ней, что идёт в разрез с нашими целями сделать вёрстку более независимой. Я не рекомендую использовать модификацию от контекста, опыт показывает, что это приносит больше вреда, чем пользы.
Слайд 24: Изменение конкретного блока
Так что же делать, если надо изменить внешний вид одного и того же блока или сделать несколько однотипных блоков?
Всё очень просто, мы создаём модификацию блока вводя новый класс, имя которого начинается с имени модифицируемого блока и добавляем к нему постфикс описывающий изменения.
Например, если у нас есть блок новостей (b-news) и нам надо реализовать его модификацию для индексной страницы, мы к b-news добавляем index и получаем b-news-index, который добавляем вторым классом в элемент.
b-news | b-news b-news-index |
В этом случае стили b-news-index дополняют стили у b-news. b-news может использоваться отдельно, а вот b-news-index нет.
Если проводить аналогии с ООП, то это наследование от конкретного класса.
Рассмотрим ещё одно применение модификации блока.
Слайд 25: Изменение абстрактного блока
В случае когда у нас есть несколько разных однотипных блоков, у которых часть стилей общая, имеет смысл ввести абстрактный блок, который без модификаторов не используется. Общие свойства описываются в абстрактном блоке, а конкретика в модифицированных блоках.
В этом примере b-info это абстрактный блок, задающий общее поведение, а b-info-news, b-info-meteo и b-info-other это конкретные блоки.
Если проводить аналогии с ООП, то это наследование от абстрактного класса.
И в заключение рассмотрим какие бывают префиксы блоков.
Слайд 26: Префикс b-
Наиболее используемый префикс, почти все блоки описываются используя его.
Слайд 27: Префикс h-
Если нам надо задать отступы у группы блоков или разные отступы у одного и того же блока на разных страницах, то удобнее всего использовать для этого элемент-обёртку.
Слайд 28: Пример h-
Т.е. если у нас есть три блока b-info и у каждого из них должен быть отступ слева на одной странице 1em, а на другой 8%, то лучше всего не вводить модификаторы и не делать модификарию от контекста, а обернуть эту группу блоков в h-info и задать отступ этому блоку. Блоки-обёртки можно точно так же модифицировать постфиксом, как и обычные блоки.
Слайд 29: Префикс l-
Если блок используется только для расположения других блоков, называем его лайаутным блоком, используем для него префикс l- и делаем его полностью независимым. Это позволяет сразу видеть в коде блоки для расположения и, в случае необходимости, заменить раскладку флоатами на таблицу или наоборот.
Слайд 30: Префикс g-
С префиксом g- описываются глобальные модификаторы, которые могут быть добавлены к любому элементу. Вводить их надо очень аккуратно, вообще необходимость в них очень маленькая.
Например, есть несколько видов меню на странице и выделение текущего элемента в них делается одинаковым образом, скажем, изменением фона. В этом случае можно ввести глобальный модификатор g-active который добавлять текущему пункту меню.
Слайд 31: Пример g-active
Как ещё один пример, можно привести модификатор g-hidden, которй скрывает текущий элемент, например, он может использоваться из скрипта.
При этом, если везде в скрипте используется добавление и удаление класса g-hidden, а не непосредственное оперирование inline-стилями, то в случае необходимости можно заменить display: none на position: absolute; left: -9999px;
Это всё, что я хотел бы вам сегодня рассказать по этой теме. Спасибо за внимание. Готов ответить на любые вопросы.
vitaly@yandex-team.ru