Zpět na domů

BEM v Vue: styly pro komponenty

Článek rozebírá použití BEM v Vue pro strukturované styly. Uvádějí se příklady tlačítek s modifikátory, výhody scoped a pravidla škálování. Vhodné pro middle/senior vývojáře.

BEM + Vue: spolehlivý systém stylů
Advertisement 728x90

BEM v Vue: struktura stylů pro škálovatelné komponenty

BEM zůstává aktuální ve projektech s Vue díky přísné hierarchii tříd, která zabraňuje konfliktům stylů v komponentové architektuře. Vue se soustředí na reaktivitu a logiku, zatímco BEM zajišťuje nezávislost bloků a elementů. Tato kombinace minimalizuje zmatek v CSS při růstu aplikace.

BEM je postaven na třech principech:

  • Blok: nezávislá entita jako .header nebo .card, bez vnějších závislostí.
  • Element: část bloku, označená dvojitým podtržením — .button__icon.
  • Modifikátor: varianta nebo stav přes jednoduché podtržení — .button_disabled, .card_theme_dark.

Taková struktura umožňuje izolovat styly, což usnadňuje ladění a refaktorování.

Google AdInline article slot

Stylování v Vue komponentách

Ve Vue se styly píšou uvnitř <style scoped>, což omezuje jejich rozsah na komponentu. Scoped zabraňuje únikům stylů, ale vyžaduje opatrnost s vnořováním.

:deep() se používá pouze pro integraci s externími knihovnami, kde scoped nestačí. Vyhněte se mu pro obcházení vlastní architektury — to je známka problémů ve struktuře.

BEM doplňuje scoped, logicky seskupuje třídy. Blok definuje základní styl, modifikátory — variace, elementy — vnitřní strukturu.

Google AdInline article slot

Praktický příklad: tlačítko se stavy

Bez systému se třídy chaoticky množí. Podívejte se na typickou chybu:

template>
  <button :class="{
    'button-basic': isBasic,
    'button-href': isHref,
    'button-avatar': isAvatar 
  }">
    {{ text }}
  </button>
</template>

Problémy:

  • Absence hierarchie: třídy nejsou spojeny s blokem.
  • Škálování: nové stavy vyžadují dodatečné podmínky.
  • Čitelnost: s časem se logika ztrácí.

S BEM se šablona zjednodušuje a dokumentuje:

Google AdInline article slot
template>
  <button :class="[
    'button',
    {
      'button_disabled': disabled,
      'button_loading': loading,
    },
    {
      'button_size_xl': size === 'xl',
      'button_size_l': size === 'l',
    },
    {
      'button_primary': color === 'primary',
      'button_secondary': color === 'secondary',
    }
  ]">
    {{ text }}
  </button>
</template>

Třídy jsou rozděleny podle sémantiky: základní blok, stavy, velikosti, témy. V CSS:

.button {
  /* základní styly */
  padding: 12px 24px;
  border: none;
  border-radius: 4px;
}

.button_disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.button_loading {
  position: relative;
}

.button_primary:not(.button_disabled):hover {
  background-color: #0055ff;
}

Selektor :not() filtruje konfliktující stavy bez zbytečných tříd.

Škálování a týmová práce

Ve velkých projektech BEM snižuje kognitivní zátěž: vývojář vidí blok a jeho modifikátory přímo v šabloně. Není třeba prohledávat CSS, abyste pochopili styly.

Výhody v týmu:

  • Předvídatelnost: názvy tříd odrážejí účel.
  • Izolace: bloky na sebe nemají vliv.
  • Rozšiřitelnost: nové modifikátory se přidávají bez refaktorování.

Příklad složitého komponentu — karta produktu s tématy a velikostmi:

template>
  <div class="card" :class="[
    `card_size_${size}`,
    `card_theme_${theme}`
  ]
  ">
    <div class="card__image"></div>
    <div class="card__title">{{ title }}</div>
    <button class="card__button button">Koupit</button>
  </div>
</template>

Elementy uvnitř bloku dědí kontext, ale zůstávají nezávislé.

Kdy se vzdát BEM

BEM je nadbytečný pro prototypy nebo landing pages: Tailwind nebo utility třídy jsou rychlejší. Používejte BEM v projektech s dlouhodobou podporou, týmem a složitým UI.

Co je důležité

  • BEM doplňuje Vue, zajišťuje přísnou hierarchii bez konfliktů se scoped.
  • Modifikátory seskupují stavy a varianty, zjednodušují šablony.
  • :deep() — pouze pro externí knihovny, ne pro vnitřní strukturu.
  • Ve velkých projektech BEM zrychluje onboarding a refaktorování.
  • Testujte na reálném komponentu: čitelnost se okamžitě zvýší.

— Editorial Team

Advertisement 728x90

Číst dál