• Микс БЭМ, правильно ли Элемент другого блока вставить миксовый блок?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Да, конечно. li в этом случае одновременно и элемент header, и элемент list. При этом li.list__item знает, что у него, например, list-style: none; (хотя, это логичнее задать у ul.list.list_type_unstyled { list-style-type: none; }, но для примера — сойдёт), а li.header__item «задаёт» отступы ( .header__item + .header__item { margin-left: 1em } ).
    Ответ написан
    Комментировать
  • Как назвать класс в BEM?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    <header class="header">
      <div class="header__logo">
        <img class="logo logo_size_m" />
      </div>
    </header>
    …
    <footer class="footer">
      <div class="footer__logo">
        <img class="logo logo_size_l" />
      </div>
    </footer>
    Ответ написан
    5 комментариев
  • Как правильно по БЭМу?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Лучше одним, да. На главной: .product.product_view_preview, на странице продукта — .product.product_view_detail. Это удобнее, т. к. в обоих вариантах по-любому повторяются общие элементы: заголовок, изображение, описание.
    А для описание отличий используются модификаторы (можно на уровне модификатора блока через каскад).

    .page.page_route_index
      .page__header.header
      .page__content
        .page__heading
        .page__section
        .list.list_of_products
          .list__item.product.product_view_preview
            .product__title
            .product__description
            .product__image
            .product__price


    .page.page_route_product
      .page__header.header
      .page__content.product.product_view_detail
        .page__heading.product__title
          .product__section
            .product__image
            .product__description
          .product__content
          .product__price
    Ответ написан
    3 комментария
  • Может ли блок наследовать свойства или он должен быть полностью самодостаточным?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Раз родительский элемент управляет отступами, это явно свойства ( элемента ) родительского блока.
    Когда возникают такие дилеммы, нужно просто задать блоку / элементу вопрос: «А кто назначил тебе это правило?» и всё становится понятно — какие-то свойства отъезжают в модификатор, какие-то — в элемент внешнего блока.

    Общие стили:
    .title { display: block }
    .title_align_left { text-align: left }
    .title_align_right { text-align: right }
    .title_align_center { text-align: center }


    Элемент прижат к левому краю (модификатор .title_align_left добавил для наглядности):
    .card
      .card__title.title.title_align_left

    — card__title „говорит“: «внутри меня лежит блок title с модификацией align в значении left»

    Элемент прижат к правому краю:
    .card
      .card__title.title.title_align_right

    — card__title „говорит“: «внутри меня лежит блок title с модификацией align в значении right»

    Элемент выровнен по центру:
    .card
      .card__title.title.title_align_center

    — card__title „говорит“: «внутри меня лежит блок title с модификацией align в значении center»

    Элемент прижат к левому краю, но на другом брейкпоинте выравнивается по правому:
    .card__title { text-align: right }
    @media (min-width: 720px) {
      .card__title { text-align: left }
    }

    .card
      .card__title.title

    — card__title „говорит“: «внутри меня лежит блок title, но я сам управляю его align»

    Надеюсь, аналогия ясна.
    Ответ написан
    3 комментария
  • Какое решение по БЭМ правильнее?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Оба верные, но не имеют никакого отношения к БЭМ.
    Ответ написан
    2 комментария
  • Как можно назвать этот элемент?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Вопрос лучше задавать команде, чтобы не было разногласий. Если команды нет, подойдёт любое семантическое название: https://github.com/yoksel/common-words
    Ответ написан
    Комментировать
  • Оформление навигации по методологии БЭМ?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Выглядит так, словно это два независимых элемента того же блока. Значит ли это, что "menu__icon" должен быть способен существовать вне "menu__item"?


    — Нет. В смысле, что он «не должен». Структуру вложенности задаёт блок. Блок menu «утвердил», что menu__icon лежит внутри menu__item. Если это поменяется, это уже может быть выражено через модификацию блока menu:

    <nav class="menu menu_outside-icon">
      <i class="menu__icon"></i>
      <a class="menu__item" href="#!">
        Main
      </a>
    </nav>


    .menu_outside-icon .menu__icon {
      margin-right: 0;
    }


    или модификацию элемента:

    <nav class="menu">
      <i class="menu__icon menu__icon_outside"></i>
      <a class="menu__item" href="#!">
        Main
      </a>
    </nav>


    .menu__icon_outside {
      margin-right: 0;
    }


    По поводу альтернативной структуры — на самом деле вам нужны миксы. Т. е. вы хотите на одном теге выразить и то, что это иконка (блок icon), и то, что у неё есть какая-то внешняя геометрия, обусловленная вложенностью в другой блок ( т. е. что она одновременно ещё и menu__icon):

    <nav class="menu">
      <a class="link link_no-decoration menu__item" href="#!">
        <i class="icon icon_size_m menu__icon"></i>
        Main
      </a>
    </nav>


    .menu__item {
      padding: 1rem 2rem;
    }
    
    .menu__icon {
      margin-right: 0.5rem;
    }
    
    .link {
      color: blue;
    }
    
    .link_no-decoration,
    .link_no-decoration:hover,
    .link_no-decoration:focus {
      color: inherit;
      text-decoration: none;
      outline: none;
    }
    
    .icon {
      color: inherit;
      line-height: 1;
    }
    
    .icon_size_m {
      width: 1.5rem;
      height 1.5rem;
    }
    Ответ написан
    Комментировать
  • Можно ли в БЭМ верстке подключать reset.css и применять символ * для сброса всех отступов?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Ответ написан
    Комментировать
  • Что в БЭМ значит модификатор-темы?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Это ошибка — такого модификатора быть не может. Скорее всего имелось в виду

    <form class="form  form_size_m form_color_red form_theme_forest"></form>


    Про размер и цвет шрифта вы правильно сказали, а модификатор темы (в значении forest) задаёт базовые значения темы (цвет шрифта, фона, заливки, border'а и т. д.). Любой компонент может быть представлен в тёмной и светлой теме. И это не симметричная инверсия, так что задание отдельных тем (*_theme_light, *_theme_dark) более чем оправдано. Дополнительные темы полезны, если ваш интерфейс стилизуется, например, под Material, или какой-то иной бренд. Т. е. вы просто группируете оформление (включая отступы, если они меняются при переключении темы) в модификатор темы, а в классе самого блока или элемента описывается остальные базовые свойства — лэйаут, позиционирование и т. д.

    P. S. В вашем случае, например, в form_theme_forest могут быть такие свойства:

    .form_theme_forest {
      background-color: #fff;
      color: #000;
    }


    Но вам нужен красный цвет текста, т. е. переопределить color: #000, поэтому вы добавляете класс form_color_red.
    Ответ написан
    Комментировать
  • Опишите правильно структуру FormInput по БЭМ?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    С HTML всё ок (если нет возможности задать CSS-класс , то всё ок), JSX не смотрел, а в CSS смутила вот эта строка:

    &.label_notification_error {
      margin: 4px 0px 0px 20px;
    }


    Смешиваются стили .form-input__label и label_notification_error. Эту проблему решит каскад:

    .form-input {
      &__label {
        margin-bottom: 4px;
      }
    }
    
    .label {
      &_notification_error {
        margin: 4px 0px 0px 20px;
      }
    }


    Если же такой margin нужен только у этой конкретной формы — или вынести его в инлайн-стили, или сделать отдельный модификатор, но для .form-input__label (например,
    .form-input_view_super-form-with-notification-margin .form-input__label_notification_error {
      margin: 4px 0px 0px 20px
    }
    )
    Ответ написан
    Комментировать
  • Где убрать БЭМ-примеси?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Вы, наверное, неправильно поняли — «с БЭМ нет необходимости в миксинах». Т. е. ваша вёрстка вполне соответствует БЭМ (если я правильно понял и container используется для задания ширины макетной сетки). Это просто микс: https://ru.bem.info/methodology/key-concepts/#микс и беглого взгляда на классы достаточно, чтобы понять структуру. А если вы спрячете это за SCSS-миксин, эта нагляднсть «потярется», но вы ничего не «выишраете» с этого — ни уменьшите код на выходе, ни упростите понимание сущностей коллегам (себе через пару месяцев).
    Ответ написан
    5 комментариев
  • Правильно ли в БЭМ применять миксы для задания одинаковых свойств для нескольких элементов?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Да, всё верно! Есть пару советов, основанных уже на личном опыте:
    1. Абсолютно справедливо наблюдение про вынесение текстовых закономерностей в самостоятельный блок. Блок text отлично подходит. Но если семантически (и в дизайне) этот текст соответсвует заголовку (жирность, бо́льший размер шрифта, можно использовать тег <h1-h6>), то я завожу отдельный блок heading. Если используется шаблонизатор (React, Pug, Handlebars, etc.), то задание тега удобно ещё положить в
    …/heading/heading.<jsx | tsx | pug | html | yet-another-templater>
    . Тогда микс будет более «семантичным» тоже:

    /* …/heading/heading.css */
    .heading {
      font-weight: bold;
    }
    
    /* …/heading_size/heading_size.css */
    .heading_size_s {
      font-size: 18px;
    }
    
    .heading_size_m {
      font-size: 24px;
    }
    
    .heading_size_x {
      font-size: 28px;
    }


    Ну и просто для наглядности:

    /* …/header/header.css */
    .header {
      padding: 4px;
      text-size: 20px;
    }
    
    /* …/header/__text/header__text.css */
    .header__text {
      margin-bottom: 20px;
    }


    <div class="header">
        <h3 class="header__text heading heading_size_x">
            Lorem, ipsum dolor sit amet consectetur, adipisicing elit. Illo sunt iure aperiam sint dolor suscipit aut, delectus nesciunt officiis assumenda iusto quisquam libero similique, ex culpa porro vitae? Enim, qui.
        </h3>
    </div>


    /* …/presentation/presentation.css */
    .presentation {
      padding: 6px;
      background-color: #000;
      color: #ffff;
    }
    
    /* …/presentation/__text/presentation__text.css */
    .presentation__text {
      margin-bottom: 20px;
      color: #123;
    }


    <div class="presentation">
        <h4 class="presentation__text heading heading_size_m">
            Lorem, ipsum dolor sit amet consectetur, adipisicing elit. Illo sunt iure aperiam sint dolor suscipit aut, delectus nesciunt officiis assumenda iusto quisquam libero similique, ex culpa porro vitae? Enim, qui.
        </h4>
    </div>


    /* …/description/description.css */
    .presentation {
      padding: 11px;
      border: 1px solid #000;
      border-radius: 4px;
    }
    
    /* …/description/__text/description__text.css */
    .presentation__text {
      margin-bottom: 16px;
      text-transform: uppercase;
    }




    Lorem, ipsum dolor sit amet consectetur, adipisicing elit. Illo sunt iure aperiam sint dolor suscipit aut, delectus nesciunt officiis assumenda iusto quisquam libero similique, ex culpa porro vitae? Enim, qui.




    NB! У каждого heading оказался свой размер (модификация heading_size_*) и свой тег (<h1-h6>), но вполне может быть и

    <h1 class="heading heading_size_s">Самый главный заголовок, но мелким шрифтом</h1>
    
    <h6 class="heading heading_size_xl">Заголовок под-под-подраздела, но крупным шрифтом</h6>


    2. Если же это просто текст (подзаголовок, описание раздела, мета-информация), то просто модификация текста тоже сработает:

    /* …/text/text.css */
    .text {
      padding: 11px;
      border: 1px solid #000;
      border-radius: 4px;
    }
    
    /* …/text/_weight/text_weight.css */
    .text_weight_bold {
      font-weight: bold;
    }
    
    /* …/text/_style/text_style.css */
    .text_style_italic {
      font-style: italic;
    }
    
    /* …/text/_decoration/text_decoration.css */
    .text_ transform_uppercase {
      text-transform: uppercase;
    }


    <div class="header">
        <div class="header__text text text_weight_bold">
            Lorem, ipsum dolor sit amet consectetur, adipisicing elit. Illo sunt iure aperiam sint dolor suscipit aut, delectus nesciunt officiis assumenda iusto quisquam libero similique, ex culpa porro vitae? Enim, qui.
        </div>
    </div>
    <div class="presentation">
        <div class="presentation__text text text_style_italic">
            Lorem, ipsum dolor sit amet consectetur, adipisicing elit. Illo sunt iure aperiam sint dolor suscipit aut, delectus nesciunt officiis assumenda iusto quisquam libero similique, ex culpa porro vitae? Enim, qui.
        </div>
    </div>
    <div class=" description">
        <div class=" description__text text text_weight_bold text_ transform_uppercase">
            Lorem, ipsum dolor sit amet consectetur, adipisicing elit. Illo sunt iure aperiam sint dolor suscipit aut, delectus nesciunt officiis assumenda iusto quisquam libero similique, ex culpa porro vitae? Enim, qui.
        </div>
    </div>
    Ответ написан
    Комментировать
  • Нужны ли здесь модификаторы?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    1. Если делать по БЭМ, то да, правильно выделять каждое отличие от базовой реализации в отдельный модификатор (по возможности группируя их по признакам: размер, состояние, оформление + одиночные «булевы» модификаторы «disabled», «loading»). Хорошо сделано, например, в https://ru.bem.info/libraries/classic/bem-componen.... Иконка внутри — это не модификатор, это просто вложенный блок. Если вложенный блок меняет внешний вид, то да, тут использование модификатора оправдано. Например:
    <button type="button" class="btn btn_size_large btn_state_success">
      Подробнее
    </button>
    
    <a href="/article" class="btn btn_size_large btn_state_success">
      Подробнее
    </a>
    
    <button type="button" class="btn btn_size_large btn_type_like">
      <span class="icon icon_size_large icon_type_thumb-up icon_state_success"></span>
    </button>
    
    <button type="button" class="btn btn_size_large btn_type_dislike btn_with-count">
      <span class="icon icon_size_large icon_type_thumb-down icon_state_error"></span>
      <span class="btn__count">12</span>
    </button>


    2. Select — это три блока: Button + Popup с Menu
    Ответ написан
    2 комментария
  • Как правильно по бэм?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Или, стиснув зубы, использовать каскад:

    .header__menu.menu .menu__item {
      /* … */
    }


    или использовать. модификатор — вы пытаетесь модифицировать внутреннее содержимое блока, основываясь на каких-то специфических для этого блока параметрах (расположение внутри header) — резонный повод для модификатора:

    .menu_view_header .menu__item {
      /* … */
    }


    Первый вариант на фоне второго кажется менее «БЭМ», так что советую модификатор.
    Ответ написан
  • Как лучше писать отступы для BEM блоков?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    То, что написал Сергей delphinpro, не имеет отношения к БЭМ — из-за таких «советов» у Егор Живагин потом куча проблем и ложное представление о методологии.
    Как советует Михаил — посмотрите на Tailwind — там куча примеров готовых компонентов с уже расставленными классами. Так вот, Tailwind к БЭМ тоже не имеет никакого отношения, хотя именно там используются «атомарные стили» вида mt-40 / pd-20 / и т. д. Понимание концепции БЭМ стоит начинать с bem.info, а если останутся или появятся вопросы — в официальный канал @bem_ru.
    Ответ написан
    2 комментария
  • Можно ли вкладывать элементы одного блока в другой?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    5 комментариев
  • Как изучить js бэм?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
  • Как правильнее задавать классы по BEM?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Оба варианта корректны.
    Ответ написан
    Комментировать
  • Когда использовать микс, а когда модификатор?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    Первое, что нужно научиться делать — находить повторяющиеся сущности (которые в последствии станут Блоками и Элементами). Вы уже пытаетесь сделать это, но пока получается слишком многословно, судя по количеству классов и это, очевидно, сбивает с толку.
    Я уже рассказывал на последнем БЭМапе (https://youtu.be/d4dcGj8abv0) о том, как я ищу эти повторяющиеся закономерности, поэтому постараюсь кратко:
    1) Собираем и группируем «данные»
    Разберём «шапку» и «подвал». И там, и там есть логотип, какая-то навигация, контактная информация, ссылки на соц. сети, в шапке есть кнопка:
    1.1) «Шапка»

    {
      logo: {
        img: 'путь до картинки',
        text: '…',
      },
      contacts: [
        'телефон',
        'email',
        'график работы',
        'адрес',
        'соц. сети',
        'кнопка обратной связи',
      ],
      navigation: [
        'пункт меню…',
        'пункт меню…',
        'пункт меню…',
      ]
    }


    1.2) В «подвале» почти то же самое, что-то в другом порядке, но это неважно, и нет «кнопки обратной связи» из секции «Контактов».

    1.3) Есть ещё самостоятельные секции «Свяжитесь с нами» на главной странице и на странице контактов, которые тоже используют пункты из секции «Контактов» (теперь уже понятно, что такое частое повторение позволяет выделить это в блок).

    1.4) Логотип и навигацию тоже выделим в блоки (я разделил логотип на два элемента — изображение и текст, потому что на малых экранах текст превращается в замыленое нечитаемое говно, поэтому его лучше убрать).

    1.5) Получается какая-то такая структура:

    // Блок логотипа
    {
      logo: [
        { img: '…' },
        { text: '…' },
      ]
    }
    
    // Блок контактов
    {
      contacts: [
        { tel: '…' },
        { email: '…' },
        { schedule: '…' },
        { address: '…' },
        { socials: [
          { vk: '…' },
          { telegram: '…' },
          { instagram: '…' },
        ] },
        { map: '…' },
        { feedback: '…' },
      ]
    }
    
    // Блок навигации
    {
      navigation: [
        { item: '', link: '…' },
        { item: '', link: '…' },
        { item: '', link: '…' },
      ]
    }
    
    // Блок «Шапки»
    {
      header: [
        {
          logo: [] // Тут всё без изменений
        },
        {
          contacts: [
            'tel',
            'email',
            'schedule',
            'address',
            'socials',
            'feedback',
          ]
        },
        {
          navigation: [] // Тут тоже без изменений
        }
      ]
    }
    
    // Блок «Подвала»
    {
      footer: [
        {
          logo: [] // Тут всё без изменений
        },
        {
          navigation: [ // Тут почти без изменений
            // …
            'Марки автомобилей' // Без выпадающего списка
            // …
          ]
        },
        {
          contacts: [
            'tel',
            'email',
            'address',
            'socials',
            'schedule', // Без иконки
          ]
        },
      ]
    }



    2) Вроде, пока хватит. «БЭМизируем» эти данные.
    Структура в формате JSON

    // Блок логотипа
    {
      block: 'logo'
      content: [
        { elem: 'img', src: '…' },
        { text: '…' },
      ]
    }
    
    // Блок контактов
    {
      block: 'contacts'
      content: [
        { elem: 'tel', content: '…' },
        { elem: 'email', content: '…' },
        { elem: 'schedule', content: '…' },
        { elem: 'address', content: '…' },
        { elem: 'socials', content: [
          { elem: 'vk', content: '…' },
          { elem: 'telegram', content: '…' },
          { elem: 'instagram', content: '…' },
        ] },
        { elem: 'map', content: '…' },
        { elem: 'feedback', content: '…' },
      ]
    }
    
    // Блок навигации
    {
      navigation: [
        { item: '', link: '…' },
        { item: '', link: '…' },
        { item: '', link: '…' },
      ]
    }
    
    // Блок «Шапки»
    {
      header: [
        {
          block: 'logo'
        },
        {
          block: 'contacts',
          // У этого блока определённо свой контент,
          // будем отличать его от других вариантов
          // этого блока с помощью модификатора
          mods: { view: 'header' },
          content: [
            { elem: 'tel' },
            { elem: 'email' },
            { elem: 'schedule' },
            { elem: 'address' },
            { elem: 'socials' },
            { elem: 'feedback' },
          ]
        },
        {
          block: 'navigation',
          // Этот блок по внешнему виду отличается от блока в «Подвале»,
          // поэтому обозначим его модификатором
          mods: { view: 'header' },
          content: [
            // …
            // У одного пункта выпадающий список
            {
              elem: 'item',
              item: 'Марки автомобилей',
              elemMods: { dropdown: true },
              content: [
                // …
                { elem: 'subitem', item: 'Infinity', href: '…' }
              ]
            },
            // …
          ]
        }
      ]
    }
    
    // Блок «Подвала»
    {
      footer: [
        {
          block: 'logo'
        },
        {
          block: 'navigation',
          mods: { view: 'footer' },
          content: [ // Тут почти без изменений
            // …
            { elem: 'Марки автомобилей', link: '…' }, // Без выпадающего списка
            // …
          ]
        },
        {
          contacts: [
            'tel',
            'email',
            'address',
            'socials',
            { elem: 'schedule', elemMods: { noIcon: true } }, // Без иконки
          ]
        },
      ]
    }


    2.1) Базовый лэйаут: https://codepen.io/Realetive/pen/PoGRjZo
    2.2) Добавляем обёртки для группировки некоторых элементов: https://codepen.io/Realetive/pen/KKgoBdN
    Про обёртки и зачем они нужны уже обсуждалось в https://ru.bem.info/forum/656/, очень советую.
    2.3) Добавим отступы: https://codepen.io/Realetive/pen/bGwvjow
    Как видите, миксы по-прежнему не нужны.
    3) У контента есть фиксированная ширина, обозначим её через класс-элемент блока page: например, .page__layout:
    https://codepen.io/Realetive/pen/WNGzgjJ
    Но вёрстка закономерно сбилась, потому что классы, которые мы назначали для родительского уровня, «поднялись» ещё н один уровень. Добавим ещё обёртки, чтобы «выровнять» лэйаут: стили header перенесутся в header__body, из footer в footer__body: https://codepen.io/Realetive/pen/wvzmEpy
    4) Получилось достаточно много «лишних» обёрток только лишь для позиционирования. Можно было бы этого избежать, если бы стили были описаны в одном классе. Но тогда мы лишимся пользы разделения логики благодаря БЭМ-неймингу. Вместо этого объединим эти слои с помощью миксов: page__header + header, header__body + page__layout, page__footer + footer, footer__body + page__layout: https://codepen.io/Realetive/pen/RwGMYyV

    Вот наконец и пригодились миксы. Они лишь позволяют объединить две сущности по схожему признаку (например, лэйаут и позиционирование) на одном теге. А модификаторы обозначают различие между двумя одинаковыми сущностями (например, в одном месте у элемента есть иконка, в другом — нет, хотя это всё тот же элемент).

    Блок с контактами делается аналогичным способом:
    .page__section.page__section_view_feedback
      .page__layout
        .form.form_view_feedback.page__column_width_half (миксуем блок формы обратной связи и лэйаут 1/2 колонки)
          …
        .contacts_view_feedback.page__column_width_half
          .contacts__info
            .contacts__address
            .contacts__email
            .contacts__tel
            .contacts__schedule
          .contacts__map
    Ответ написан
    1 комментарий
  • Как правильно назвать вложенный блок в BEM?

    Realetive
    @Realetive
    MODX Ambassador России, самозванный БЭМ-евангелист
    На абстрактных примерах без дизайна — тут только гадать, но в реальном проекте балансом между здравым смыслом и реиспользованием будет 1 вариант:

    <div class="card">
      <div class="card__header">
        <h2 class="card__header-title">Заголовок</h2>
      </div>
      <div class="card__footer">
        <h2 class="card__footer-title">Заголовок</h2>
      </div>
    </div>


    Т. к. он избавляет от необходимости использовать каскад и эффективно использует нейминг для обозначения каждой сущности. Также я убрал префикс c-, т. к. не вижу в нём никакого смысла.

    Вариант с c-card-header и c-card-footer смысла особого не имеет, т. к. создаёт ложное впечатление, что эти блоки могут использовться за пределами блока c-card.

    Альтернативным правильным решением может быть использованием модификаторов элемента card__header для описания их рзличий в зависимости от расположения:

    <div class="card">
      <div class="card__header">
        <h2 class="card__title card__title_position_header">Заголовок</h2>
      </div>
      <div class="card__footer">
        <h2 class="card__title card__title_position_footer">Заголовок</h2>
      </div>
    </div>


    Стили в card__title в этом случае сгруппируют общие свойства, а в модификаторах опишутся различия.
    Ответ написан