Пользователь
20,8
рейтинг
24 ноября 2013 в 20:20

Разработка → Верстка для самых маленьких. Верстаем страницу по БЭМу tutorial

HTML*, CSS*
Недавно хабраюзер Mirantus написал статью «Как сверстать веб-страницу», в которой рассказывал о том, как же сверстать веб-страничку. В его статье было подробно рассмотрено, как выделить отдельные элементы из заданного шаблона, подобрать шрифты и т.п. Однако его подход к написанию, собственно, веб-страницы мне показался не очень хорошим, о чем я написал в комментариях.

В данной статье я хочу рассказать, о том, как можно сверстать «хорошо» (по крайней мере структурировано ;), а заодно рассказать и о методологии, которая может «упростить жизнь» при верстке. Структура поста будет следующей:

  • BEM
  • Собственно пример — как сверстать страницу


BEM


БЭМ (Блок, Элемент, Модификатор) — методология разработанная внутри Яндекса предлагает следующую концепцию (если описать 1-2 предложениями):

Любая веб-страница — набор блоков, которые состоят из элементов, причем элементом может быть другой блок (таким образом мы получаем вложенность). При необходимости мы можем модифицировать «стандартное» отображение блока\элемента, путем добавления к нему модификатора.

Сайт методологии: ru.bem.info

Очень хорошее «руководство к действию» можно найти здесь: ru.bem.info/method/definitions

Предлагаю дать определения основным элементам:

Блок — часть страницы, являющаяся логически независимой от остального наполнения. Представляет собой «строительную единицу» для сайта (на примере конструктора лего — это отдельный «кирпичек»)

Блок не отвечает за свое расположение. Он задает внутренние свойства (размеры, шрифты и т.д.)

Внутри Блок содержит Элементы. Элемент — часть блока, которая отвечает за отдельную задачу (например, это расположение внутри блока). Элемент должен входить в состав блока и не должен иметь какого-либо смысла отдельно от блока.

Пример выделения блоков\элементов


Для примера возьмем блок «прямой эфир» на сайте Хабра:

Вот так он выглядит:



Если «организовать» его по методологии БЭМ, то данная часть будет являть собой блок, состоящий из элементов:



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

Элементы выделенные розовым цветом внутри себя содержат другой блок, назовем его «пост».

Соответственно, рассмотрим из чего состоит блок пост:



Таким образом, блок «пост» состоит из 5 элементов.

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

Теперь рассмотрим третью составляющую БЭМ — модификатор.
Модификатор может задавать как дополнительное поведение для блока\элемента, так и переопределять стандартное.
Самым ярким примером для понимания «модификатора» служит пример с кнопками.
Предположим, что в проекте используются кнопки типа:



Такая кнопка имеет некий padding слева и справа, шрифт и цвет background'а. Соответственно, мы представляем кнопку как .button и добавляем эти свойства ей.

Теперь, в проект на некоторых страницах необходимо добавить такие же кнопки, но, скажем, с background-color:red;
Решить данную задачу с использованием БЭМ можно очень просто:
Создать модификатор для блока: .button_red, для которой добавить заданное свойство.

Готово! В проекте появились красные кнопки с другим внешним видом. Причем нам не понадобилось создавать новые сущности.

Стиль описания БЭМ


БЭМ не декларирует «особого» стиля описания классов. Однако, де-факто используется следующий стиль:

1) Несколько слов в одном названии разделяются дефисом (например, блок main-page или my-super-main-list)
2) Элементы отделяются от блоков с использованием двух символов подчеркивания "__" (например, main-page__header или my-super-main-list__item)
3) Модификаторы отделяются одним символом подчеркивания "_" (например, main-page__header_strong или my-super-main-list_blue)

Префиксы


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

Например:
g- (global) префикс для глобальных классов. (Например, для задания невидимых элементов g-hidden.)
b- (block) префикс для выделения элементов, относящихся к структуре документа.
js- (JavaScript) префикс для выделения элементов для селекторов js.

Разметка страницы


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

Почему использование каскада — плохо?


У людей, впервые для себя открывших БЭМ может возникнуть вопрос — почему элементы описываются такими длинными цепочками? не проще ли:
.main-page
.main-page .header
и т.д.

Данный способ проще записывается, но, к сожалению, может нарушить независимость блоков.
Пример:
имеем следующую стуктуру:

.main-page
 		.header
 		.item
 			.article
 				.header
 				.text
 		.item
 		////


В этом случае .main-page .header будет применен не только к нужному .header, но и .item .article .header, что является ненужным. БЭМ предполагает уход от каскадных стилей (типа div .someClass li), которые:
1) повышают специфичность веб-страниц;
2) нарушают независимость блоков. (в отличие от БЭМ).

Именно поэтому, корректной структурой для БЭМ будет:


 	.main-page
 		.main-page__header
 		.main-page__item
 			.article
 				.article__header
 				.article__text
 		.main-page__item
 		////



Какие плюсы дает БЭМ?


0) Независимость блоков — за счет ухода от каскадности и отказа от описания в блоке «своего позиционирования»;
1) Повторяемость блоков — любой независимый блок можно повторять на любых страницах проекта. Возможно создать базу блоков, вследствие чего новые страницы будут создаваться подобно конструктору Лего;
2) Простота поддержки;
3) Структурированность кода.

Страница, сверстанная с использованием БЭМ может выглядеть больше, чем страницы, сверстанные без использования данной методологии, однако, представьте, если вы работаете с сайтом, где >20-30 уникальных страниц? В таком случае возможность повторного использования блоков и единая концепция позволяет:
1) намного быстрее принимать решения о модернизации страниц\блоков сайта;
2) уменьшает порог вступления в проект новых разработчиков.

Верстаем страницу


В качестве шаблона воспользуемся Corporate Blue.
Верстать будем главную страницу:



Изначально определим разметку страницы:



Здесь блок имеет 6 элементов.
По порядку:
1) Верхняя линия
2) Header
3) Меню
4) Слайдер
5) Main
6) Footer

Запишем эту структуру:

<!DOCTYPE html>
<html>
<head>
    <title>BEM-example</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="styles/style.css">    
</head>
<body class="b-page">
    <div class="b-page__head-line">
        
    </div>
    <div class="b-page__line">
        
    </div>
    <div class="b-page__line">
        
    </div>
    <div class="b-page__line">
        
    </div>
    <div class="b-page__line">
      
    </div>
    <div class="b-page__footer">
       
    </div>
</body>
</html>


Зададим стили для блока и элементов:

.b-page
{
    width:100%;
    margin:0;
    background-color:#f7f7f7;
    background:url("../img/bg.png");
    font-family:Oswald,Tahoma;
    font-size:12px;
}

    

.b-page__head-line
{
    background-color:#7e7e7e;
    height:5px;
    
    width:100%;
}

.b-page__line
{

    width: 960px;
    margin: 0 auto;
    margin-top:27px;    
}


Разберем header страницы


Он состоит из двух элементов:

1) Лого:



2) Форма поиска:



Выделим картинку и зададим HTML-структуру:

<div class="b-page__line">
        <div class="b-head">
            <div class="b-head__logo">
                <div class="b-logo">
                    <a href="#"><img class="b-logo__img" src="img/Logo.png"/></a>
                </div>
            </div>
            <div class="b-head__search">
                <div class="b-search">
                    <div class="b-search__input">
                        <input type="text" class="b-input b-input_search" placeholder="Search"> 
                    </div><div class="b-search__input"><div class="b-button">GO</div>
                    </div>
                </div>
            </div>
        </div>
    </div>



HINT: второй div .b-search__input располагаем «впритык» к концу первого. Если так не сделать, то между двумя элементами будет пустое место. Его можно убрать либо изменив отступы, либо убрав в html коде пробелы.

Соответствующие стили:

Для блока лого:

.b-head
{
    height:36px;
}
    

.b-head__logo
{
    float: left;    
}

Для поиска:

.b-head__search
{
    float:right;
}

.b-search__input
{
    display:inline-block;
}

.b-input
{
    background-color: #f3f3f3;
    border:1px solid #e7e7e7;    
}

.b-input_search
{
    height:32px;
    padding:0 10px;
    width:135px;
    border-right:none;
}
.b-button
{
    color:#fefefe;
    height:34px;
    padding:0 12px;
    line-height:33px;
    cursor:pointer;
    background-color:#29c5e6;
}

В данном блоке мы расположили элементы блока b-head слева и справа, а для input поиска задали стиль отображения inline-block.

Реакцию на работу кнопок\ссылок создавать не будем, так как цель статьи — показать на примере как можно верстать, используя БЭМ.

header готов.

Переходим к меню




Заметим, что каждый элемент можно представить как самостоятельный блок (состоящий только из себя) и являющийся ссылкой. Заведем сущность ссылка (b-link) и определим для нее обычный стиль и шрифт для ссылки:

.b-link
{
    color:#525252;
    font-size:12px;
        
}


Стили ссылок для меню определим в модификаторе .b-link_menu. Создадим HTML код:
<div class="b-page__line">
        <div class="b-menu">
            <a href="#" class='b-link b-link_menu b-link_menu_active' >HOME</a>
            <a href="#" class='b-link b-link_menu' >ABOUT US</a>
            <a href="#" class='b-link b-link_menu'>SERVICES</a>
            <a href="#" class='b-link b-link_menu'>PARTNERS</a>
            <a href="#" class='b-link b-link_menu'>CUSTOMERS</a>
            <a href="#" class='b-link b-link_menu'>PROJECTS</a>
            <a href="#" class='b-link b-link_menu'>CAREERS</a>
            <a href="#" class='b-link b-link_menu'>CONTACT</a>
        </div>
    </div>


Активный пункт меню выделим как .b-link_menu_active.

Остается только добавить стили и меню готово:
.b-menu
{
    margin:0;
    padding:0;
    list-style:none; 
    width:100%;
    display:table;
    table-layout: fixed;   

}

