Download pdf - BEM - CSS, Seriously

Transcript
Page 1: BEM - CSS, Seriously

CSS, Seriously!Introduction to a new CSS methodology

Page 2: BEM - CSS, Seriously

What the BEM?

- Naming convention

- Block-Element-Modifier

- Invented by Yandex in 2009

- Widely used by the frontend community

Page 3: BEM - CSS, Seriously

Key concepts How to In the wild In community

The Agenda

Page 4: BEM - CSS, Seriously

Key concepts of Block-Element-Modifier

Page 5: BEM - CSS, Seriously

BBlock Element

EModifier

M

Page 6: BEM - CSS, Seriously

BA block is defining the high level component and should be seen as

logical and functionally independent entity.

Block

Page 7: BEM - CSS, Seriously

Tab 1 Tab 2 Tab 4Tab 1

LOGO Search

Sign in

Login

*****

TabsLogo Authentication

Search Header

Page 8: BEM - CSS, Seriously

Item

1,40 Meter breiter

Schlafbereich, Kchenzeile,

Eckbank, Waschbecken.

Stadtwohnung? Nein!

Page 9: BEM - CSS, Seriously

1,40 Meter breiter

Schlafbereich, Kchenzeile,

Eckbank, Waschbecken.

Stadtwohnung? Nein!

1,40 Meter breiter

Schlafbereich, Kchenzeile,

Eckbank, Waschbecken.

Stadtwohnung? Nein!

1,40 Meter breiter

Schlafbereich, Kchenzeile,

Eckbank, Waschbecken.

Stadtwohnung? Nein!

Item

Page 10: BEM - CSS, Seriously

EAn element is a child within the Block, that

helps to form it. An element is semantically

tied to its Block and can't stand alone

Element

Page 11: BEM - CSS, Seriously

Tab Item Tab Item Tab Item Tab Item

Tabs

Tab 1 Tab 2 Tab 4Tab 1

Page 12: BEM - CSS, Seriously

Title

1,40 Meter breiter

Schlafbereich, Kchenzeile,

Eckbank, Waschbecken.

Stadtwohnung? Nein!

Image

Text

Item

Page 13: BEM - CSS, Seriously

MA Modifier defines the appearance and behaviour

of a Block or Element

Modifier

Page 14: BEM - CSS, Seriously

Tabs

Tab 1 Tab 2 Tab 4Tab 1

Tab 1 Tab 2 Tab 4Tab 1

Tab 1 Tab 2 Tab 4Tab 1

Tab 1 Tab 2 Tab 4Tab 1

Spread

Small

Small & Spread

Page 15: BEM - CSS, Seriously

A State defines a temporary appearance

and behaviour of a Block or Element

State

Page 16: BEM - CSS, Seriously

Active

Tabs

Tab 1 Tab 2 Tab 4Tab 1

Page 17: BEM - CSS, Seriously

BBlock Element

EModifier State

Mindependent and reusable

children of a Block

behaviour & appearance

temporary behaviour & appearance

Page 18: BEM - CSS, Seriously

How to master Block-Element-Modifier methodologyThe cookbook for naming and writing HTML and CSS the BEM-way

Page 19: BEM - CSS, Seriously

BBlock

Page 20: BEM - CSS, Seriously

Naming

tabs

site-header

feed-item

search

may consist of lowercase latin letters, digits, and

dashes.

as generic as possible, as specific as necessary.

Page 21: BEM - CSS, Seriously

names are meant to be used as classes only

can be nested

Html

<div class="tabs"></div>

// Nested blocks

<header class="header"> <div class="tabs"></div> <form class="search"></form></header>

Page 22: BEM - CSS, Seriously

CSS

.tabs {}

.header {}

.site-header {}

.header .tabs {}

h1.title {}

remain semantically independent

are never addressed in the context of another block

never use float, positioning or margin

do not depend on DOM elements

Page 23: BEM - CSS, Seriously

Tab 1 Tab 2 Tab 4Tab 1

LOGO Search

Sign in

Login

*****

TabsLogo Authentication

