-
Notifications
You must be signed in to change notification settings - Fork 2
components
Компонентная верстка - создание малых и независимых CSS-компонентов
Многократно используемый CSS-компонент может применяться к различным элементам в различных частях дерева DOM и не зависит от типов элементов, поскольку опирается на классы
CSS-компонент связан с элементом-контенером с помощью уникального имени класса
Элемент-контейнер может содержать другие элементы
Инкапсюляция стилей этих элементов обеспечивается использованием наследственных селекторов:
.some-component {
...
}
.some-component img {
...
}Таким образом стили внутри компонента изолируются от стилей других элементов на странице
Иными словами, мы используем уникальное имя для набора стилей, что позволяет многократно использовать этот набор без повторения CSS-правил
Главное достоинство такого подхода - возможность использовать модификаторы, обеспечивающие различное поведение и внешний вид одного и того же CSS-компонента
Технология BEM ( block, element, modifier ), разработанная ребятами из Яндекса, представляет собой способ информативного именования CSS-классов, чтобы сделать их более понятными для других разработчиков
Смысл BEM заключается в том, чтобы рассказать другим разработчикам больше о том, что делает фрагмент разметки только от своего имени
Прочитав некоторый HTML-код с некоторыми классами, можно понять, как связаны элементы
- что-то может быть просто компонентом
- что-то может быть дочерним элементом этого компонента
- а что-то может быть вариацией или модификатором этого компонента
Схема именования CSS-классов:
.block { ... }
.block__element { ... }
.block--modifier { ... }где
- .block представляет класс компонента
- .block__element представляет класс потомка элемента класса .block
- .block--modifier представляет другую версию класса .block
Здесь использованы двойные, а не одиночные дефисы и подчеркивания
Причина этого в том, что в имени самого блока может быть использован дефис или подчеркивание
/* Блок */
.site-search { ... }
/* Элемент */
.site-search__field { ... }
/* Модификатор */
.site-search--full { ... } Компонент, отображающий указанное изображение на половину высоты окна просмотра
Ниже выводит текст, который передается через атрибут message
![]() |
|---|
<section class="component" message="Welcome">
<figure class="component__figure component__figure--1">
</figure>
</section>body, html {
margin: 0;
}
.component {
height: 100vh;
margin: 0;
text-align: center;
}
.component:after {
content: attr(message);
font-family: Arial;
font-size: 7vmin;
font-weight: bold;
color: #550;
}
.component__figure {
height: 50%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
padding: 0;
margin: 0 0 1rem 0;
}
.component__figure--1 {
background-image: url("https://images.pexels.com/photos/1089168/pexels-photo-1089168.jpeg");
}
.component__figure--2 {
background-image: url("https://images.pexels.com/photos/371589/pexels-photo-371589.jpeg");
}Изменим предыдущий пример с использованием модификаторов:
![]() |
|---|
body, html {
margin: 0;
}
.component {
height: 100vh;
margin: 0;
text-align: center;
--text-color: attr(color);
}
.component:after {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
content: attr(mess);
font-family: Arial;
font-size: 10vmin;
font-weight: bold;
variant: attr(variant);
}
.component--1:after {
content: "Welcome";
color: #550;
}
.component--2:after {
content: "Nature";
color: #fff;
text-shadow: 2px 2px 3px #00000090;
}
.component figure {
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
padding: 0;
margin: 0 0 1rem 0;
}
.component--1 figure {
background-image: url("https://images.pexels.com/photos/1089168/pexels-photo-1089168.jpeg");
}
.component--2 figure {
background-image: url("https://images.pexels.com/photos/371589/pexels-photo-371589.jpeg");
}<section class="component component--1">
<figure></figure>
</section>Мы можем выбрать модификацию компонента, что позволяет не только изменить фоновую картинку, но и текст, и цвет текста
![]() |
|---|
<nav id="nav">
<ul class="main-nav">
<li>
<a href="#">Main-item 01</a>
<ul class="dropdown">
<li><a href="#">Sub-item 01</a></li>
<li><a href="#">Sub-item 02</a></li>
<li><a href="#">Sub-item 03</a></li>
<li><a href="#">Sub-item 04</a></li>
</ul>
</li>
<li><a href="#">Main-item 02</a></li>
<li><a href="#">Main-item 03</a></li>
<li><a href="#">Main-item 04</a></li>
</ul>
</nav>:root {
--hover-back: #457;
--menu-back: #bbc;
}
html {
font-family: Arial;
font-size: 16px;
}
.main-nav {
font-size: 0;
line-height: 0;
background: var(--menu-back);
padding-left:0;
}
.main-nav > li {
position: relative;
display: inline-block;
vertical-align: top;
font-size: 1rem;
line-height: 1rem;
border-left: 2px solid #fff;
}
.main-nav > li:hover .dropdown {
opacity: 1;
visibility: visible;
}
.main-nav > li:hover > a {
color: #fff;
background: var(--hover-back);
}
.main-nav > li > a {
display: block;
color: var(--hover-back);
padding: 20px 30px;
transition: background .5s ease;
text-decoration: none;
}
.main-nav a:hover {
color: #fff;
background: var(--hover-back);
}
.dropdown {
position: absolute;
z-index: 10;
left: 0;
top: 100%;
width: 100%;
background: #dde;
border: 2px solid #fff;
opacity: 0;
visibility: hidden;
transition: opacity .5s ease;
padding-left: 0;
}
.dropdown > li {
border-bottom: 1px solid #fff;
list-style-type: none;
list-style-position: outside;
}
.dropdown > li:last-child {
border-bottom: 0;
}
.dropdown > li > a {
display: block;
padding: 1rem;
text-decoration: none;
color: #555;
}![]() |
|---|
<figure class="overshadow">
<img src="https://images.pexels.com/photos/450038/pexels-photo-450038.jpeg"
alt="Welcome"
class="overshadow__image">
<div class="overshadow__shadow">
<div class="overshadow__text">Welcome</div>
</div>
</figure>.overshadow {
position: relative;
width: 50%;
margin: 0 25%;
box-sizing: border-box;
}
.overshadow__image {
display: block;
width: 100%;
height: auto;
}
.overshadow__shadow {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
opacity: 0;
transition: .5s ease;
background-color: #003030b0;
transform: rotate(30deg) scale(0.5);
}
.overshadow:hover .overshadow__shadow {
opacity: 1;
transform: rotate(0deg) scale(1);
}
.overshadow__text {
font-family: Arial;
color: white;
font-size: 5vmin;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}![]() |
|---|
<form action="#"
class="form-component
form-component--email
form-component--password">
<div class="form-col form-col-name" before="Enter your name: ">
<input type="text" placeholder="Name">
</div>
<div class="form-col form-col-email" before="Enter your email here: ">
<input type="email" placeholder="Email">
</div>
<div class="form-col form-col-password" before="Do you remember your password? ">
<input type="password" placeholder="Password">
</div>
<button type="submit">Submit</button>
</form>.form-component {
margin: 10vh 10vw;
height: max-content;
border: inset 1px;
box-sizing: border-box;
text-align: center;
font-family: Arial;
padding: 10%;
background: #eef;
}
.form-component .form-col {
width: 80%;
margin: 2rem 10%;
display: none;
}
.form-component--name .form-col-name,
.form-component--email .form-col-email,
.form-component--password .form-col-password {
display: block;
}
.form-component .form-col input {
display: inline-block;
vertical-align: middle;
border: 1px inset;
padding: 1rem 2rem;
margin-top: 1rem;
}
.form-component .form-col:before {
content: attr(before);
color: #333;
}
.form-component button {
padding: 1rem 2rem;
font-size: 1.2rem;
}
@media screen and (max-width:480px) {
.form-component {
margin: 10vh 0;
padding: 0;
}
.form-component .form-col {
padding: 0;
}
.form-component .form-col input {
max-width: 50vh;
padding: 0.8rem 0.5rem;
}
.form-component button {
padding: 0.5rem 0.5rem;
font-size: 1.0rem;
margin-bottom: 2rem;
}
}
Компонентная вёрстка
BEM
1




Всемирная паутина
Пример