.b-link_menu
{
    text-align:center;
    color:#bfbfbf;
    cursor:pointer;
    font-size:14px;
    height:38px;
    background-color:#f3f3f3;
    line-height:38px;
    border: 1px solid #e7e7e7;
    display:table-cell;
    text-decoration: none;
}

.b-link_menu_active
{
    color:#fefefe;
    background-color:#29c5e6;
    border:1px solid #29c5e6;
}


HINT: Если стоит задача сверстать набор элементов на полную ширину родителя, причем все элементы должны занимать одинаковое место, то решением можно считать:
1) Родителю задаем display: table; table-layout:fixed;
2) Дочерним элементам задаем display: table-cell;
Такое моделирование таблицы позволяет успешно решить поставленную задачу.


Переходим к слайдеру:




Здесь текст на слайдере необходимо вывести на картинке. Соответственно, для этого можно использовать картинку (на которой написать вручную текст), а можно воспользоваться особенностью position, либо z-index.
Второй способ гласит, что элементы с position: relative\ absolute отрисовываются отдельно от «остальных» элементов. Соответственно, эти элементы будут отображены «выше» остальных.
Третий способ: z-index задается для сестринских элементов. Представляет собой отображение по оси 0Z. Соответственно, тот элемент, у которого z-index выше, будет перекрывать собой те, у которого z-index ниже.

Зададим HTML структуру:

<div class="b-page__line">
        <div class="b-slider">
            <div class="b-slider__current">
                <div class="b-slide">
                    <div class="b-slide__text">
                        <div class="b-slide-text">
                            <div class="b-slide__header  ">  
                                FUSCE VITAE NIBN QUIS DIAM FERMENTUM
                            </div>
                            <div class="b-slide__subtext">
                                Etiam adipscing ultricies commodo.
                            </div>
                        </div>                       
                    </div>
                    <div class="b-slide__image">
                        <img class="b-image b-image_slider" src="img/slider.png">
                    </div>
                </div>
            </div>
            <div class="b-slider__list">
                <ul class="b-slide-list">
                    <li class="b-slide-list__item">
                        <div class=b-slider-case-element>
                            <span class="b-slider-case-element__number b-slider-case-element__number_active">1</span>
                            <span class="b-slider-case-element__text b-slider-case-element__text_active">LOREM IPSUM DOLOP</span>
                        </div>
                    </li>
                    <li class="b-slide-list__item">
                        <div class=b-slider-case-element>
                            <span class="b-slider-case-element__number">2</span>
                            <span class="b-slider-case-element__text">ULTRICIES PELLENTESQUE</span>
                        </div>
                    </li>
                    <li class="b-slide-list__item">
                        <div class=b-slider-case-element>
                            <span class="b-slider-case-element__number">3</span>
                            <span class="b-slider-case-element__text">ALIQUAM IPSUM</span>
                        </div>
                    </li>
                    <li class="b-slide-list__item">
                        <div class=b-slider-case-element>
                            <span class="b-slider-case-element__number">4</span>
                            <span class="b-slider-case-element__text">NULLAM SED MAURIS UT</span>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
    </div>


Меню слайдера не использует так как предполагается, что при нажатии меняется текущее содержимое слайдера.

CSS:
.b-slide__text
{
    position:relative; 
    top:40px;
    left:35px;
    z-index:10;
}

.b-slide__header
{
    font-size:42px;
    color:#5a5a5a;    
}

.b-slide__subtext
{
    font-size:20px;
    color:#b0b0b0;
}

.b-slide__image
{
    z-index: 0;
    margin-top:-62px;
}

.b-slider__list
{
    height:50px;
    background-color:#f3f3f3;
    width:100%;
    margin-top:-2px;
    border-bottom: 1px solid #e7e7e7;
}

.b-slide-list
{
    margin:0;
    padding:0;
    list-style:none; 
    width:100%;    
    display:table;
    table-layout:fixed;    
    font-size:16px;
    color:#8f8f8f;
}

.b-slide-list__item
{
    display:table-cell;
}

.b-slider-case-element__number
{
    text-align:center;
    display:inline-block;
    width:22px;
    margin-left:12px;
    margin-top:12px;
    height:22px;
    background-color: #8f8f8f;
    color:#f3f3f3;
}

.b-slider-case-element
{
    cursor:pointer;
}

.b-slider-case-element__number_active
{
    background-color:#29c5e6;
    color:#fefefe;
}

.b-slider-case-element__text_active
{
    color:#29c5e6;
}


Main-блок


Основной блок состоит из 6 элементов, каждый из которых содержит блок, наполненый:
а) картинками
б) текстом
в) ссылками



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

.b-main__item
{
    float:left;
    margin-left:10px;
    width:460px;
}

.b-main__item_small
{
    width:300px
}

.b-main__item_long
{
    width:920px;
}

Отдельно взятый блок будет выглядеть так:

  <div class="b-company">
                    <div class="b-company__header">
                        <div class="b-item-head">
                            <div class=b-item-head__img>
                                <img  src="img/sq.png">
                            </div><div class="b-item-head__text">ABOUT WHITESQUARE</div>                         
                        </div>
                    </div>
                    <div class="b-company__content">
                        <div class="b-content">
                            <img class="b-content__img" src="img/middle.png"/>
                            <div class="b-content__text">
                                In ultricies pellentesque massa a porta. Aliquam ipsum enim, hendrerit ut porta nec, ullamcorper et nulla. In eget mi dui, sit amet scelerisque nunc. Aenean augue arcu, convallis ac vulputate vitae, mollis non lectus. Donec hendrerit lacus ac massa ornare hendrerit sagittis lacus tempor. Vivamus et dui et neque accumsan varius et ut erat. Enean augue arcu, convallis ac ultrices. 
                            </div>
                            <div class="b-content__link">
                                <p><a href="#" class="b-link">Read more</a></p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

Со стилями:

.b-item-head__img
{
    display:inline-block;
    background: url("../img/bg.png");
    padding:2px;
    
}

.b-item-head__text
{
    display:inline-block;
}

.b-item-head
{
    line-height:16px;
    height:19px;
    background:url('../img/hbg.png') repeat;
}


.b-item-head__text
{
    display:inline;
    font-size:16px;   
    color:#8f8f8f;
    padding:3px;    
    padding-right:10px;  
    background: url("../img/bg.png");
}

.b-company
{
    width:100%;
}

.b-company__content
{
    margin-top:15px;
}
.b-content__img
{
    float:left;
    margin-right:20px;
}
.b-content__text
{
    color:#8f8f8f;
    font-size:12px;
}
.b-link,.b-content__link
{
    color:#525252;
    font-size:12px;
        
}


Аналогично отображаются другие блоки. (Меняем стили только внутренних элементов)

Переходим к footer


footer состоит из трех расположенных последовательно вложенных блоков:
1) Twitter
2) SiteMap
3) Social Networks
И четвертого, выровненного по правому краю — логотипу:


Разберем верстку каждого из этих блоков:

Twitter


Состоит из времени, заголовка и текста.

<div class="b-twitter">
           <div class="b-twitter__header  ">
                            TWITTER FEED
           </div>
           <div class="b-twitter__time">
                            22 oct
          </div>
          <div class="b-twitter__text">
                         In ultricies pellentesque massa a porta. Aliquam ipsum enim, hendrerit ut porta nec, ullamcorper et nulla. In eget mi dui, sit amet scelerisque nunc. 
          </div>
</div>


В стилях задаем размер блока, цвета и прочие стили:

.b-twitter
{
    width:300px;
}

.b-twitter__header,.b-sitemap__header,.b-networks__header
{
    color:#fff;
    font-size:14px;
    width:100%;
    border-bottom:1px solid #878787;
}

.b-twitter__time
{
    margin-top:5px;
    font-size:11px;
    color:#b4aeae;
    text-decoration:underline;
}

.b-twitter__text
{
    margin-top:5px;
    font-size:11px;
    color:#dbdbdb;
}


Здесь же задали и стили заголовков для остальных блоков (т.к. они одинаковы)

Sitemap


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

Эффект 2 колонок получаем за счет указания размера блока + одной группе ссылок задаем float:left, другой float: right:

<div class="b-sitemap">
                    <div class="b-sitemap__header  ">
                        SITEMAP
                    </div>
                    <div class="b-sitemap__links">
                        <a href="#" class="b-link b-link_white b-link_block b-link_undecorate">Home</a>
                        <a href="#" class="b-link b-link_white b-link_block b-link_undecorate">About</a>
                        <a href="#" class="b-link b-link_white b-link_block b-link_undecorate">Services</a>
                    </div>
                    <div class="b-sitemap__links_right">
                        <a href="#" class="b-link b-link_white b-link_block b-link_undecorate">Partners</a>
                        <a href="#" class="b-link b-link_white b-link_block b-link_undecorate">Support</a>
                        <a href="#" class="b-link b-link_white b-link_block b-link_undecorate">Contact</a>
                    </div>
                </div>


CSS:

.b-sitemap__links
{
    float:left;
}

.b-link_white
{
    color:#dbdbdb;    
}

.b-link_undecorate
{
    text-decoration:none;
}

.b-link_block
{
    margin-top:8px;
    display:block;
}

.b-sitemap__links_right
{
    float:right;
    margin-right:20px;
}


Social


Здесь воспользуемся спрайтами. (Спрайт -картинка, которая содержит набор других картинок) Соответственно, с помощью Background-image + background-position для каждого элемента блока выбираем необходимые части картинки:


<div class="b-networks">
                   <div class="b-networks__header  ">
                        SOCIAL NETWORKS
                    </div>
                   <div class="b-networks__icon b-networks__icon_twitter"></div> 
                   <div class="b-networks__icon b-networks__icon_facebook"></div> 
                   <div class="b-networks__icon b-networks__icon_google"></div> 
                   <div class="b-networks__icon b-networks__icon_small  b-networks__icon_vimeo"></div> 
                   <div class="b-networks__icon b-networks__icon_small  b-networks__icon_youtube"></div> 
                   <div class="b-networks__icon b-networks__icon_small  b-networks__icon_flickr"></div> 
                   <div class="b-networks__icon b-networks__icon_small  b-networks__icon_instagram"></div> 
                   <div class="b-networks__icon b-networks__icon_small  b-networks__icon_rss"></div> 
               </div>