Search Header

<header class="header"> <nav class="tabs"> ... </nav> <img class="logo" /> <form class="search"> ... </form> <form class="auth"> ... </form></header>

Page 24: BEM - CSS, Seriously

EElement

Page 25: BEM - CSS, Seriously

Naming

tabs__item

feed-item__title

search__input

consist of lowercase latin letters, digits, and

dashes.

start with the name of the block separated with

two underscores:

block__element

Page 26: BEM - CSS, Seriously

are meant to be used as classes only

can be nested while naming will stay flat

Html

<nav class="tabs"> <a class=“tabs__item”></a> <a class=“tabs__item”></a> </nav>

// Nested elements

<div class=“card"> <header class=“card__header”> ... </header> <div class=“card__body”> <h3 class=“card__title”></h3> </div></div>

Page 27: BEM - CSS, Seriously

CSS

.tabs__item {}

// Try to avoid.tabs .tabs__item {}

.header .tabs__item {}

li.tabs__item {}

avoid block selectors to keep specificity low

do not depend on other blocks

do not depend on DOM elements

Page 28: BEM - CSS, Seriously

<nav class=“tabs"> <a class=“tabs__item”></a> <a class=“tabs__item”></a> <a class=“tabs__item”></a> <a class=“tabs__item”></a></nav>

Tab Tab Tab Tab

Tab 1 Tab 2 Tab 4Tab 1

Page 29: BEM - CSS, Seriously

MModifier

Page 30: BEM - CSS, Seriously

Naming

tabs--spread

button--theme-red

user__image—-small

consist of lowercase latin letters, digits, and dashes.

as descriptive as necessary

start with the name of the block/element separated with by two

dashes:

block--modifier block__element--modifier

Page 31: BEM - CSS, Seriously

always appended as an extra class

can be chained to combine modifications

Html

<a class=“button button--small> <a class=“button__icon button__icon--inverted”</a>

// Chained modifier <a class=“button button--small button--blue”>

Page 32: BEM - CSS, Seriously

CSS

.button--m {}

.tabs--spread .tabs__item {}

.button__icon--inverted {}

// Try to avoid.button--red .button--small {}

.header .tabs--spread {}

nav.tabs--spread {}

avoid cross modifier dependencies

do not depend on other blocks

do not depend on DOM elements

Page 33: BEM - CSS, Seriously

Tab 1 Tab 2 Tab 4Tab 1

<nav class=“tabs”> <a class=“tabs__item”></a></nav>

.tabs {}

.tabs__item {}

Page 34: BEM - CSS, Seriously

Tab 1 Tab 2 Tab 4Tab 1

<nav class=“tabs tabs—spread”> <a class=“tabs__item”></a></nav>

.tabs {}

.tabs__item {}

.tabs--spread .tabs__item { margin: 0 10px;}

Page 35: BEM - CSS, Seriously

Tab 1 Tab 2 Tab 4Tab 1

<nav class=“tabs tabs—spread tabs--small”> <a class=“tabs__item”></a></nav>

.tabs {}

.tabs__item {}

.tabs--spread .tabs__item { margin: 0 10px;}

.tabs--small{font-size: 10px;

}

Page 36: BEM - CSS, Seriously

State

Page 37: BEM - CSS, Seriously

Naming

is-selected

has-value

may consist of lowercase latin letters, digits, and

dashes.

prefixed with is or has:

is-state has-state

Page 38: BEM - CSS, Seriously

names are meant to be used as classes only

added as an extra class

Html

<nav class=“main-menu”> <a class=“main-menu__link is-active”></a></nav>

Page 39: BEM - CSS, Seriously

CSS

.tab.is-visible {}

.tab__item.is-active {}

.tab.is-visible .tab__item {}

h1.is-active {}.is-visible {}

always tied to a block or element

trumps other stylings due to higher specificity

do not depend on DOM elements

do not use standalone

Page 40: BEM - CSS, Seriously

Active

Tab 1 Tab 2 Tab 4Tab 1

<nav class=“tabs”> <a class=“tabs__item”></a>

