Это компонентый подход к разработке веб-приложения: разделение интерфейса на независимые блоки (и их элементы).
В разметке реализуется атрибутами class
.
Блок — логически и функционально независимая часть.
Элемент — всегда часть блока, самостятельно не нужен.
Модификатор — класс, меняющий внешний вид/поведение блока/элемента.
Существует как методология и как стек технологий.
<article class="blog-post">
<h2 class="blog-post__title">...</h2>
<div class="blog-post__content">
...
</div>
<footer class="blog-post__footer">...</footer>
</article>
<article class="blog-post blog-post--accent">
<h2 class="blog-post__title">...</h2>
<div class="blog-post__content">
...
</div>
<footer class="blog-post__footer">...</footer>
</article>
Проверяем понимание БЭМ.
margin
, как это сделать?id
в селекторах?<!-- main-menu — Блок -->
<ul class="main-menu">
<!-- main-menu__item — Элемент -->
<li class="main-menu__item">
<!-- main-menu__link — Элемент -->
<a href="/home" class="main-menu__link">Home</a>
</li>
<!-- main-menu__item_active — Модификатор -->
<li class="main-menu__item main-menu__item_active">
<a href="/about" class="main-menu__link">About</a>
</li>
</ul>
<!-- main-menu — Блок -->
<ul class="main-menu">
<!-- main-menu__item — Элемент -->
<li class="main-menu__item">
<!-- main-menu__link — Элемент -->
<a href="/home" class="main-menu__link">Home</a>
</li>
<!-- _active — Модификатор -->
<li class="main-menu__item _active">
<a href="/about" class="main-menu__link">About</a>
</li>
</ul>
<!-- main-menu — Блок -->
<ul class="main-menu">
<!-- main-menu__item — Элемент -->
<li class="main-menu__item">
<!-- main-menu__link — Элемент -->
<a href="/home" class="main-menu__link">Home</a>
</li>
<!-- main-menu__item--active — Модификатор -->
<li class="main-menu__item main-menu__item--active">
<a href="/about" class="main-menu__link">About</a>
</li>
</ul>
<!-- MainMenu — Блок -->
<ul class="MainMenu">
<!-- MainMenu__Item — Элемент -->
<li class="MainMenu__Item">
<!-- MainMenu__Link — Элемент -->
<a href="/home" class="MainMenu__Link">Home</a>
</li>
<!-- MainMenu__Item_active — Модификатор -->
<li class="MainMenu__Item MainMenu__Item_active">
<a href="/about" class="MainMenu__Link">About</a>
</li>
</ul>
<!-- MainMenu — Блок -->
<ul class="MainMenu">
<!-- MainMenu-Item — Элемент -->
<li class="MainMenu-Item">
<!-- MainMenu-Link — Элемент -->
<a href="/home" class="MainMenu-Link">Home</a>
</li>
<!-- MainMenu-Item_active — Модификатор -->
<li class="MainMenu-Item MainMenu-Item_active">
<a href="/about" class="MainMenu-Link">About</a>
</li>
</ul>
b-
— блок
o-
— объект, e-
— элемент
c-
— компонент или контрол
l-
— layout (раскладка), p-
— page
u-
— утилита
t-
— тема оформления
g-
— глобальный модификатор
is-/has-
— состояния
<section class="promo">
<h2 class="promo__title title">Купите наши цинковые вёдра</h2>
<ul class="promo__list grid">
<li class="product-card grid__item">...</li>
</ul>
</section>
<section class="c-promo">
<h2 class="c-promo__title c-title">Купите наши цинковые вёдра</h2>
<ul class="c-promo__list l-grid">
<li class="c-product-card l-grid__item">...</li>
</ul>
</section>
<ul class="l-list">
<li class="l-list__item">
<div class="c-checkbox">
<input class="c-checkbox__input" id="op_1" type="checkbox">
<label class="c-checkbox__label" for="op_1">Apples</label>
</div>
</li>
</ul>
<div class="o-media c-user c-user--premium">
<img class="o-media__img c-user__photo c-avatar" src="" alt="" />
<p class="o-media__body c-user__bio">...</p>
</div>
-nojs
— убираемый суффикс стилизации состояния без JS
@sm, @md, @lg
— адаптивные суффиксы
@print
— вспомогательные классы для сокрытия блоков при печати
<div class="o-media@md c-user c-user--premium">
<img class="o-media@md__img c-user__photo c-avatar" src="" alt="" />
<p class="o-media@md__body c-user__bio">...</p>
</div>
Эти суффиксы принимают формат @<контрольная точка>, и сообщают нам этот класс в следующем размере.
Здесь мы имеем o-media@md, что означает, что медиа-объект будет в этой контрольной точке.
Оригинал
<div class="promo">
<h2 class="promo__gray-title">...</h2>
</div>
<button class="button-red">Buy me!</button>
<span class="black-icon">...</span>
<section class="tariff">
<header class="tariff__header">
<h3 class="tariff__header__title">Tariff № 2</h3>
</header>
<div class="tariff__info">
<p class="tariff__info__price">
200 <span class="tariff__info__price__icon"></span>
</p>
</div>
</section>
<section class="promo">
...
<div class="promo__item">
...
<!-- Блок slider отсутствует на странице -->
<div class="slider__item">...</div>
</div>
</section>
<section class="tariffs">
...
<div class="tariffs__item">
<h3 class="tariffs__item-header">Tariff № 2</h3>
<p class="tariffs__item-header">...</p>
<div class="tariffs-item"> <!-- tariff — было бы лучше -->
<div class="tariffs-item__main-info">...</div>
</div>
</div>
</section>
<section class="promo promo__info">
<h2 class="promo__title">Promo</h2>
<div class="promo__list">
...
</div>
</section>
<section class="promo">
...
<div class="promo__item">...</div>
<div class="promo__item--large">...</div>
<div class="promo__item">...</div>
</section>
<section class="article">
<h2 class="article__heading article__heading_level_1_active">...</h2>
...
</section>
<section class="layout-profile">
<h2 class="layout-profile__name-header ft-typography _h1">...</h2>
...
</section>
.ft-typography { position: relative; }
.ft-typography._h1 { color: #232428; font-family: Effra, sans-serif; }
<div class="table">
<div class="table__head">
<div class="table__head-title table__head-title--version">Версия</div>
<div class="table__head-title table__head-title--date">Дата</div>
<div class="table__head-title table__head-title--author">Автор</div>
<div class="table__head-title table__head-title--descr">Примечание</div>
</div>
...
</div>
<section class="promo">
<h2 class="promo__title text-muted">Promo</h2>
<div class="text-right">
...
</div>
</section>
<button class="btn">Button</button>
.btn {
/* много стилей и... */
margin-right: 20px;
}
<h2 class="subtitle">Subtitle</h2>
.subtitle {
margin-top: 20px;
font-size: 24px;
line-height: 1.2
}
src/scss/components/common.blocks/the-sidebar/the-sidebar.scss
.sidebar { ... }
src/scss/pages/common.blocks/athletes/athletes.scss
.p-athletes { ... }
.promo {
&__text {
h2 { ... }
p { ... }
}
}
function cth(c) { document.documentElement.classList.add(c) }
'ontouchstart' in window ? cth('touch') : cth('no-touch');
if (typeof InstallTrigger!=='undefined') cth('firefox');
if (/*@cc_on!@*/false||!!document.documentMode) cth('ie');
.product-minicard {
.ie & { ... }
}
<div class="glavnayaStranitsa">
<h1 class="zagolovok">Заголовок</h2>
...
<!-- Оправданное использование префикса b- -->
<article class="b-product-minicard">...</article>
</div>
<div class="preloader">
<!-- preloader__container — единственный прямой потомок -->
<div class="preloader__container preloader__container--sm"> ... </div>
</div>
<div class="preloader preloader--sm">
<!-- preloader__container — единственный прямой потомок -->
<div class="preloader__container"> ... </div>
</div>
<ul class="article-rewind article-rewind_type_static article-rewind_lang_ru">
<li class="article-rewind__next">
<div class="article-rewind__next-text">Читать далее</div>
<a class="article-rewind__next-link" href="...">Основные понятия</a>
</li>
</ul>
<ul class="article-rewind type_static lang_ru">
<li class="next">
<div class="text">Читать далее</div>
<a class="link" href="...">Основные понятия</a>
</li>
</ul>
<!-- Сохрана разметка от автора «критики» -->
<section class="promo-section promo-section_color_white">
...
</section>
<h1 class="article__title">...</h1>
<h2 class="article__title article__title--level-2">...</h2>
<h3 class="article__title article__title--level-2">...</h3>
@for $index from 1 through 6 {
h#{$index}.heading {
font-size: (42px / $index);
}
}
// desktop.bundles/hello/hello.bemjson.js
({
block : 'page',
title : 'hello',
head : [
{ elem : 'css', url : 'hello.min.css' }
],
mods : { theme : 'islands' },
content : [
{ block : 'hello' }
]
})
// desktop.bundles/hello/hello.bemjson.js
({
...
content : [
{
block : 'hello',
content : [
{
elem : 'greeting',
content : 'Hello %user%!'
}
]
}
]
})
// desktop.blocks/hello/hello.bemhtml.js
block('hello')(
tag()('article')
);
/* desktop.blocks/hello/hello.css */
.hello {
color: green;
padding: 10%;
}
<div block="animals">
<div elem="item" mix="block:unicorn, mod: [large, female]">
<div block="unicorn" elem="photo"></div>
<div elem="item-name"></div>
</div>
</div>
<div class="animals">
<div class="animals__item unicorn unicorn_large unicorn_female">
<div class="unicorn__photo"></div>
<div class="animals__item-name"></div>
</div>
</div>
<div block="animal" mix="block:elephant elem:trunk">
<div elem="nose" mods="size:long">Nose</div>
</div>
<div class="animal elephant__trunk">
<div class="animal__nose animal__nose_size_long">Nose</div>
</div>
+b.block1
+e.element1 Foo
+b.block2
+e.A(href="#bar").element Bar
+e.element2 Baz
<div class="block1">
<div class="block1__element1">Foo</div>
<div class="block2">
<a class="block2__element" href="#bar">Bar</a>
</div>
<div class="block1__element2">Baz</div>
</div>
Николай Громов.
Бонус
скидка 10% на курс по вёрстке в EpicSkills по промо-коду GROMOV10