Skip to content

components

garevna edited this page Apr 22, 2019 · 16 revisions

ico25 Компонентная вёрстка

Компонентная верстка - создание малых и независимых CSS-компонентов

Многократно используемый CSS-компонент может применяться к различным элементам в различных частях дерева DOM и не зависит от типов элементов, поскольку опирается на классы

CSS-компонент связан с элементом-контенером с помощью уникального имени класса

Элемент-контейнер может содержать другие элементы

Инкапсюляция стилей этих элементов обеспечивается использованием наследственных селекторов:

.some-component {
    ...
}

.some-component img {
    ...
}

Таким образом стили внутри компонента изолируются от стилей других элементов на странице

Иными словами, мы используем уникальное имя для набора стилей, что позволяет многократно использовать этот набор без повторения CSS-правил

Главное достоинство такого подхода - возможность использовать модификаторы, обеспечивающие различное поведение и внешний вид одного и того же CSS-компонента


ico20 BEM

Технология 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 { ... } 

cap-25 1

Компонент, отображающий указанное изображение на половину высоты окна просмотра

Ниже выводит текст, который передается через атрибут message

html
<section class="component" message="Welcome">
  <figure class="component__figure component__figure--1">
  </figure>
</section>
css
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");
}

cap-25 2

Изменим предыдущий пример с использованием модификаторов:

CSS
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");
}
html
<section class="component component--1">
  <figure></figure>
</section>

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


cap-25 3

html
<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>
css
: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;
}

cap-25 4

html
<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>
css
.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;
}

cap-25 5

Обратите внимание, что модификаторы form-component--email, form-component--password и form-component--name позволяют управлять содержимым формы

Для того, чтобы в форме отображались определенные поля, необходимо включить соответствующие модификаторы:

  • form-component--name чтобы в форме отображалось поле name
  • form-component--email чтобы в форме отображалось поле email
  • form-component--password чтобы в форме отображалось поле password

Добавляя или удаляя модификаторы, можно настраивать форму:

html
<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>
CSS
.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;
    }
}

© Irina H.Fylyppova 2019



Занятие 1


Занятие 2


Занятие 3


Занятие 4


Занятие 5


Занятие 6


Занятие 7


Занятие 8


Дополнительно

Clone this wiki locally