<a class=“tabs__item”></a><a class=“tabs__item is-active“</a><a class=“tabs__item”></a>

</nav>

Page 41: BEM - CSS, Seriously

start with a modifier/element instead of over-modularize

–when it gets difficult to manage,

start with a brand new component–

latest when starting to overwrite a lot of the block styling with

modifiers

Element/Modifier or a new Block ?

Page 42: BEM - CSS, Seriously

BEM in the wildCommon best practices and pitfalls

Page 43: BEM - CSS, Seriously

Monoliths Single responsibility

Page 44: BEM - CSS, Seriously

Monoliths

.btn-login { display: inline-block; padding: 2em; background-color: green; color: white;}

hard to change

hard to swap styles out

Page 45: BEM - CSS, Seriously

.btn{ display: inline-block;}

.btn--large { padding: 2em;}

.btn--primary { background-color: green; color: white;}

clearly separated concerns

easy to just use the ones that we need

easy to add new ones

Single responsibility

Page 46: BEM - CSS, Seriously

Monoliths

.btn-login { display: inline-block; padding: 2em; background-color: green; color: white;}

.btn{ display: inline-block;}

.btn--large { padding: 2em;}

.btn--primary { background-color: green; color: white;}

Single responsibility

Page 47: BEM - CSS, Seriously

Complexity Simplicity

Page 48: BEM - CSS, Seriously

Complexity

div.main section.content div.categories .title

hard to read

way to specific

Page 49: BEM - CSS, Seriously

Complexity

div.main section.content div.categories .titlethe only thing we care about

Page 50: BEM - CSS, Seriously

Complexity

div.main section.content div.categories .title

conditions add complexity

harms readability

lowers performance

Page 51: BEM - CSS, Seriously

Simplicity

.categories__title

simply give things the name of what they are

choose the level of abstraction for names (be

specific or generic)

Page 52: BEM - CSS, Seriously

Complexity Simplicity

.categories

.categories__titlediv.main section.content div.categories .title

Page 53: BEM - CSS, Seriously

Mutability Immutability

Page 54: BEM - CSS, Seriously

Mutability

.btn { font-size: 1em; }

.promo .btn { font-size: 2em; }

Contextual styling will result in two different outcomes for one and the

same class

Page 55: BEM - CSS, Seriously

Mutability

@import ‘nova/lib/scss/components/button’;

.nova-c-button { padding: 20px;

}

add styles of third party libraries

Page 56: BEM - CSS, Seriously

.btn { font-size: 1em; }

.promo .btn { font-size: 2em; }

@import ‘nova/lib/scss/components/button’;.nova-c-button { padding: 20px;

}

.btn { font-size: 1em; }

.btn--large { font-size: 2em; }

@import ‘nova/lib/scss/components/button’;.my-padded-button {padding: 20px;

}

Mutability Immutability

Page 57: BEM - CSS, Seriously

Deep Nesting Flat Tree

Page 58: BEM - CSS, Seriously

Deep Nesting

<div class=“main-menu”> <ul class=“main-menu__section”>

<li class=“main-menu__section__title”>Section One

</li><li class=“main-menu__section__item”><a class=“main-menu__section__item__link” />

</li></ul>

</div>

hard to read

not BEM conform

adds unnecessary complexity

Grand children

Page 59: BEM - CSS, Seriously

<div class=“main-menu”> <ul class=“main-menu__section”>

<li class=“main-menu__title”>Section One

</li><li class=“main-menu__item”><a class=“main-menu__link” />

</li></ul>

</div>

Flat Tree

easy to read

easy to maintain regarding order and

nesting depth

Page 60: BEM - CSS, Seriously

Deep Nesting

<div class=“main-menu”> <ul class=“main-menu__section”>

<li class=“main-menu__section__title”>Section One

</li><li class=“main-menu__section__item”><a class=“main-menu__section__item__link” />

</li></ul>

</div>

<div class=“main-menu”> <ul class=“main-menu__section”>

<li class=“main-menu__title”>Section One

