BEM
Nazewnictwo klas
block
block__element
block__element -modifier
- stosujemy takie-nazwy-klas, z myślnikami, zamiast camelCase
- pamiętamy o odpowiednio małych blokach - jeden może zawierać się wewnątrz drugiego
- unikamy stosowania czystych tagów html jako selektorów - używamy klas - .normal-form zamiast form
- jeżeli obiekt ma dwie klasy, to modyfikatory w html zapisujemy po tej klasie, której dotyczy (np. <div class=”button -hoverable box__button -red”> to w domyśle .button.-hoverable i .box__button.-red)
- jeżeli obiekt jest zarówno niezależnym blokiem, jak i elementem rodzica (jak poniższy .button.box__button), to w .box__button deklarujemy tylko to, co dotyczy związku elementu z rodzicem, np. pozycję; jeżeli button ma mieć np. inny rozmiar tekstu, lepiej zrobić to modyfikatorem np. -large-text, i nie wynosić takich zależności poza moduł, bo nie będą reużywalne i zrobi się bałagan
- modyfikatorów nie stylujemy osobno, w oderwaniu od wlaściwej klasy elementu- traktujemy to jako suffix, nie samodzielny selektor (nie robimy tak: .-green {background: $green;})
<article class=”box -green -rounded”>
<header class=”box__heading”>
<h1 class=”box__title”></h1>
</header>
<div class=”box__content”>
<img src=”” class=”box__image”/>
<div class=”box__description”></div>
<div class=”button box__button”></div>
</div>
</article>
States & event hooks
Przejściowe stany, w odróżnieniu od stałych modyfikatorów, oznaczamy klasą .is-cośtam, np.:
- is-active
- is-inactive
- is-valid
- is-invalid
Klasy wywołujące zdarzenia w javascripcie nazywamy .js-cośtam, np.:
- js-datepicker
- js-lightbox
Struktura pojedynczego pliku scss
- jeden moduł (blok) = jeden plik scss
- style responsywne dotyczące danego modułu są zadeklarowane na jego końcu
- ew. dokumentacja jest zadeklarowana jeszcze niżej
- zmienna $root z przypisanym & wspomaga zapis w przypadku, gdy po danym stanie rodzica (.is-active, :hover) chcemy ostylować element podrzędny1.
.box {
$root: &;
float: left;
width: 50%;
&__heading { … }
&__title { … }
&__content { … }
&.-green {...}
&.-rounded {...}
&.-large {...}
&:hover {
#{$root}__heading {...}
}
@include media($desktop) {
&__heading { … }
&__title { … }
&__content { … }
}
/*doc
......
*/
}
Struktura plików i katalogów scss
- _partials
- _base.scss - Basic styles including body, html, tags
- _layout.scss - Styles related with layout [grid, containers, rows, cols]
- _buttons.scss - Styles for buttons
- _common.scss - Styles related to all pages which not work as modules
- _fonts.scss - Embedded fonts used in project
- _footer.scss - Styles for footer
- _header.scss - Styles for header
- _mixins.scss - Mixins and SASS functions used in project
- _reset.scss - CSS reset styles for cross-browser
- _sprite.scss - Configuration of compass sprites
- _typography.scss - Styles related with text on website. Headers, paragraphs, links and other
- _vars.scss - SASS variables used on website. Colors, fonts sizes etc. [This file can be included in stand-alone CSS files (without underscore in name which will be compiled into separate files)]
- _modules
- _buttons.scss
- _article.scss
- _box.scss
- style.scss - Main SASS file gathering all other files into one
Style
- sortujemy style alfabetycznie
- objaśnienie problemu:
.link {
$root: &;
&:hover {
&__title {...}
// nie mozemy zrobic tak, bo w tym miejscu & odnosi sie juz nie do .link,
// a do hovera, czyli konwertuje sie to do .link:hover__title :)
.link__title {...}
// a to jest strasznie slabe, trzeba powtarzac nazwe klasy
#{$root}__title {...}
// +1
}
}
// Uwaga! Nie zadziała, gdy blok do którego przypisujemy zmienną $root, jest zagnieżdżony w innym, np.:
.blok1 {
.blok2 {
$root: &;
&:hover {
#{$root}__title {
// znak & zapisuje całą ścieżkę, czyli tutaj kompiluje się to tak:
// .blok1 .blok2:hover .blok1 .blok2__title (!)
}
}
}
}