← Blog · · Zespół ConvertCaseHQ · 6 min czytania

Nazewnictwo klas w CSS: kebab-case, BEM i inne konwencje

Większość nazw klas CSS pisze się małymi literami w kebab-case (.site-header, .price-tag), bo tak samo CSS nazywa własne elementy: background-color, font-size, flex-direction. BEM dokłada do tego stałą strukturę, block__element--modifier, więc klasa taka jak card__title--large mówi, do którego komponentu należy, którą jego częścią jest i jaki wariant pokazuje.

Poniżej: co w CSS rozróżnia wielkość liter, a co nie, dlaczego kebab-case stał się domyślny, jak naprawdę brzmią reguły nazewnictwa BEM i kiedy inne podejście sprawia, że BEM jest zbędny.

Co w CSS rozróżnia wielkość liter, a co nie

Własna składnia CSS nie rozróżnia wielkości liter w zakresie ASCII, więc COLOR: RED działa dokładnie tak samo jak color: red. Trzy rzeczy działają inaczej:

  • Nazwy klas rozróżniają wielkość liter. .Card nie pasuje do class="card". Jedynym wyjątkiem jest strona w trybie quirks, w którym przeglądarki dopasowują nazwy klas bez rozróżniania wielkości liter, co jest kolejnym powodem, by każdą stronę zaczynać od <!DOCTYPE html>.
  • Właściwości niestandardowe rozróżniają wielkość liter. --brand-color i --Brand-Color to dwie różne zmienne.
  • Nazwy elementów i atrybutów HTML jej nie rozróżniają. W dokumencie HTML DIV i div wybierają te same elementy. W XML byłyby różne.

Najprostszy sposób, żeby nigdy więcej o tym nie myśleć, to pisać wszystkie nazwy klas i właściwości niestandardowych małymi literami. O tym, jak z wielkością liter radzą sobie inne języki i systemy plików, przeczytasz w naszym porównaniu wrażliwości na wielkość liter.

Dlaczego kebab-case wygrał w nazwach klas CSS

Nic w CSS nie narzuca kebab-case nazwom klas. .cardTitle i .card_title są poprawne. Myślniki mają sens, bo wszystko wokół nazwy klasy już ich używa: nazwy właściwości, wartości (jak space-between) i atrybuty HTML, takie jak aria-label i data-user-id. Klasa w camelCase w arkuszu pełnym myślników wygląda jak literówka.

JavaScript to miejsce, w którym kebab-case staje się kłopotliwy, bo myślniki nie są dozwolone w identyfikatorach. Przeglądarka radzi sobie z własnymi przypadkami: data-user-id jest odczytywane jako element.dataset.userId, a background-color staje się element.style.backgroundColor. Nazwy klas zwykle pozostają ciągami znaków (classList.add("is-open")), więc im to nie przeszkadza.

Wyjątkiem są moduły CSS (CSS Modules). Moduł CSS eksportuje nazwy klas do JavaScriptu jako obiekt, więc .card-title trzeba zapisać jako styles["card-title"], a .cardTitle staje się czystszym styles.cardTitle. To jedyna konfiguracja, w której przestawilibyśmy nazwy klas na camelCase.

Nazewnictwo BEM: blok, element, modyfikator

BEM (Block, Element, Modifier) wywodzi się z Yandexa. Strona z historią metodologii wiąże początki prac z rokiem 2005, za początek BEM uznaje wydanie frameworku Lego 2.0 przez Yandex w marcu 2009 roku, a przejście na open source datuje na rok 2010. Reguły nazewnictwa są krótkie:

  • Blok (block): samodzielny komponent, który ma sens sam w sobie, taki jak .card, .search-form czy .menu.
  • Element: część bloku, która nie ma znaczenia poza nim; nazwa to blok, dwa podkreślniki, element: .card__title, .menu__item.
  • Modyfikator (modifier): flaga zmieniająca wygląd, zachowanie lub stan; nazwa to blok lub element, dwa myślniki, modyfikator: .card--featured, .card__button--disabled. Modyfikator może też być parą klucz i wartość: .form--theme-xmas.

Wyrazy wewnątrz każdej części oddziela się pojedynczymi myślnikami, jak w .search-form__submit-button. Oto cały komponent:

<article class="card card--featured">
  <h2 class="card__title">Spring sale</h2>
  <p class="card__body">Everything 20% off this week.</p>
  <a class="card__button card__button--disabled" href="/sale">Shop now</a>