</li><li class=“main-menu__item”><a class=“main-menu__link” />

</li></ul>

</div>

Flat Tree

Page 61: BEM - CSS, Seriously

Contextual Styling Mixes

Page 62: BEM - CSS, Seriously

Tab 1 Tab 2 Tab 4Tab 1

LOGO Search

Sign in

Login

*****

Tabs

Header

Tab 1 Tab 2 Tab 4Tab 1

LOGO Search

Sign in

Login

*****

Page 63: BEM - CSS, Seriously

Tab 1 Tab 2 Tab 4Tab 1

LOGO Search

Sign in

Login

*****

Tabs

Header

Page 64: BEM - CSS, Seriously

<header class="header"> <nav class=“tabs”> ... </nav></header>

Cross-Components Mixes

Page 65: BEM - CSS, Seriously

<header class="header"> <nav class=“tabs”>

... </nav></header>

.tabs { font-size: 18px;}

.header .tabs { font-size: 10px; position: absolute; bottom: 100%;

}

Contextual Styling

not BEM conform

can cause side-effects thatare hard to track down

Page 66: BEM - CSS, Seriously

Should be avoided!

Page 67: BEM - CSS, Seriously

<header class="header"> <nav class=“tabs”> ... </nav></header>

Cross-Components Mixes

Page 68: BEM - CSS, Seriously

<header class="header"> <nav class=“header__tabs tabs”> ... </nav></header>

Cross-Components Mixes

Page 69: BEM - CSS, Seriously

<header class="header"> <nav class=“header__tabs tabs”> ... </nav></header>

.tabs {font-size: 18px;

}

.header__tabs { font-size: 10px;position: absoute;bottom: 100%

}

Cross-Components Mixes

Page 70: BEM - CSS, Seriously

Cross-Components Mixes

can be used to extend styles

don’t use it to overwrite styles!

<header class="header"> <nav class=“header__tabs tabs”> ... </nav></header>

.tabs {font-size: 18px;

}

.header__tabs { font-size: 10px;position: absolute;bottom: 100%

}

Page 71: BEM - CSS, Seriously

<header class="header"> <nav class=“header__tabs tabs tabs--small”> ... </nav></header>

.tabs {font-size: 18px;

}

.tabs—-small {font-size: 10px;

}

.header__tabs {font-size: 10px;

}

Cross-Components Mixes

consider to use a modifier

Page 72: BEM - CSS, Seriously

<header class="header"> <nav class=“header__tabs header__tabs--small tabs”> ... </nav></header>

.tabs {font-size: 18px;

} .header__tabs--small {font-size: 10px;

}

.header__tabs {font-size: 10px;

}

Cross-Components Mixes

would this be okay?

Page 73: BEM - CSS, Seriously

Layout as part of a Component Separate Layout from Components

Page 74: BEM - CSS, Seriously

Layout as part of a Component

<div class="card"> <div class="card__body"> <ul class="card__checklist"> <li class="card__checklist__item"> <input class=“card__checklist__input" type="checkbox"> <label class="card__checklist__label">Apples</label> </li> <li class="card__checklist__item"> <input class=“card__checklist__input" type="checkbox"> <label class="card__checklist__label">Bananas</label> </li> </ul> </div></div>

Page 75: BEM - CSS, Seriously

Separate Layout from Components

<div class="card"> <div class="card__body"> <ul class="stack"> <li class=“stack__item”> <input class=“card__checkbox” type="checkbox"> <label class=“card__label”>Apples</label> </li> <li class="stack__item"> <input class=“card__checkbox” type="checkbox"> <label class=“card__label”>Bananas</label> </li> </ul> </div></div>

Page 76: BEM - CSS, Seriously

Separate Layout from Components

<div class="card"> <div class="card__body"> <ul class="stack"> <li class=“stack__item”> <input class=“checkbox” type="checkbox"> <label class=“label”>Apples</label> </li> <li class="stack__item"> <input class=“checkbox” type="checkbox"> <label class=“label”>Bananas</label> </li> </ul> </div></div>

and reuse of other blocks


Recommended