.b-networks__icon
{
    background:url("../img/social.png") 0 0;
    width:30px;
    height:30px;
    display: inline-block;
    margin-top:10px;
    margin-right:10px;
}

.b-networks__icon_small
{
    width:16px;
    height:16px;
    margin-right:5px;
}

.b-networks__icon_twitter
{
    background-position:0 0;
}

.b-networks__icon_facebook
{
    background-position: -40px 0;
}

.b-networks__icon_google
{
    background-position:-80px 0;
}

.b-networks__icon_vimeo
{
    background-position:0 -38px;
}

.b-networks__icon_youtube
{
    background-position: -23px -38px;
}

.b-networks__icon_flickr
{
    background-position: -46px -38px;
}

.b-networks__icon_instagram
{
    background-position: -69px -38px;
}

.b-networks__icon_rss
{
    background-position: -92px -38px;
}


Малые иконки от «стандартных» отличаются только модификатором, задающим размер.

Footer logo


Для лого в футере странице воспользуемся уже готовым блоком b-logo. Вставим данный блок внутрь элемента, который будет отформатирован с помощью float:right;

<div class="b-footer-logo">
                    <div class="b-footer-logo__img">
                        <div class="b-logo">
                            <a href="#"><img class="b-logo__img" src="img/fooLogo.png"/></a>
                        </div>
                    </div>
                    <div class="b-footer-logo__copyright">Copyright  2012 Whitesquare. A <a href="#" class="b-link b-link_small b-link_white">pcklab</a> creation
                    </div>
                </div>


.b-footer__logo
{
    float:right;
    margin-top:23px;
    margin-right:40px;
}

.b-footer-logo__img
{
    float:right;
}

.b-footer-logo__copyright
{
    clear:right;
}

.b-link_small
{
    font-size:10px;    
}

.b-footer-logo__copyright
{
    font-size:10px;
    color:#dbdbdb;
}


Подведем итог


В данном обучающем посте мной была поставлена задача показать, что использование методологий (таких как БЭМ) позволяет упростить разработку веб-страниц за счет «единого словаря терминологий» и единой структуры страницы.
Также, данный пост является дополнением моего комментария (в начале поста) в котором я говорил о том, почему использовать стили на id — есть bad practices.

Соответственно, ссылка на git-pages и github:
xnimorz.github.io/ex-habr
github.com/xnimorz/ex-habr

