[первая часть] - [вторая часть] - [третья часть]
Самое начало (Яндекс.Адреса)
Когда я начал работать над Яндекс.Адресами в далёком 2005 году, вёрстку я делал так:
Делались статические HTML-странички (index.html, about.html), стили для них складывались в один CSS-файл (adresa.css), скрипты в adresa.js, а картинки в директорию i (i/yandex.png, i/hint.png, etc).
Хаки для MSIE писались в этом же файле через * html и [id].
about.html
index.html
...
adresa.css
adresa.js
i/
yandex.png
Все стили были в одном файле, и для их визуального разделения в коде использовались комментарии с указанием начала и конца этой части.
/* Content container (begin) */
#body
{
font: 0.8em Arial, sans-serif;
margin: 0.5em 1.95% 0.5em 2%;
}
/* Content container (end) */
/* Graphical banner (begin) */
.banner
{
text-align: center;
}
.banner a
{
text-decoration: none;
}
/* Graphical banner (end) */
Свёрстанные статические HTML-странички нарезались в XSL, который использовался в продакшене. Правки HTML, которые вносились в XSL, вручную переносились в HTML, для поддержания статики в актуальном состоянии.
Проекты большего размера (Яндекс.Музыка, Яру)
Адреса были маленьким проектом с несколькими страницами и там такой подход к вёрстке работал.
При вёрстке первой версии Яндекс.Музыки в начале 2006 стало понятно, что для проекта с большим количеством страниц такой подход к верстке не работает. Тяжело подбирать названия классам, так, чтобы они не пересекались с классами на других страницах. Код всего проекта сложно держать в голове и писать его так, чтобы изменения на одной странице ничего не ломали на другой странице.
Типичный код того времени:
/* Albums (begin) */
.result .albums .info
{
padding-right: 8.5em;
}
.result .albums .title
{
float: left;
padding-bottom: 0.3em;
}
.result .albums .album .listen
{
float: left;
padding: 0.3em 1em 0 1em;
}
.result .albums .album .buy
{
float: left;
padding: 0.4em 1em 0 1.6em;
}
.result .albums .info i
{
font-size: 85%;
}
/* Albums (end) */
И вот ещё пример:
/* Картинки на фоне (begin) */
.b-foot div
{
height: 71px;
background: transparent url(../i/foot-1.png) 4% 50% no-repeat;
}
.b-foot div div
{
background-position: 21%;
background-image: url(../i/foot-2.png);
}
.b-foot div div div
{
background-position: 38%;
background-image: url(../i/foot-3.png);
}
.b-foot div div div div
{
background-position: 54%;
background-image: url(../i/foot-4.png);
}
.b-foot div div div div div
{
background-position: 71%;
background-image: url(../i/foot-5.png);
}
.b-foot div div div div div div
{
background-position: 87%;
background-image: url(../i/foot-6.png);
}
/* Картинки на фоне (end) */
Одновременно с Музыкой началась вёрстка Яндекс.Друзей (сейчас это Яру). Это был проект с десятками страниц и такой подход к верстке не работал — вёрстка становилась неуправляемой.
Поэтому части страниц, которые имеют самостоятельное значение в дизайне проекта, стали называть блоками. Корневые классы блоков получили префиксы (b-, c-, g-). Внутренние классы блоков писали без префиксов.
Используемые префиксы:
b- block
независимый блок, может использоваться в любом месте страницы
с- control
контрол (независимый блок) с которым ассоциирован javascript
объект, обеспечивающий его функциональность, может использоваться
в любом месте страницы
g- global
глобальное определение, используется по необходимости, количество
сведено к минимуму
Используемые постфиксы:
-nojs no javascript
стиль применяется в отсутствие javascript, если javascript
включен, то при загрузке страницы у всех элементов этот
постфикс убирается, для этого должен быть вызван метод init() в onload
Элементы у которых много кода, обрамляются в коде своими комментариями с маркерами начала и конца:
/* Head (begin) */
.b-head { ... }
/* Logo (begin) */
.b-head .logo { ... }
.b-head .logo a { ... }
/* Logo (end) */
/* Right side (begin) */
.b-head .right { ... }
/* Info (begin) */
.b-head .info { ... }
.b-head .info .exit a { ... }
/* Info (end) */
/* Search (begin) */
.b-head .search { ... }
.b-head .search div div, .b-head .search div div i { ... }
/* Search (end) */
/* Right side (end) */
/* Head (end) */
Стили кладутся в директорию css (css/music.css), скрипты в js (js/music.js).
Валидные хаки для MSIE пишутся в основном CSS-файле:
/* Common definitions (begin) */
body
{
font-family: Arial, sans-serif;
font-size: 0.8em;
padding: 0 0 2em 0;
background: #fff;
}
* html body
{
font-size: 80%;
}
...
/* Common definitions (end) */
Невалидные хаки уносятся в файл css/music-ie.css:
/* Common blocks (begin) */
/* Artist (begin) */
.b-artist .i i
{
top: expression(7 + (90 - this.parentNode.getElementsByTagName('img')[0].height)/2);
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../i/sticker-lt.png', sizingMethod='crop');
}
...
Структура проекта выглядит следующим образом:
about.html
index.html
css/
music.css
music-ie.css
js/
music.js
i/
yandex.png
Зачатки общепортального фреймворка
Когда верстаешь несколько проектов одновременно, появляются общие блоки, которые растут и меняются вместе с проектами. Очень быстро понимаешь, что copy/paste этих блоков с проекта на проект не выход и надо делать некоторый common, куда уносить общее.
Так появляется общее хранилище, в которые складываются стили шапки, статического текста и т.д.
Эти стили подключаются в основной проектный файл с помощью импортов:
@import url(http://common.cloudkill.yandex.ru/css/global.css);
@import url(http://common.cloudkill.yandex.ru/css/head/common.css);
@import url(http://common.cloudkill.yandex.ru/css/static-text.css);
@import url(http://common.cloudkill.yandex.ru/css/list/hlist.css);
@import url(http://common.cloudkill.yandex.ru/css/list/hlist-middot.css);
@import url(http://common.cloudkill.yandex.ru/css/dropdown/dropdown.css);
@import url(http://common.cloudkill.yandex.ru/css/dropdown/dropdown-arrow.css);
@import url(http://common.cloudkill.yandex.ru/css/foot/common-absolute.css);
@import url(http://common.cloudkill.yandex.ru/css/foot/common-absolute-4-columns.css);
@import url(slider.css);
/* Header (begin) */
/* Service (begin) */
.b-head .service h1 { ... }
.b-head .service h1, .b-head .service h1 a, .b-head .service h1 b { ... }
...
Чтобы с этим можно было уйти в продакшн, появляется процесс сборки проекта, во время которого вместо @import подставляется содержимое этих файлов.
Вёрстка независимыми блоками (доклад на ClientSide'2007)
К осени 2007 года правила вёрстки уже устоялись и о них захотелось рассказать вне Яндекса.
На ClientSide'2007 я сделал доклад «Вёрстка независимыми блоками»
Блок
В докладе вводится понятие «Блок»:
Блоком будем называть фрагмент страницы, который описывается своей разметкой и стилями.
Правила независимости блока
Формулируются правила независимости блока:
1) для описания элемента используется class, но не id
2) каждый блок имеет префикс
3) в таблице стилей нет классов вне блоков
Отказ от использования id даёт возможность использовать один и тот же блок несколько раз на странице. Так же позволяет использовать несколько классов на одном DOM-узле, что в дальнейшем нам пригодилось.
Более позднее описание в клубе БЭМ: http://clubs.ya.ru/bem/replies.xml?item_no=4
Простые и составные блоки
Блоки делятся на простые и составные.
В простые блоки нельзя вкладывать другие блоки, в составные — можно. Это было очень наивное деление, даже в самые простые блоки вкладывались другие блоки и приходилось переделывать вёрстку, потому что простые блоки верстались с использованием имён html-элементов в селекторах.
Более позднее описание в клубе БЭМ: http://clubs.ya.ru/bem/replies.xml?item_no=42
Правила полной независимости блоков
Так же были сформулированы правила полной независимости блоков:
1) никогда не опираться на элементы, только на классы: .b-user b -> .b-user .first-letter
2) всем классам внутри блока давать имена начинающиеся с имени этого блока: .b-user .first-letter -> .b-user-first_letter
Позже мы назвали это АНБ (абсолютно-независимые блоки): http://clubs.ya.ru/bem/replies.xml?item_no=43
Сейчас все блоки делаются в АНБ-нотации, но на тот момент мы считали, что так раздувать html-код дорого и надо этот подход применять только в исключительных случаях.
Префиксы
Имена блоков начинаются с префиксов. На тот момент использовались префиксы b-, h-, l-, g-
Модификация блоков
Определились правила изменения внешнего вида блока:
- Модификация блока от контекста — блок меняет свой внешний вид в зависимости от того в какой контекст он помещён
- Модификация постфиксом — добавляя постфикс имени блока (b-block b-block-postfix) и используя дополнительные классы в HTML
[первая часть] - [вторая часть] - [третья часть]
И нам про это на школе верстки рассказывали! Полезно почитать)