Skip to content

lexxcode/sfm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 

Repository files navigation

Simple Frontend Methodology

Микрометодология создания клиентского кода веб-сайтов и приложений. Не является чем-то уникальным или новым. Скорее компиляция моего видения того как может быть удобнее разрабатывать frontend. Скорее собирает интересные мысли из разных источников, чем предлагает какой-то кардинально новый подход к этому вопросу. Все обычно и привычно. :)

Block

Блок представляет собой самодостаточную сущность, инкапсулированный компонент. Имя может состоять из одного слова или быть комбинированным из нескольких слов разделенных одним тире:

.block
.block-name

Element

Элемент представляет из себя внутреннюю составляющую блока и тесно с ним саязан. Находится в области имен родительского блока. Использован может где угодно в рамках контекста своего блока. Не может быть ситуации возникновения элемента от элемента! Имя элемента является производной от имени блока и записывается через двойное нижнее подчеркивание:

.block__elem
.block-name__elem

Modifier

Модификатор это способ кастомизации блока или элемента. Не должен нести какой либо логической нагрузки. Это всего лишь возможность реализации разных визуально разных видов одного и того же блока или элемента. В отличии от классического БЭМ подхода, модификатор не смешивает в себе понятия собственно модификации и состояний. Имя модификатора состоит из имени блока или элемента и названия модификатора отделенного двойным дефисом:

.block--modifier
.block-name--modifier
.block__elem--modifier
.block-name__elem--modifier

State

Состояние - относительно самостоятельный слой, но в то же время должен быть привязан к какому-то блоку или элементу. Понятие состояния несет в себе логический смысл и служит определением того как должен себя вести (а так же выглядеть) блоки или элемент при определенных условиях. Состояния записываются отдельным дополнительным классом, имя которого может быть идентифицировано как состояние. Например: .success, .warning, .error, .done, .show, .hide, .draggable, .current, ... Нельзя привязывать стили непосредственно на классы состояний! То есть, так нельзя:

.success {
    backgorund: #0f0;
}

Стили состояний, так же как и модификаторы, могут быть применены в связке с блоком или элементом:

.block {
    &.success {}
    &.error {}
}
.block__elem {
    &.success {}
    &.error {}
}

SCSS Nesting

Использование препроцессоров позволяет автоматизировать комбинирование css-селекторов. Тем самым мы можем писать меньше стилей и как следствие меньше классов в html.

.block {
    &.state {}

    &__elem {
        &.state {}

        &--modifier {}
    }

    &--modifier {}
}

Так как, модификатор это способ дополнения стилей блока/элемента, модификатор должен наследовать стили своего блока/элемента (если есть что наследовать!).

.block {
    &.state {}

    &__elem {
        &.state {}

        &--modifier {
            @extend .block__elem;
        }
    }

    &--modifier {
        @extend .block;
    }
}

Можно сделать это еще круче? Да, можно. Use Variables Luke!

.block {
    $root: &;

    &.state {}

    &__elem {
        $elem: &;
        &.state {}

        &--modifier {
            @extend #{$elem};
        }
    }

    &--modifier {
        @extend #{$root};
    }
}

Что нам это дает? Мы можем больше не беспокоиться об именах в наследуемых блоках и элементах. Все заключено в локальных переменных. Если нам нужно изменить имя блока - просто меняем имя блока. Все зависимости будут подхвачены сквозь переменные.

По поводу html, да там мы сможем меньше писать. Сделать код более читабельным. Нам больше не нужно прописывать вагон длинных классов (gg BEM). Представим ситуацию, когда у нас есть модифицированный блок со списком элементов внутри. Один из них выделен как текущий, а другой просто модифицирован.

В теории BEM:

<div class="block block--modifier">
    <div class="block__elem"></div>
    <div class="block__elem block__elem--current"></div>
    <div class="block__elem"></div>
    <div class="block__elem"></div>
    <div class="block__elem block__elem--modifier"></div>
</div>

В теории SFM

<div class="block--modifier">
    <div class="block__elem"></div>
    <div class="block__elem current"></div>
    <div class="block__elem"></div>
    <div class="block__elem"></div>
    <div class="block__elem--modifier"></div>
</div>

Мы избавились от чрезмерного дублирования классов. Все по прежнему логично, без лишнего хлама в коде.

JS-hooks

Что касательно js, для него есть отдельный слой. Любое поведение должно привязываться либо на классы с префиксом js-* либо на специальные атрибуты, которые будут выполнять роль слоя для js-hooks. Например data-role="action". В js мы можем обращаться к таким элементам по селектору [data-role="action"]

Layers

Слои. Нет это не те слои с эпохи перехода от табличной верстки к div-ной. Разработка страницы, должна делиться на несколько глобальных слоев:

  • Layouts
  • Components
  • JS-hooks

Layouts - это скелет. Он может быть как обобщенный для построения основного скелета страницы, так и локальным для построения внутренней структуры блока. Это не обязательно обертка вокруг чего-то (хотя скорее всего именно так). Этот скелет должен задавать структуру распределения в нем элементов и других блоков. Выравнивание, отступы между чем либо и прочие организационные вещи общего плана это Layout.

Components - это наши блоки и элементы. В первую очередь блоки должны управлять только своей внутренней структурой (Назовем это Inner Layout). Внешнее поведение должно быть максимально простым, понятным и не влиять на собственное позиционирование, относительно других участников структуры. То есть, если у нас есть, например, кнопка она может управлять своим внутренним устройством. Размеры, внутренние отступы, размер шрифта текста, поведения иконок если есть. Но не должна иметь внешних отступов (margin) Если нам нужно разместить несколько кнопок в ряд с отступами мы строим вокруг них Layout. Создадим над ними блок, который разберется с внутренней структурой. Да здесь могут быть компромиссы и использование контекстной зависимости вместо последующего оборачивания каждой кнопки в элемент, а можно и обернуть все зависит от ситуации.

JS-hooks тут все просто, это отдельный слой который вообще никак не связан с выше перечисленным. На селекторы JS-hooks запрещено привязывать вообще какие-либо стили. Это специальные селекторы для обращения к ним через js. Если нам нужно динамически менять состояние компонента, мы должны управлять его селекторами состояний.

Good Luck & Have Fun ⚡⚡⚡

Releases

No releases published

Packages

No packages published