Благодарю за внимание!
Никита Мостовой @xnim
карма
26,0
рейтинг 20,8
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (172)

  • +8
    Вот таких туториалов и не хватает, ИМХО, чтобы распространить БЭМ. Спасибо.
    • +17
      Замечу, что мне очень сильно не нравится стиль описания классов вида: .my-super-main-list__item, .b-footer-logo__copyright. То есть, идея БЭМ мне нравится, а вот реализация — нет.
      • 0
        В БЭМ настраивается стиль. По хорошему, надо писать сразу в bemjson/bemhtml/css/js, из которых уже собирается конечная страница. И в таком случае, можно настроить все эти разделители.
        • +18
          Суть не в разделителях.

          Суть вот в таких конструкциях: class="b-link b-link_white b-link_block b-link_undecorate" (из примера в статье).

          Чем это, по существу, отличается от style="color: #fff; display: block; text-decoration: none;"?

          • +2
            Специфичностью.

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

            • +13
              ИМХО, специфичность здесь ни при чём.

              Проблема здесь в том, что эти модификаторы слишком низкоуровневые и действительно эквивалентны inline-стилям, а значит не нужны.

              Гораздо лучше было бы модификаторы делать более высокоуровневые — например, b-link_primary, b-link_secondary, b-link_inverted-background в которых стиль ссылок соответствует семантике, а не деталям реализации.

              Хороший тест для проверки этого свойства — это придумать хотя бы 2 различные реализации модификатора. Для b-link_primary их бесчисленное множество, в зависимости от стиля сайта. Для b-link_white или b-link_undecorate — только одна.
      • +4
        БЭМ — это методология не более, а сокращение кода решается с помощью препроцессоров.

        Например вот такую конструкцию:

        div.b-footer__logo
            div.&__img
        


        Можно транслировать в:

        <div class="b-footer__logo">
              <div class="b-footer__logo__img">
                        ....
              </div>
        </div>
        


        Из минусов:
        — написание собственного препроцессора
        — усложняется поиск элемента грепом и его автоматическая замена
        — требуется поддержка синтаксиса в редакторах
      • +1
        Никому это не нравится, поэтому в bem-tools или enb html генерируется из шаблонов, а при написании стилей используются препроцессоры. Ну и идея длинных имён в том, что с одного взгляда понятно, к какому блоку принадлежит элемент или модификатор. И как сделать лучше лично я еще не придумал.
  • +2
    БЭМ — это интересная технология, но достаточно сложная в описании (при всей ее внутренней простоте). До сих помню первый вопрос из зала на Я.Субботнике в Минске после доклада по БЭМ: «Я так и не понял, так что такое БЭМ?»
    • +1
      Конечно, чувак про сео был :)
      • 0
        «Честный веб-мастер» который? :)
  • 0
    БЭМ предполагает уход от каскадных стилей (типа div .someClass li)

    Будет ли в БЭМ считаться исключением такой вариант, когда нужно при наведении курсором на блок изменить свойства элемента?
    .block:hover .block__element { /* ... */ }
    
    • +1
      Если говорить вкратце, то основная идея БЭМ — это полный отказ от каскадов и любых цепочек классов.

      Однако, как отмечают в яндексе: «Не обязательно использовать БЭМ ровно в том виде, в котором он предлагается».
      Соответственно, здесь вопрос относится к тому — какое соглашение принято в Вашей компании (либо лично Вами)
      • 0
        Полного отказа от каскада нельзя избежать. Каскад нужен, если задан модификатор у блока и нужно менять внешний вид/поведение у вложенных элементов, как в примере выше.

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

        При такой структуре

        block_theme_blue
        another-block
        block

        по каскаду будут затронуты так же элементы внутреннего вложенного блока, что скорее всего не предполагалось при разработке.
    • –2
      Зачем исключения?

      .block__element:hover { }
      • +2
        В таком случае свойства не изменятся для братьев.
        • –1
          Так и в оригинальном коде они (кто бы они ни были) не изменятся.
          • +2
            Идея заключалось в том, чтобы при наведении курсором на блок .block изменялись свойства для всех его потомков .block__element.
            • –7
              У меня для вас хорошие новости. Они и будут изменяться. Потомки. Все.
              • +1
                Будут, но не одновременно.
              • +1
                Допустим мне надо при наведении курсора на блок изменить цвет всех заголовков в данном блоке, что вы предлагаете?
    • 0
      Да нет, нормальная практика. Когда навешивается модификатор, вы же не будете добавлять модификатор на все элементы? Суть в независимости разных блоков.
    • +2
      Я спокойно отношусь к использованию каскада внутри блока. Но нетерпим к межблочному каскаду, либо когда пишут каскад ради каскада (даже если вы не пишете стили по БЭМ), т.е.

      .block .block__text {}
      

      терпимо, а

      .block .link {}
      
      или
      .block .block__content .block__item .block__text {}
      

      ужасно.

      Даже в первом случае у нас в будущем могут быть проблемы с этим блоком при внесении изменений, но часто проще и быстрее делать именно так.
  • НЛО прилетело и опубликовало эту надпись здесь
    • +3
      Да вы хитрец!
      Именно для таких вещей и был разработан БЭМ, чтобы вместо этого ада —
       .menu {
          > a {
            &.active {
              background: blue;
            }
          }
        }
      


      Было:
      .b-menu-link-active
      {
              background: blue;
      }
      
      
      • НЛО прилетело и опубликовало эту надпись здесь
        • +2
          Вы опять идете на каскад. Идея, сама СУТЬ БЭМа — уйти от каскада. Этот код переписывается и Вы освобождаетесь от каскада.
          В БЭМ вы переплачиваете за размер «букоф», выигрывая на этапе отрисовки веб-страниц: использование классов БЕЗ каскада позволяет браузерам быстрее применять стили -> пользователь быстрее получает запрашиваемую страницу.
          • НЛО прилетело и опубликовало эту надпись здесь
            • –1
              БЭМ — это как раз про разделение на модули, так что классы не идут лапшой.
          • 0
            Ну, мне кажется, тут вы лукавите. Если уйти от каскада, то каждый новый блок должен быть со стандартным шрифтом (Times New Roman чаще всего), стандартным размером, станартным box-sizing и т.п.

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

            a {
                text-decoration: none;
            }
            
            — нормально (если вы хотите отказаться от подчёркиваний ссылок во всём проекте… ну и «порадовать» сами_знаете_кого),
            a {
                text-decoration: none;
                padding: 40px;
                background-color: black;
                color: white;
            }
            
            — плохо, т.к. существует почти 100%-ная вероятность, что вам понадобятся обычные текстовые ссылки без паддингов и фонов.

            Т.е. если использовать каскад для расширения, то никакие БЭМ не нужны:
            .panel {
                display: block;
            }
            .panel-sm {
                font-size: 12px;
                padding: 20px;
            }
            .panel-md {
                font-size: 14px;
            }
            .panel-dark {
                background-color: #444;
                color: #ccc;
            }
            .panel-dark a {
                color: #fff;
            }
            


            <div class="panel panel-sm panel-dark">...</div>
            


            Имхо, правильный каскад с миксинами намного более удобен и гибок.
        • +3
          .b-menu {
            margin: 10px;
            position: relative;
            transition: all .5s;
            color: green;
          
            &-link {
              position: relative;
              transition: all .5s;
              color: green;
          
              &-active {
                position: relative;
                transition: all .5s;
                color: green;
              }
            }
          }
          
        • +1
          Ваш пример в стайлусе:
          .b-menu
            margin: 10px;
            position: relative;
            transition: all .5s;
            color: green;
          
            &__link 
              position: relative;
              transition: all .5s;
              color: green;
          
              &_active
                position: relative;
                transition: all .5s;
                color: green;
          
          • 0
            Тоже так по началу писал, но потом отказаля от этой идеи, т.к. в файлах с большой вложенностью блоков ориентироваться невозможно, да найти нужный класс не зная проект весьма сложно.
            • 0
              В листинге ведь максимальная вложенность блоков: здесь и Б и Э и М. Хорошо, можно добавить ещё медиавыражение. Глобальный поиск возможен только по блоку, конечно, но я никогда не сталкивался с проектами, где это было бы проблемой из-за количества элементов у блока.
              • 0
                У эллементов тоже могут быть модификаторы.
                • 0
                  Александр, если под элементами вы сейчас имеете в виду блоки (ведь только так есть противоречия моему комментарию), то действительно — плюс одна вложенность. Но в таком случае добавляется прямой каскад вместо независимого элемента с модификатором &__link_vertical:
                  &_vertical &__link 
                      color: pink;
                  
            • 0
              Если разбивать файлы по блокам на файловой системе, то эта проблема становится не такой большой.
  • +13
    Поклонники БЭМа часто забывают упомянуть, что эта методика оправдывает себя только на очень крупных проектах. Типа Яндес.Маркета. Для сферического в вакууме сайта-визитки, интернет-магазина средней руки или админки БЭМ — излишество. К тому же автор поста зачем-то учит вредному: писать БЭМ код руками, это все равно что программировать простенькое приложение на ассемблере, в 99% случаев неудобства перекрывают преимущества. БЭМ раскрывает себя, когда html и CSS пишутся вместе при помощи встроенных средств. В том же виде, который приводится в статье — это излишне и трудно читается <sarcasm>как раз то, что нужно начинающему верстальщику</sarcasm>.
    Технологии нужны, чтобы облегчать людям жизнь, а не следовать им как догме, повинуясь реальным или надуманным авторитетам. Для приведенного шаблона идеальный набор инструментов — немного перепиленный Twitter Bootstrap или просто хорошая сетка + normalize.css. Не надо учить людей забивать гвозди микроскопом.
    • –1
      Во-первых, существуют компании, которые при написании веб-страниц пользуются методологией, но не пользуются инструментами bemjson и т.п.

      Затем, как подчеркивал в статье — БЭМ используется для сайтов, которые имеют >20-30 уникальных страниц. Когда блоки могут повторяться и т.п.

      • +5
        Сайты, которые имеют > 20-30 уникальных страниц, прекрасно себя чувствуют и без БЭМ. И блоки можно повторно использовать применяя существующие практики и не прибегая к помощи БЭМ.

        Применять или не применять БЭМ — это выбор компании (или группы разработчиков). Нельзя говорить, что это, более «хороший» (или, по крайней мере, структурированный) подход. Это ваше субъективное мнение.

        В остальном, для желающих изучить и применять БЭМ, хорошая статья.
        • 0
          Вы часто брали старую верстку в проектах, где «полностью переделывался дизайн»?
          Допустим пришел заказчик и заказал у вас новую версию сайта.
          • +7
            Старую верстку в новом дизайне, при условии что она сделано нормально, использую только частично и только в тех местах, где новый дизайн предусматривает схожие элементы со старым дизайном. Чем вам БЭМ поможет при новом дизайне?

            Но давайте посмотрим на другой вариант. Взять тот же Twitter Bootstrap (просто как пример). Если вы его внедряли в проект (заказанный на полный редизайн), вы в нем сильно что-то меняли? Вот вам пример хорошей верстки не по БЭМ, с большим количеством реюзабельных блоков. И применять его можно для сайтов с > 20 страниц очень даже запросто.

            Я не отрицаю использование БЭМ. Если вам он подходит, то хорошо. Но говорить, что это «более хороший подход к верстке» — это субъективное мнение.
            • –3
              Я не увидел ответа на свой вопрос.
              • 0
                Как не увидели? Я же написал, что частично могу использовать старую верстку, при условии, что она выполнена нормально и при условии, что новый дизайн содержит схожие элементы со старым дизайном.
                Если это не ответ на ваш вопрос, то значит я не правильно понял ваш вопрос.
        • 0
          Если Вы приходите в компанию, где работают без БЭМ и их продуктом является таки веб-сервис, то у них почти всегда есть концепция построения проекта. Иначе держать всю структуру просто-таки невозможно.
          • +1
            Вот тут полностью согласен. Концепция построения проекта обязана быть. Иначе хаос. И если это БЭМ, то значит, по каким то причинам, он подходит компании. Но БЭМ — это очередная методология и она не самая лучшая, но, стоит отметить, и не самая худшая.
            • +2
              а какие методологии, похожие на БЭМ, вы ещё подразумеваете в сравнении?
              • 0
                Я не правильно применил термин «методология». Более правильно было бы выразиться — «техники верстки» (а статья именно о верстке). Я понимаю, что БЭМ шире, чем просто верстка.

                И я хотел сказать, что, как минимум, существуют SMACSS и OOCSS. Лично для меня (я не говорю, что это более хороший подход) больше подходит техника OOCSS, которая имеет схожие черты с вашим БЭМ, но которая не подталкивает давать классы практически всем элементам. Я просто не вижу необходимости настолько усложнять процесс верстки (ИМХО).

                • +2
                  Зачем давать классы всем элементам:
                  clubs.ya.ru/bem/338
      • +3
        Повторюсь, без описания основ работы с БЭМ окружением, ваш пост выглядит как: «Вот вам бассейн, ребята. А будете себя хорошо вести еще и воды нальем, потом как-нибудь». То есть по сути ваш пост вреден, поскольку не дает понимания общей картины для верстальщика.
        • 0
          Не согласен, это как раз первый шаг в понимании и начало освоения БЭМ как методологии. Я CSS 2 года писал в терминах БЭМ, и никому это фатальных неудобств не доставляло. А для меня и других верстальщиков было удобно разговаривать на одном языке, поддерживать вёрстку друг друга и свободно взаимодействовать.
    • 0
      Я тоже так думал несколько лет назад.
  • +2
    Ну вот я сколько не пробовал — так и не понял в чем его «фишка» по сравнению с тем-же XSLT или любым другим шаблонизатором.

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

    Плюсы те-же:
    • изменили блок — поменялось везде
    • иерархия блоков
    • зависимости
    • реюзабельность блоков
    • возможность иметь библиотеку блоков

    Ну и т.д.

    И не надо ничего описывать в json-ах — все внутри блоков, если блок состоит из других блоков — то они так-же соберутся при вызове основного.

    А шаблонизатор можно применять как к html, так и к js и css — главное правильно испольозвать наименование — и все.

    Так можно делать свои контролы аля select2 — в шаблоне всего-лишь что-то наподобие <% include /blocks/customSelect %>, а шаблонизатор сам поймет что сюда надо засунуть /blocks/customSelect/body.tpl и сгенерирует для сборщика, что на данной странице в js надо добавить /blocks/customSelect/body.js, а в css /blocks/customSelect/body.css.

    Отказ от наследования классов с моей точки зрения ужасен — отказываться в угоду скорости можно на проектах уровня yandex.market, а в обычных, коих 90% каков смысл отходить от столь удобного инструмента как каскадирование CSS?

    Если Вы применяете профессионально БЭМ, и Вам не сложно — объясните — чем он лучше? И в чем все-таки его главный козырь?

    Может я действительно не понимаю его сути?
    • +2
      И как вас защитит XJST, когда возникают проблемы со специфичностью? Например, стили «.sidebar ul li» начнёт конфликтовать со вторым списком, когда вы его добавите в сайдбар? Придётся перевёрстывать. Или когда нужно переместить блок, содержащийся в ul, куда-нибудь ещё? Независимые блоки позволят избавиться от такой лишней работы — они могут использоваться в любом контексте.
      • 0
        Ну, во-первых данный стиль именования можно заюзать на любом шаблонизаторе, в БЭМ это не упирается.

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

        Но самое главное — незаисимвые блоки != БЭМ, их можно делать с моей точки зрения абсолютно на любом шаблонизаторе, о чем я выше и написал.
        • 0
          Почитайте историю БЭМ.
          БЭМ == Независимые блоки.

          Изначальное название БЭМ: Верстка на независимых блоках (точное название не припомню, но суть эта)
          • +1
            Вот самое первое описание:
            vitaly.harisov.name/independent-blocks.html

            Вот про АНБ уже в клубе БЭМ:
            clubs.ya.ru/bem/43
            • 0
              Мне кажется, в 2006 (или 2005?) году статья на вашем сайте выглядела немного иначе. Про с- там кажется ничего не было, а было про h- (holster).
          • 0
            Не слышали разницу понятий «необходимое условие» и «достаточное условие»?
        • –3
          Ваш комментарий звучит как: «БЭМ можно использовать везде, только в БЭМ это не упирается»…
          • 0
            Ниже ответ был дан xnim — мое заблуждение было в том, что я считал БЭМ прежде всего шаблонизатором со своей методологией, а это просто методология.
            • 0
              Да, увидел уже потом.
    • +2
      Вы сейчас говорите о шаблонизаторах. Однако БЭМ это не шаблонизатор. Это методология написания html\css кода.
      Это такая же методология, как, например, SMACSS или OOCSS (весьма популярные технологии разработки html\css кода)

      Многие компании используют XSLT шаблонизатор + БЭМ методологию.

      БЭМ описывает то, как организовывать структуру HTML кода, чтобы добиться ее переносимости и плавного расширения.

      В проектах без БЭМ (а если быть более точным — без методологии разработки), зачастую случается следующего рода проблема — создан сайт. Затем появляется необходимость поправить расположение блока меню, блок регистрации поменять местами с лого. Используя БЭМ вы отлично знаете, что, чтобы поменять местами достаточно сменить стили у элементов блока хедер (если говорить о примере в статье) Если необходимо сменить цвет — Вам не надо лезть в код и менять что-то там. Достаточно лишь добавить нужный модификатор. Код становится гибким.

      Отказ от наследования…
      В статье писал, что может случиться, если Вы в блок добавите вложенный элемент с тем же названием, что и для тех, кои были раньше. БЭМ это учитывает, а в проекте построенном на каскаде может потребоваться переписать код (пример есть в статье)

      • 0
        Хм, я всегда почему-то считал, что БЭМ это все-таки инструмент, т.е. да, методология, но в контексте конкретных инструментов для нее. Возможно в этом причина моего непонимания.

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

        Естественно если писать body div то это тихий ужас :-D

        Ну а если применять единое устаявшееся правило именования, то,, например я не вижу конфликтов.
        • 0
          Инструменты для БЭМ были разработаны много позже методологии.

          БЭМ предлагает правила именования. В этом его прелесть — разработчикам не нужно «искать то какой принцип исопльзовал предыдущий разработчик при именовании»

          Я думаю, Вам будет очень интересна дискуссия в статье здесь — marow.net/archives/161

          Для данного треда вынесу цитату:
          «Каждый их разработчиков, рано или поздно приходит к чему-то подобному БЭМу»

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

          Также добавлю, если посмотреть на SMACSS — он очень похож на БЭМ.
          • 0
            Спасибо огромное за статью — действительно более-менее понятно стало.
        • +1
          Еще исходя из опыта своего вот что странное вырисовывается при разработке сайта.

          «Тот самый крутой плюс ради чего все и затевалось» — реюзабельности — в сайтах нет.
          Практически. ИМХО.

          Если не брать в расчет контролы (типа автоподборщика, календариков, поиска и т.д.).

          Обычно сайты живут очень простой жизнью — они пишутся под компанию на определнном этапе развития ее бизнеса, они решают потребности в данный конкретный момент времени.

          И да — чуть-чуть допиливаются до тех пор, пока компанию не шагнет на ступеньку выше (ну или не умрет).

          Если она шагнула — обычно идет полное переписывание сайта, т.к. адаптация старого к новому развившемуся бизнесу гораздо сложнее.
          Плюс убивается такой заяц, как редизайн.

          Я работал на многих проектах, как для больших компаний, так и для средних и мелких и везде это повторялось.

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

          У всех так? Или мне только так везло? Стоит заморачиваться на сайтах с версткой независимыми блоками, если не брать в расчет контролы?
          • 0
            Я думаю, что стоит. Яндекс (могу ошибаться) никогда кардинально не менял всю верстку. Используется как старая, так и новая. (по мере наработки — спасибо независимым блокам)

            Далее, такие сайты как lenta.ru — постоянно дорабатывают сайт -> без независимости постоянно бы вставал вопрос о «переписки»

            hh.ru -использует БЭМ + XSLT — аналогично использование наработок позволяет использовать заново блоки -> сокращается время разработки.
            • 0
              Ну я эти сайты подразумевал под «веб-проектами» — там — да. Ибо одна и та-же идея, бизнес-модель практически не меняется.
              • 0
                Для сайтов, которых цель — бложик или статика, либо форумы (подобное им) БЭМ не нужен.(читать как не является нужным) Так как такие сайты создаются один раз и следующий раз изменятся только при редизайне.
                • 0
                  Ок, ну а сайты компаний?
                  Я про них как раз писал.

                  Они тоже обычно создаются один раз, т.к. создаются под конкретную бизнес-модель и точно так-же редко меняются до полного редизайна, который обычно заключается в полном обновлении всего и вся, вклшючая сервер-сайд.
                  • 0
                    В таком случае разработчику стоит решить использовать БЭМ или нет. Так как острой необходимости здесь не будет.

                    Единственная вещь, которую можно записать в «стоит» — это следование единому стилю оформлению
  • 0
    Для независимости блоков делаем классы без каскада, хорошо, но почему для элементов нельзя применять каскад от класса блока, ведь они уже зависимы от своего блока? И модификаторы также.
  • 0
    Независимость зависима от решений, что считать блоками?
    Приводится пример: «с БЭМ легко перенести блок из левой колонки в правую». А что если этот «блок» при проектировании считался элементом для колонки? Значит элементов в обще не должно быть, каждый тег — независимый блок. Каждому тегу свой класс?

    • 0
      Прочитайте, пожалуйста, статью. Я привожу пример и рассказываю, что же такое блоки и что такое элементы
      • 0
        Имя пользователя используется в разных виджетах хабра, в статьях, комментах… Но вы посчитали его элементом, я его бы делал блоком.
        • 0
          Я его выделил как элемент внутри блока. Сам по себе он может быть также блоком.
          Яркий пример — верстка меню — есть блок меню, который включает элементы — пункты меню, которые включают в себя блок — ссылка
          • 0
            Рискну спросить: если мы хотим сделать вложенный блок, его нужно засовывать в элемент?
            • 0
              Строго следуя БЭМ — да
            • +2
              Нет, её будет отдельный блок, который можно использовать где угодно.
          • 0
            У элемента могут быть элементы?
            • 0
              Нет
  • 0
    (извиняюсь, не туда отправил)
  • 0
    Великолепно.
    Очень полезно и нужно!

    Буквально на днях собирался вспомнить, как оно делается, а тут эта статья.
    Спасибо вам, автор!
  • +2
    <div class="b-networks__icon b-networks__icon_small  b-networks__icon_instagram"></div>
    

    Тут даже инлайн стиль короче будет написать чем такую лапшу в коде держать (может даже еще быстрее отработает его браузер чем каскад)
    • +4
      Вы напишите вместо b-networks__icon_small инлайн стиль типа width: 16px. Ок. А потом маленькая иконка станет шириной 15px — и в случае инлайна вас ждет жесткий find + replace all, в одном месте указать width: 15px не получится.
    • 0
      С таким подходом к именованию классов я могу вообще в верстку не заглядывать — работать только с css стилями, впрочем так и поступаю, разрабатывая универсальные html блоки с классами, которые копируются из проекта в проект практически не в тронутом виде.
  • +5
    Любая методология хороша до тех пор, пока ею не заинтересовались фанбои или какая-нибудь контора, желающая подчеркнуть свой авторитет (что вполне равнозначно).

    Любой нормальный верстальщик в те или иные моменты пользуется каким-либо из средств, которые здесь перечислены для своих нужд.
    А какими-то — очень часто. Например, независимыми блоками. Скажем, я видел (и сам пару раз так делал — способ-то очень логичный) как при добавлении новой порции функций к сайту, который разрабатывали совсем другие люди, новые блоки верстались совершенно отдельно, в пустой странице, с отдельными стилями и т.п., но с обязательной каскадностью (препроцессоры там не использовались, но всем селекторам было просто добавлен в начале id родительского блока, правило для самого контейнера блока выполняло при этом функцию reset-а, экранируя содержимое блока от стилей сайта и управляя его позиционированием). Дальше программисту оставалось только подключить стиль и вставить код блока в шаблон, заменив текст переменными. Верстальщик при этом вообще ни разу не взглянул на верстку остального сайта.

    И никому не приходило в голову называть это особым словом и пропагандировать это в сети, люди просто работали так, как им удобно в конкретный момент.
  • –1
    Т.е. если в курпном проекте вдруг появятся два блока с одинаковыми названиями классов, но разными стилями оформления, то вся эта методология коту под хвост и нужно добавлять модификаторы и переписывать стили одному из блоков? Или я что-то не так понял.
    • 0
      У разных блоков разные имена. Если же появляется элемент интерфейса, совсем немного отличающийся от уже существующего, то можно взять готовый блок и добавить ему модификатор, всё верно.
      • 0
        В том-то и дело, что БЭМ, добавляя каждому тегу много презентационных классов и усложняя их названия, не дает никаких преимуществ и независимости блоку. Потому-что нет гарантии что этот класс уже где-то не используется и ваш стиль не сломает верстку в другом месте.
        Я решил познакомиться с этой методологией, потомучто все говорят о независимости блоков, но я этого не увидел к сожалению.
        Единственно верным методом для меня осталась семантическая верстка с одним классом для создания пространства имен. Как в примере ниже комментарий.
        • +1
          По сути блок — это и есть пространство имён. В этом пространстве задаются модификаторы и могут быть вложены элементы.
          Проблема одноимённых пространств имён есть всегда.
          • 0
            Проблема одноимённых пространств имён есть всегда.

            Так пропаганда идет что БЭМ решает эту проблему, а на самом деле нет, лишь усложняет верстку.
            • 0
              Возьмём блок a, у него есть элемент header. И ещё блок b, у него тоже есть элемент header.

              Получится такой css:

              .a {}
                  .a__header {}
              
              .b {}
                  .b__header {}
              


              У каждого блока элемент header может выглядеть абсолютно по-разному, но иметь одинаковое название.
              • 0
                Разве это не каскадом?
                Ладно, не будем начинать священную войну. Я свой выбор сделал и для себя решил самообманом не заниматься.
                Единственное что может решить поблему независимости — это класс со случайным названием в 256 бит вида <a class='sjica3c...' href=..., но это уже хардкор.
                • +1
                  БЭМ — это не только про CSS, это ещё и про JS, шаблонизацию, файловую структуру и про сборку проекта, поэтому очень удобно оперировать именно такими сущностями.

                  А если сделать каскад:
                  .a .header {}
                  

                  то получится, что это селектор на блок header, который вложен в блок a. Но так писать не стоит, потому что теряется смысл независимости блоков.
                • 0
                  мы пробовали такое решение — не взлетело
                • +2
                  Где вы увидели каскад в классах .a__header и .b__header?
                  • 0
                    Каскад тут на месте, только он вынесен в семантику классов.
        • +2
          В том-то и дело, что БЭМ, добавляя каждому тегу много презентационных классов и усложняя их названия, не дает никаких преимуществ и независимости блоку.
          Где вы увидели в БЭМ рекомендацию добавлять презентационные классы?

          Имена сущностям надо подбирать так, чтобы они отражали суть, а не то, как оно выглядит.
    • 0
      Особенно такой ужас начнет плодиться при росте последователей БЭМ. Раньше при интеграции проектов могли нарваться на одинаковый класс .link, а потом .b-link. А если g-класс разный? Ууу…
  • +4
    Поддерживаю комментарий выше, этот БЕМ похож на Inline-style, только на классах, не вижу смысла в таком количестве классов, если тут все можно решить просто семантической версткой:

    Чем это лучше обычной верстки?

    <footer>
    <div class="b-twitter">
               <h3> TWITTER FEED</h3>
               <time>22 oct</time>
               <p>In ultricies pellentesque massa a porta. Aliquam ipsum enim, hendrerit ut porta nec, ullamcorper et nulla. In eget mi dui, sit amet scelerisque nunc. </p>
    </div>
    </footer>
    • 0
      Яндекс проводил тестирование, что классы при рендере работают быстрее чем ID.
      Чтобы уйти от ID они начали пользоваться классами, классов стало много и чтобы привести в порядок кашу классов придумали БЭМ.

      .button .inactive{ } работает медленнее чем .button{} .button__inactive{}, каскады в правилах CSS тоже медленнее рендерятся чем разные правила.

      В ответ на ваш вопрос производительностью рендера страницы.

      Для себя лично выбрал SASS: для блока указывается id внутри блока каскад, лично для меня это более наглядно и просто в использовании.
      • +2
        Сомнительная производительность, при таком подходе мы раздуваем и html и css код, что уменьшает отклик еще при загрузке сайта.

        Да и экономить в производительности CSS, ну не знаю. Inline наверное будет еще быстрей и даже короче :)
        • 0
          Вот и у меня напросился тот же самый вывод.
          Я люблю короткие и лаконичные решения. Compass + минимальный HTML как раз то что мне подходит.
      • +2
        Думается мне, что разница в производительности CSS мизерна и даже не стоит обсуждения в сравнении с тем, что пожирает JS. Исключая разве что какие-то особо клинические случаи.

        Это напоминает баянистые разговоры про якобы медленность селектора *, поутихшие вот только недавно. Угу, поставить звездочку это значит медленно, а перечислить в файле reset.css все возможные html-теги через запятую — это окей, это хорошо.
        • 0
          clubs.ya.ru/bem/338

          Погоняйте в своих браузерах приведённые в тексте тесты.
          • 0
            Усреднил по нескольким попыткам:
            FF 25: 130/220 мс соответственно
            Chrome 31: 210/240 мс
            IE 10: 240/250 мс

            То есть в абсолютном выражении на сегодняшний день разница невелика. Но дело даже не в этом.
            Главное в том, что ваш тест — тот самый искусственный клинический случай. Стили в нём нарочно написаны предельно неоптимально, а 30 тысяч дивов на практике не встречается никогда.
            Например, результаты поиска на ebay (причем я специально включил максимальное число товаров на страницу) имеют DOM с 7-8к узлов. Развесистая статья на smashingmagazine с двумя сотнями комментариев ~6к.
            Время ответа сервера, загрузки картинок и обработки JS просто проглотит время обработки CSS.
            • +2
              Тут есть некоторое уточнение, пересчет css / перерисовка страницы может происходить более одого раза, причем может происходить сотни раз, особенно это заметно на Single Page Applications.
              И когда у вас перерироска на 100 мисек медленней, чем могла бы быть — это выльется в заметные глазу тормоза UI, причем виной этих тормозов будет — не оптимально написаный css.
              • 0
                Про одностраничные приложения я в общем-то согласен, но ещё раз напоминаю об искусственной переусложненности того теста.
                В реальной жизни цифры меньше в несколько раз. Например, сейчас посмотрел, веб-интерфейс Gmail оперирует 6-9к узлов, в Google Docs около 5к.

                Вот, правда, Яндекс-почта, имея сразу после загрузки ~3к, в процессе хождения по папкам и письмам растет практически неограниченно — мне удалось достигнуть 40к и наверное это не предел (но опять-таки, для этого пришлось совершить действий гораздо больше, чем я делаю в реальной жизни). Наверное, потому у Яндекса и встает проблема CSS-производительности там, где другие её избегают :)
                • +3
                  Время reflow gmail = 60ms, время reflow яндекс почты = 20 ms, время reflow этого топика = 100ms
                  • 0
                    Что и требовалось доказать. Мы специально работали над этим.
                    • 0
                      Хотелось бы увидеть ваш ответ на habrahabr.ru/post/203440/#comment_7028578 и habrahabr.ru/post/203440/#comment_7028034, а не только там где вас похвалили.
                      Насчет Я.Почты — пока выглядит так, что ошибка проектирования решена переусложнением верстки (впрочем, с использованием имевшейся методологии).
                      • 0
                        Я не занимаюсь разработкой ЯПочты, поэтому не могу прокомментировать.
                  • 0
                    20 мс в свежеоткрытом виде?
                    • 0
                      даже после активного ею пользования
    • 0
      Если вам достаточно написать вручную HTML, по-быстрому накидать CSS и не менять регулярно внешний вид страницы, то можно обойтись традиционным подходом.

      Как родилась методология БЭМ и зачем делать всё так сложно — об этом хорошо рассказывает Сергей Бережной в своём докладе на YaC 2011: video.yandex.ru/users/ya-events/view/387/
  • +1
    Объясните логику префикса b-. Я понимаю и одобряю префикс js-, в целом не против префикса g-, но префикс b-… Да он у каждого элемента! Соответственно можно легко отказаться от него, приняв за основу тот факт, что все классы относятся к структуре документа, если не указано иное.
    • +1
      Я думаю, у человека просто привычка. Взгляните на современные open-source библиотеки Яндекса, выполненные по БЭМ — там сложно найти вообще какие бы то ни было префиксы.
    • +1
      Яндекс уже давно отказался от префиксов. Они остались в старом коде. А логика: что типа блок. В отличие от i-хелперов (аналог js-) и прочих.
    • +3
      Префиксы полезны в процессе постепенного перевода сайта с лапши на бэм, гарантированно не пересекаются со старыми классами. Когда всё становится бэм — можно спокойно от них отказаться
  • +2
    Неоспоримое преимущество БЭМ в том виде, каком он описан Яндексом — строгая формализация. Не менее очевидный недостаток — очень громоздкие и избыточные цепочки классов. Поэтому он — удел очень крупных проектов в которых:
    а) крайне важна стандартизуемость
    б) пишутся очень большой командой
    в) активно применяются средства автоматической генерации (писать это врукопашную — полный мазохизм).

    В «обычной жизни» я использую что-то типа лайт-БЭМ-а — принцип тот же, но имена классов гораздо короче и читабельнее. То есть, например, вместо:
    b-slide-list__item
    b-slide-list__item_active
    

    будет что-то вроде
    .slider-item
    .slider-item-active
    
    • +1
      Эти классы не надо писать вручную www.slideshare.net/Alex_Baum/alex-baumgertner-beminsmallprojects, 18 слайд
      • +2
        Наверное, кому-то эта технология подойдет, но мне не понравилось. Я не очень понимаю, зачем тащить страницу вместе с контентом в JSON?
        На мой вкус, в масс-проектах (об уровне Яндекса сейчас не говорю) удобнее и практичнее просто использовать CSS-препроцессоры, а верстать всё же в HTML.
        • +1
          HTML — это ассемблер для веба. :)
          Когда я верстал hunterboat.ru/ — дизайн менялся уже после сдачи макета, но мне не нужно было переколбашивать тонны html и
          вручную разбираться в css-классах.

          И более подробно в статье ru.bem.info/libs/bem-core/1.0.0/bemhtml/rationale/
        • 0
          Многие используют другие шаблонизаторы для генерации html. Я слышал про priv.js, bemtree, jade. Ну и если просто фигачить html-странички, вёрстка со временем очень быстро устареват и поддерживать её в актуальном состоянии становится очень трудно.
  • +4
    Отдельно хотел бы обратить вот на какое преимущество БЭМа, а именно, на примере использования с разными CMS. Довелось мне как-то внедрять верстку на малоизвестную CMS Diem (на базе Symfony 1.4). Дело в том, что там многое завязано на то, что многое можно делать с помощью drag'n'drop в процессе редактирования блоков в интерактивном режиме. Как результат, огромное количество всяких оберток, от которых никуда не деться. Типичный пример:
    <div id="dm_page">
     	<div class="dm_layout"> 
    	<div class="dm_area dm_layout_top" id="dm_area_19"><div class="dm_zones clearfix"><div class="dm_zone"><div class="dm_widgets"><div class="dm_widget main_header"><div class="dm_widget_inner">
      .....
    

    Ужасно, конечно. Но наш верстальщик привык все верстать независимыми блоками. И когда я внедрил его верстку в это безобразие, обнаружил, что все выглядит просто отлично с самого начала! И даже при перетаскивании блоков в режиме интерактивного редактирования ничего нигде не ломалось. При использовании каскадов, все могло бы быть намного сложнее.
  • +3
    Никита, спасибо вам большое за эту статью. Вы — пример для других хабраюзеров. Вы не только написали комментарий к существующей статье, но еще и своей статьёй подробно объяснили эту методологию, объяснив все ее достоинства и недостатки.
    P.S. Странно, что еще никто про uppercase не написал ;)
  • +2
    Касательно БЭМа, его приверженцев и системы минусования (я рискую, но не могу не спросить): «Часто ли вы сталкиваетесь с тем, что негативно отзываясь о технологии авторитетной компании, вам ставят минус в карму, а сами посты или комментарии плюсуются»?

    Это означает, что с вами соглашаются люди, но не любители того, о чем вы отозвались негативно. Это банальное занудство, мол «ты обидел БЭМ», а я тебе наср… у в карму. Очень логично и обоснованно, прямо детский сад какой-то))). Я высказываю свое мнение, обосновываю его, а вы срет… е.

    Чем то это напоминает высказывание из недавнего поста «Вечный торт: интервью с Денисом Крючковым, основателем Хабрахабра»: «Хочешь быть объективным и писать обо всем? Будь готов к тому, что придется многое выворачивать наружу и не всем это понравится. Разумеется, такое далеко не всем нравится. Приходишь к людям и говоришь: «Купите у меня рекламу», а они отвечают: «Нет, мы не станем покупать у тебя рекламу, потому что ты написал вот об этом, а тебя просили этого не делать». Так я довел себя до ручки и продал проект, не успев из него даже уйти.» Точно по тому же принципу вас и минусуют.

    Не пора ли ввести систему обоснования минуса в карму (именно в карму)? И если это банальная обида на то, что вы «обижаете высокотехнологичную методологию», то ограничиваться только этим обоснованием. Не могут все быть «хомячками и пресмыкающимися».
  • +2
    Никита,

    большое тебе спасибо за статью! Очень полезная и интересная!!!

    Будет очень круто, если ты напишешь про нее пост со ссылкой в нашем БЭМ-клубе на Я.Ру и в группе на Фейсбуке. Написали в твиттер, но в эти места лучше б ты сам (пусть знают в лицо автора!).

    Если аккаунтов нет, то дай знать, я опубликую.
    • +1
      спасибо, что запостил :)
  • +4
    Меня одного в БЭМе смущает, что по названию блока невозможно понять с первого взгляда что же он всё-таки делает?

    <div class="b-networks__icon b-networks__icon_small  b-networks__icon_rss"></div>

    Вместо «сети-рсс» здесь написано: «блок сети с иконкой и блок сети с иконкой маленький и блок сети с иконкой рсс».
    • +3
      В БЭМе?
      Названия блоков придуманы автором статьи, при чем здесь методология?
    • 0
      Это смущает многих. Но это вы описали не самый худший вариант. На главной страницы Яндекса есть и сложнее.
    • +2
      Не путай, пожалуйста, конкретную реализацию у конкретного автора с общей методологией.
      • 0
        Ну я смотрю здесь лица из Яндекса тусуются и никто не против, статья чуть ли не на bem_ru зафичерена — вот я и позволил себе сделать выводы. Ты же понимаешь, что я сейчас не про светлую идею, я про реализацию в умах 90% адептов.
  • +3
    Если придерживаться синтаксиса БЭМ, то у автора можно найти ошибки. Например, в
    .b-networks__icon_small
    потеряно определение модификатора, вместо этого сразу идёт его значение. А должно быть так:
    .b-networks__icon_size_small
    Т.е. название-блока__название-элемента_название-модификатора_значение-модификатора. Сам по началу допускал такую ошибку, поэтому теперь её замечаю :)

    Пруф на оф.сайте:
    Мы используем одно подчёркивание для отделение имени модификатора от имени блока и ещё одно подчёркивание для отделения значения модификатора от его имени.


    В этом плане он похож на предыдущий пост, ссылку на который автор привёл в самом начале — вроде бы начинание похвальное, подробная инструкция для новичков, но написано изначально неверно — тут мелочи в синтаксисе, в предыдущей статье некоторые теги не совпадают с указанным доктайпом и т.д.
  • +6
    Плохо что автор как образец показывает классы вида block__element__element (b-slider-case-element__number) и модификаторы не в формате modifer-value (b-slider-case-element__number_active).

    Это самая главная проблема с из-за которой идёт неприятие bem у других — им кажется что bem — это «длинные бездумные классы повторяющие dom-вложенность». Это не так. По bem нельзя писать block__element__element, @harisov негодует: twitter.com/harisov/status/403421669974618112

    Ещё конечно стоило написать о миксовании, различных видах модификации (от контента и переопределением), рассказать про абстрактные блоки, и если уже пошли говорить за префиксы и упомянули никогда не существовавший в пределах Яндекса префикс js-, то стоит написать и про префиксы i- как минимум, а заодно можно и про l-, h- и т.д.

    Напишу статью-ответ, где разберу типичные ошибки с bem.
  • +4
    Про BEM написано хорошо, а вот сама верстка очень неаккуратная и со спорными моментами. Вот некоторые замечания:

    — Возникает вопрос о xml-валидности кода и общей стандартизации: почему-то часть одиночных тегов написана с закрывающим слешем, а другая часть без. Я за то, чтобы везде писать /.

    — Тег meta написан в коротком html5-стиле, а link по-старому.

    — Очень прыгают стили и верстка: лишние пустые строчки, пробелы после двоеточия в css, вперемешку tab и пробелы, двойные пробелы и т.п.

    — С фоном для .b-page кажется фейл: background-color не применится к этому блоку, так как идущий дальше background вернет это свойство к значению по-умолчанию. Пример на jsfiddle. Уже писал про использование общего свойства background и font в комментарии к посту Mirantus

    — Очень удивило, что кнопка GO сделана div'ом и все это не находится в form.

    — Излишнее количество классов для ссылок в основном меню. Также, семантически правильно считается оформлять меню в виде списка ul>li.

    — Нет ни слова о проблеме с floating-элементами и в верстке это не учитывается.

    Очень похоже, что верстка нигде не тестировалась, а писалась по-быстрому прямо в хабраредакторе :) Поэтому, есть большие сомнения, что в готовом виде она будет работать и выглядеть как на картинке (и это даже забыв про IE). Мне кажется, что для обучающих статей, рассчитанных на новичков, особенно важно уделять внимание деталям.

  • +1
    js- (JavaScript) префикс для выделения элементов для селекторов js
    Так делать не нужно. По БЭМ js это одна из технологий блока и скрипты пишутся в рамках уже имеющихся блоков, а не плодятся другие.
  • +4
    b-link b-link_menu b-link_menu_active

    это лучше писать как b-link b-menu__link b-menu__link_active_yes

    Т.е. мы не расширяем блок b-link знанием про меню, а наоборот в рамках меню делаем элемент __link. Это более специфично получается.

    Вообще про миксы стоит посмотреть доклад Кира:
    tech.yandex.ru/events/yasubbotnik/msk-sep-2012/talks/327/
    • 0
      Благодарю!
      О данном (не знаю, как точно определить..) ходе не предполагал.
  • 0
    Может, очевидность спрошу, но ни в статье ни в комментариях не нашел ответа.

    Почему независимость блоков не достигается родным CSS-селектором ">"? В чем выигрыш БЭМа по сравнению с конструкцией
    .block > .element { }
    
    ?
    • 0
      1) Этот селектор медленный
      2) Элемент не обязательно должен быть прямым потомком блока => такой css не заработает (например элементы вложены друг в друга.)
      • 0
        1) Ощутимо медленный по сравнению с прочими тормозами отрисовки страницы? Может, есть ссылки на статьи по теме?
        2) Как я понял, элемент не содержит других элементов, если не является блоком. А если даже вложен, то чем плохи решения:
        .block > .subblock { }
        .subblock > .subelement { }
        
        или
        .block > .subblock  { 
          > .subelement { }
        }
        
        ?

        Первое решение — и без вложенности и подчеркивает независимость блоков. Почти БЭМ, только в другой записи.
        • 0
          Элемент блока не обязательно вложен в блок.
          На уровне DOM-дерева элемент может содержать в себе все, что угодно — и другие блоки, и другие элементы.
          <div class="first-block__element"></div>
          <div class="first-block"></div>
          <div class="second-block">
                <div class="second-block__first-element">
                      <div class="second-block__second-element"></div>
                      <div class="some-another-block"></div>
                </div>
          </div>
          


          Автор комментария имел в виду, что элементы не могут содержать в себе элементов на семантическом уровне.
        • +1
          Нам не интересен css, который ломается при малешем изменении DOM дерева, это не имеет ничего общего с концепцией абсолютно независимых блоков — такой css очень дорого поддерживать, потому, что при каждом чихе в HTML все будет разваливаться и прийдется править CSS.
          пример:
          <nav class="menu">
           <a href="#" class="menu__link">test</a>
           <a href="#" class="menu__link">test</a>
           <a href="#" class="menu__link">test</a>
           <a href="#" class="menu__link">test</a>
          </nav>
          

          .menu > .menu__link {
             color: red;
          }
          

          потом мы решили переделать на ul-li
          <ul class="menu">
           <li class="menu__item"><a href="#" class="menu__link">test</a></li>
           <li class="menu__item"><a href="#" class="menu__link">test</a></li>
           <li class="menu__item"><a href="#" class="menu__link">test</a></li>
           <li class="menu__item"><a href="#" class="menu__link">test</a></li>
          </ul>

          вот тут старый css уже поломался
          1) Ощутимо медленный по сравнению с прочими тормозами отрисовки страницы? Может, есть ссылки на статьи по теме?

          developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS?redirectlocale=en-US&redirectslug=CSS%2FWriting_Efficient_CSS
          • –1
            т.е. вас не смущает тот факт, что конструкция <a href=""></a> настолько спецефична и неприменима ни в чем другом, кроме как в ссылках, и по факту вы не сможете без нее организовать ссылки (не стоит только умничать про обработку любого элемента JS'ом) и поэтому вы предлагаете к крайне спецефичной конструкции применить супермегаспецифичный стиль, на случай «Вдруг в будущем откажутся от использования ссылок, а мы будем на коне».

            Более логично в данном случае использовать класс .menu, потому что меню можно на чем угодно реализовать (и это факт) — div. nav, ul, span, да хоть p, а ссылки оставить ссылками

            .menu a {
            color: red;
            }

            Почему нет оператора наследования >? да потому что не факт что ссылки в меню окажутся родственниками в первом колене.

            Ну и по поводу приведенной статьи — вы на полном серьезе отсылаете к статье 13 летней давности для оценки производительности?
            • +1
              Специально для вас пример:
              <ul class="menu">
               <li class="menu__item"><a href="#" class="menu__link">test</a></li>
               <li class="menu__item menu__item_atcive"><span class="menu__link">test</span></li>
               <li class="menu__item"><a href="#" class="menu__link">test</a></li>
               <li class="menu__item"><a href="#" class="menu__link">test</a></li>
              </ul>
              
              • 0
                Вот так можно лаконично описать этот блок в BEMJSON:

                    ({
                        block: 'menu',
                        content: [
                            {
                                elem: 'item',
                                content: {
                                    elem: 'link',
                                    content: 'test',
                                    url: '#'
                                }
                            },
                            {
                                elem: 'item',
                                mods: { active: true },
                                content: {
                                    elem: 'link',
                                    content: 'test',
                                    url: '#'
                                }
                            },
                            {
                                elem: 'item',
                                content: {
                                    elem: 'link',
                                    content: 'test',
                                    url: '#'
                                }
                            },
                            {
                                elem: 'item',
                                content: {
                                    elem: 'link',
                                    content: 'test',
                                    url: '#'
                                }
                            }
                        ]
                
                    })
                


                И, согласно разделению логики представления и данных, сделать соответствующий BEMHTML-шаблон:
                (Понятие предиката в BEMHTML-шаблоне похоже по смыслу на селектор в CSS htmlbook.ru/test/selector)

                
                /**
                * Общий шаблон для блока 'menu'
                */
                block('menu')(
                
                    tag()('ul'),
                
                    elem('item')(
                
                        tag()('li')
                    ),
                
                    elem('link')(
                
                        tag()('a'),
                
                        attrs()(
                            {
                                href: this.ctx.url
                            }
                        )
                    )
                )
                
                
                /** Шаблон для блока 'menu'  с учетом модификатора "активный" у вложенного элемента :
                 *
                 * "если блок содержит элемент 'item' с модификатором 'active',
                 * то установить у блока свойство '_active_item'
                 *
                 * @predicate block('menu').elem('item').elemMod('active', true)
                 *
                 */
                block('menu').elem('item').elemMod('active', true)(
                    /* в моде def (не путать с модификатором, мода -- правило генерации html)
                     * applyNext:
                     * установить свойство шаблона для блока _active_item равное true и
                     * применить следующий шаблон
                     *
                      * */
                    def()(
                            applyNext({_active_item: true}
                        )
                    )
                )
                
                /** Шаблон для блока 'menu' с установленным свойством '_active_item':
                 * для блока со свойством '_active_item' элемент 'link' генерировать через тег 'span'
                 *
                 * @predicate block('menu').match(this._active_item).elem('link').tag()
                 */
                block('menu').match(this._active_item).elem('link').tag()('span')
                
                
                • +3
                  очень лаконично у вас получилось ;)
                  • 0
                    Развернутая структура выглядит немного многословной, но зато наглядно.
                    А BEMHTML согласен, на непривычный взгляд странно выглядит.
                • +1
                  антиреклама на 5 баллов!
                • 0
                  За это инструменты БЭМ и боятся. Лаконично это пишется разве что с Emmet с БЭМ-фильтром, как-нибудь так: .menu>.__item*5>.__link, но поддерживать потом всё равно придется полную версию, конечно.
                  • 0
                    Да, к сожалению, порог входа выше, чем «писать html».
  • 0
    В течении столетий прогрессивное человечество приходило к тому, что для удобного восприятия материала необходимы какие-то правила. Книга делится на страницы, у всех одинаковая структура, текст набирается одним шрифтом, везде одинаковые отступы, материал расположен по сетке. Если есть исключения для акцентирования на чем-то внимания, то они не многочисленны. Внутренние части подчиняются общему. Так построен CSS. Но тут пришел Яндекс и решил, что у его дизайнеров избыток творчества и все эти правила слишком ограничивают. И еще он решил, что блок, взятый неизвестно откуда, не должен подчиняться правилам страницы, на которой находится, а должен быть сам по себе. Так появился БЭМ.

    Не знаю-не знаю, мне кажется, что в идеальном мире будет свойство no-inherit, запрещающее наследование любых свойств от родителя, а БЭМа в идеальном мире не будет.
    • 0
      HTML — это код для машин — браузеров, с каких пор его читаемость для человека стала приоритетной? Т.е то, что вы не можете прочитать код исполняемого файла — вас не сильно смущает, а то, что код — скомпилированного HTML вдруг вас так расстроил :)
      Посмотрите на HTML код Gmail, например ;) Сомневаюсь, что вас до сегодняшнего дня беспокоила читаемость их классов.
      • 0
        Я же не про читаемость кода, а про читаемость сайта. Хорошо, когда на сайте, например, все ссылки одного цвета, тогда пользователь сразу их распознает. Если же дизайнер-верстальщик вдруг захотел сделать в своем блоке какую-нибудь особую няшную ссылку, пусть заслуженно помучается
        • +1
          БЭМ — позволяет писать общие правила так-же легко, как и честные — за это его и любим. И даже у идиального дизайнера есть несколько цветов для ссылок, например главное меню и ссылки в тексте.
  • 0
    Интересно, спасибо за статью, давно слышал про bem и благодаря вашей статье наконец узнал что и как это на деле. Только я бы наверное избегал модификаторов вида *_blue, *_underline и т.п.
  • 0
    Спасибо за статью.
    На bem.info нашел вот такой код:

    .menu_size_big {
      // CSS code to specify height
    }
    .menu_type_buttons .menu__item {
      // CSS code to change item's look
    }
    


    Т.е. иногда все таки каскад можно? Или только в зависимости от контекста? Или опечатка?
    • 0
      Это модификатор. Он добавляется к блоку и меняет элемент блока. Вы же не будете на все элементы модификатор вешать.
  • 0
    Без зависимости никак. Приведу пример. Есть блок, в его элементе второй блок.

    <div class="block">
        <div class="block__element">
            <div class="block2">Text</div>
        </div>
    </div>
    


    В какой-то момент первому блоку добавляется модификатор (состояние) block_select_on, что он выделен:

    <div class="block block_select_on">
        <div class="block__element">
            <div class="block2">Text</div>
        </div>
    </div>
    


    Блок в состоянии выделения, допустим, меняет фон на чёрный. У второго блока фон прозрачный, но цвет его текста желательно поменять на белый. Как в BEM в зависимости от состояния первого блока поменять стиль второго блока?

    Варианты:

    1. Блоки независимы, можно считать проблемы нет. Второму блоку нужно задать свой фон. И пофиг какое состояние у первого блока. Получим неадекватный дизайн. Для полной независимости нужно всем блокам определять все свойства стиля, иначе ложно утверждение, что блок везде будет выглядит одинакового (не поедет его стиль). Но тогда не применить множество классов на тег.
    2. Второму блоку тоже добавляем модификатор (свой), чтоб менял цвет и фон. Хм. Кто его будет добавлять? Логика первого блока? Но блоки независимы, т.е. нет знаний, какие блоки могут оказаться внутри первого и от куда узнать, какие им модификаторы добавлять? Пробуем каким-то образом обрабатывать событие выделения логикой второго блока, чтобы он сам себе модификатор добавлял. Но и тут проблема независимости. Изначально неизвестно внутри какого блока окажется второй блок и, соответственно, при каких событиях добавлять модификатор? Сам модификатор по смыслу зависим от первого блока. И от куда второй блок должен знать, что ему нужно именно в черный цвет краситься? Опять зависимость от первого блока.

    3. Применяем каскад. .block_select_on .block2{} Где писать этот каскад, в css первого, второго блока или в css проекта? Ладно, на уровне css/html получается лаконично. Но где желаемая независимость блоков? Разработчик первого блока ещё может догадаться, что в его блок будут добавлять другие блоки, и им нужно менять оформление, но неизвестно что именно менять (структура блоков неизвестна). Разработчик второго блока даже и не думал об особенностях отображения внутри неопределенных им блоков.


    Мы хотим независимость, когда всё пропитано зависимостью? Каков компромисс?

    1. Классы BEM быстрее обрабатываются. Стараемся не использовать каскад
    2. CSS BEM независим от структуры HTML. И в целом меньше проблем со стилями вложенных блоков
    3. Каскад применяется там, где BEM неприменим, где зависимость от конекста. Но мне до сих пор не понятно, как это урегулировано в самом BEM и его инструментах. Как в BEMJSON указать такую зависимость?
    4. Необходима база именованный блоков для соблюдения уникальности и возможности взять за основу существующий блок
    5. Грабли с применением jQuery и других скриптов. Например, не можем с легкостью добавить любой кнопке состояние нажатия (класс), так как название модификатора состоит из имени блока. Приходится использовать дополнительные обертки.
    6. Чтобы оформление хоть как-то зависело от темы, необходимо добавлять в HTML своего блока классы базовых блоков. Например button, input, title. Но здесь проходит тонкая грань независимости, нужно предполагать, что определяют классы базовых блоков.
    7. Вместо каскада работаем с длинными перечнем классов в теге.


    • 0
      По сути вы говорите о глобальном модификаторе, который меняет страницу или часть страницы. Использование каскада здесь вполне допустимо. Если не хочется, то конечно можете добавлять модификаторы на вложенные блоки, уведомляя их через обсерверы в JS-коде, например.
      • 0
        Глядя на реальный проект, из которого придуман пример, не могу согласится, что это глобальный модификатор. Это модификатор конкретного блока (первого). В нём он имеет смысл, определяет поведение и внешность блока. В других блоках в любых уровнях он не нужен или будет иметь другой смысл. Тут явная зависимость от родительского блока. Могут быть примеры с большой вложенностью, где модификатор влияет только на непосредственных детей или с какой-то там структурой. Это всё решается каскадом, да, с вытекающей из этого зависимостью блоков. Я, собственно, о том, что от зависимости не уйти, применяется ли БЭМ или нет.

        Всем, кто хочет улучшить свою верстку я бы только рекомендовал минимизировать какскад, применять соглашения об именовании классов и не жертвовать совместимостью со всем, что в вебе напридумывали и придумают ещё. Полностью следуя методологии BEM и применяя её инструменты, ощущаю себя в песочнице отстраненным от прогресса :)

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