</article>
.card { border: 1px solid #ddd; padding: 1rem; }
.card--featured { border-color: gold; }
.card__title { font-size: 1.25rem; }
.card__button--disabled { opacity: 0.5; pointer-events: none; }

Klasyczny BEM a styl z dwoma myślnikami

Jeśli zajrzysz na oficjalną stronę metodologii, bem.info, modyfikatory wyglądają inaczej. Klasyczny schemat oddziela modyfikatory pojedynczym podkreślnikiem: menu_hidden, menu__item_visible, menu__item_type_radio. Wersja z -- jest tam wymieniona jako alternatywa, „Two Dashes style” (styl dwóch myślników), i to ją opisuje getbem.com. Obie są poprawnym BEM; tylko nie mieszaj ich w jednej bazie kodu. bem.info zwraca też uwagę na drobny haczyk związany z myślnikami: podwójny myślnik w komentarzu HTML może nie przejść walidacji.

Reguły BEM, w których łatwo się pomylić

  1. Żadnych elementów elementów. Tytuł wewnątrz nagłówka karty to nadal card__title, a nie card__header__title. W HTML elementy możesz zagnieżdżać tak głęboko, jak chcesz; nazwy pozostają płaskie. Uzasadnienie bem.info: przy nazwach łańcuchowych nie można przenieść, dodać ani usunąć elementu bez zmiany istniejącego kodu.
  2. Modyfikatory nigdy nie występują samodzielnie. Pisz class="button button--primary", a nie class="button--primary". Modyfikator tylko uzupełnia klasę bazową.
  3. Używaj selektorów z jedną klasą. .card__title, a nie .card .card__title ani h2.card__title. Przyjętym wyjątkiem jest modyfikator bloku, który zmienia jego elementy: .card--featured .card__title.
  4. Nazywaj modyfikatory według celu. To nasza opinia, a nie reguła BEM: --featured albo --error przetrwają redesign, a --yellow staje się kłamstwem w dniu, w którym zmienia się kolor marki.
  5. Oddziel punkty zaczepienia dla JavaScriptu od klas stylów. To również nasza opinia: wybieraj elementy w skryptach atrybutem data, takim jak data-action="close", a nie klasą .card__button, żeby zmiana nazwy klasy ze względów stylistycznych nie mogła zepsuć działania.

Późniejsza zmiana nazwy bloku to w większości wyszukiwanie i zamiana. Wklej szablon do naszego narzędzia Znajdź i zamień, włącz tryb regex i zamień card(__|--) na product-card$1: każda klasa elementu i modyfikatora przejdzie na nową nazwę bloku, a liczba dopasowań powie Ci, ile ich zmieniono. Samą klasę card zmień osobno, żeby nie złapać niepowiązanych wyrazów.

Pisanie BEM w Sass i w natywnym zagnieżdżaniu CSS

Selektor rodzica w Sass potrafi dodać sufiks do zewnętrznego selektora, a jego dokumentacja używa BEM jako przykładu. Natywne zagnieżdżanie CSS tego nie potrafi i MDN zwraca na to wprost uwagę: zagnieżdżone &__title jest odczytywane jako selektor typu, więc nie wyprodukuje .card__title.

// Sass: works
.card {
  &__title { font-size: 1.25rem; }    // compiles to .card__title
  &--featured { border-color: gold; } // compiles to .card--featured
}
/* Native CSS nesting: write the full class names */
.card {
  border: 1px solid #ddd;
  &.card--featured { border-color: gold; } /* .card.card--featured */
}
.card__title { font-size: 1.25rem; }

Poza BEM: kiedy go nie potrzebujesz

BEM istnieje po to, by nazwy klas nie kolidowały i by struktura była widoczna w globalnym arkuszu stylów. Jeśli coś innego rozwiązuje problem kolizji, jego długie nazwy dają mniej:

  • Moduły CSS (CSS Modules) domyślnie ograniczają nazwy klas do zakresu lokalnego, więc zwykłe .title w jednym komponencie nie zderzy się z .title w innym.
  • CSS oparty na klasach użytkowych (utility-first), jak Tailwind, w dużej mierze zastępuje własne nazwy klas gotowymi klasami użytkowymi, takimi jak font-bold, więc nazewnictwo przenosi się do Twoich komponentów.
  • Małe witryny z garstką komponentów często dobrze radzą sobie ze zwykłym kebab-case i prefiksem dla każdego komponentu.

Nawet wtedy kebab-case pozostaje bezpiecznym domyślnym wyborem dla każdej nazwy klasy, którą piszesz.

Zasady praktyczne

  • Małe litery w kebab-case dla nazw klas i właściwości niestandardowych, zawsze.
  • BEM, gdy wiele osób dzieli jeden globalny arkusz stylów: block__element--modifier, płaskie nazwy elementów, modyfikatory obok klasy bazowej.
  • Nazwy klas w camelCase tylko wtedy, gdy narzędzie takie jak moduły CSS udostępnia je JavaScriptowi.

Zamieniasz nazwę komponentu na klasę? Wpisz „Product Card” do naszego konwertera wielkości liter, a przycisk kebab-case da Ci product-card. Konwencje dla wszystkich pozostałych warstw projektu, od zmiennych środowiskowych po adresy URL, znajdziesz w naszej ściągawce ze stylami nazewnictwa dla programistów.

© 2026 ConvertCaseHQ. Wszelkie prawa zastrzeżone.