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

Что это?


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


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

Как это реализуется?

  1. При описании блоков в CSS не используется id, а только class. Во-первых, чтобы не думать будет таких блоков на странице один или несколько, а, во-вторых, никто не даст гарантию, что блок, который встречается сейчас на страние один раз, не будет завтра использован дважды. Вносить переделки в уже работающий и отлаженый код дорого. id, если надо для использования из JavaScript, добавляется отдельно.

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

  3. В таблице стилей не может быть классов вне блоков.

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

  5. Если делать все блоки полностью независимыми, то внутри блока надо опираться только на классы и использовать все имена классов внутри блока начинающиеся на имя этого блока (например, в блоке .b-head использовать для маркировки логотипа не .logo, а .b-head-logo). Тогда никогда не возникнет ситуация, что стили внешнего составного блока будут как-то влиять на стили вложеного блока. Фактически, в этом случае в документе все имена классов будут уникальными и не будут пересекаться. Но на практике это оказывается очень расточительно (и документ, и таблица стилей сильно раздуваются) и не нужно. Внутри блоков используются обычные имена классов, а конфликты имен (которые возникают редко) разрешаются в рабочем порядке.

  6. Однотипные по семантике блоки (дизайн у них может быть разным) надо стараться завёрстывать однотипно. Вообще, при вёрстке всегда надо стараться думать, как это будет нарезано в XSLT (и никогда не смотреть, как оно действительно нарезано (шутка!)).

  7. Бывают разные модификации одного и того же блока или же несколько однотипных блоков могут иметь одно и тоже основное имя к кототому добавляется имя-модификатор. При этом оба имени, основное и модификатор, описываются в HTML одновременно. Может быть несколько модификаторов.

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

    Или если есть несколько однотипных блоков, которые хочется описать сначала в общем виде, а потом модифицировать (например, на Погоде: основной блок b-info, а модификации b-info-meteo, b-info-news, b-info-cities, b-info-other (не все блоки сейчас показываются)). В этом случае блок b-info отдельно не используется, он является, как бы, австрактным блоком.

    Это можно было бы сделать и через множественные классы (например, b-info meteo), но мешает отсутствие в MSIE6- полной поддержки множественных классов (то, что там есть работает в редких случаях).

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

    Например, вид блока b-news может отличаться на первой и всех остальных страницах. В этом случае b-news описывается в разделе Common blocks, а для страницы b-page-index описываются другие правила (.b-page-index .b-news {...}, etc)

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


block (b-)
Независимый блок, может использоваться в любом месте страницы.
control (с-)
контрол (независимый блок) с которым ассоциирован javascript объект, обеспечивающий его функциональность, может использоваться в любом месте страницы
global (g-)
глобальное определение, используется по необходимости, количество сведено к минимуму

Префикс b-


Фактически это самый распространённый префикс. С таким префиксом описываются и простые, и составные блоки.


Вот пример части описания шапки (b-head) сервиса Яndex (полный код можно посмотреть на Погоде или Музыке):


HTML:

<table class="b-head">
<tr>
    <td></td>
    <td class="l"></td>
    <td class="service">
        <h1><b>погода</b>&nbsp;</h1>
    </td>
    <td></td>
</tr>
<tr>
    <td></td>
    <td class="logo">
        ...
    </td>
</tr>
...
</table>


CSS:

/* Header (begin) */
    .b-head
    {
        width: 100%;
    }
 
    .b-head td
    {
        width: 2%;
    }
 
    /*
        Пример осторожного использования имени элемента в блоке.
        Фактически .b-head td и .b-head td td это эмуляция .b-head > td.
    */
    .b-head td td
    {
        width: auto;
    }
 
    /* logo */
    .b-head .l
    {
        width: 16%;
    }
 
    /* Service (begin) */
        .b-head .service
        {
            width: 80%;
            padding-bottom: 7px;
        }
 
        /*
            Известно, что h1 в этом блоке один,
            вот и накладываем на него стили спокойно.
        */
        .b-head .service h1, .b-head .service h1 b
        {
            height: 1em;
            min-height: 23px;
        }
 
        ...
    /* Service (end) */
 
    ...
/* Header (end) */

Префикс c-


С таким префиксом описываются «контролы» — независимые блоки, с которыми ассоциируется скрипт, который их «оживляет». (TODO: ссылка на другой документ, который описывает создание контролов).


Для ускорения инициализации контролов было решено использовать для строчных контролов элемент code, который не встречается на страницах в другом качестве и все такие элементы можно получить одним вызовом getElementsByTagName.
Для блочных контролов используется элемент div (намного больший overhead при инициализации из-за частого использования этого элемента, а что делать? другого-то нет).


HTML код контролов, как правило, это то, что увидит пользователь с отключеным скриптом. Бывает, что контрол при инициализaции перестраивает свою внутреннюю разметку. В этом случае структура контрола после инициализации описывается в документации к контролу, а в CSS используются дополнительные классы, которых нет в изначальном HTML коде контрола.


А в остальном контролы это обычные блоки. Иногда быват, что блок завёрстывается с приставкой b-, а потом «оживляется». В этом случае необходимо менять приставку на c-.

Префикс g-


Глобальные стили, которые могу быть применены к любому элементу. Вводить такие блоки надо очень аккуратно, вообще необходимость в них очень маленькая. Фактически, это не «блоки», а «модификаторы» существущих «блоков». Сейчас
на всех «моих» проектах используется только *ТРИ* таких блока:

g-line (блок в котором все другие блоки плывут)


global.css:

/* Control with floats only (begin) */
    body:after, .b-page:after, .b-foot:after, .g-line:after
    {
        display: block;
        visibility: hidden;
        clear: both;
 
        height: 0;
 
        content: ".";
    }
/* Control with floats only (end) */


global-ie.css

/* Control with floats only (begin) */
    * html body, * html .b-page, * html .b-foot, * html .g-line
    {
        height: 1%;
    }
 
    body, .b-page, .b-foot, .g-line
    {
        zoom: 1;
    }
/* Control with floats only (end) */


В его введении нет особой необходимости, фактически эти правила могут копироваться в правила блока, к которому применяется g-line (что я и делаю, если этот блок часто встречается на странице, следую правилу «лучше раздуть css,чем html»).

g-hidden


Банальный display: none. Обычно этот класс добавляется скриптом.

g-decor


Используется для создания оформления скриптом (уголки, тени, etc). Скрипт встретив такой элемент добавляет в него ещё 9 элементов, чего с головой хватает для большинства дизайнерских изысков. Активно применяется на Музыке, там же можно сейчас посмотреть реализацию (я пока не описал её).