← Blog · · ConvertCaseHQ-Team · 6 Min. Lesezeit

CSS-Namenskonventionen: kebab-case, BEM und mehr

Die meisten CSS-Klassennamen stehen in kleingeschriebenem kebab-case (.site-header, .price-tag), weil CSS seine eigenen Dinge genauso benennt: background-color, font-size, flex-direction. BEM baut darauf mit einer festen Struktur auf, block__element--modifier, sodass eine Klasse wie card__title--large dir sagt, zu welcher Komponente sie gehört, welcher Teil davon sie ist und welche Variante sie zeigt.

Im Folgenden: wobei CSS zwischen Groß- und Kleinschreibung unterscheidet und wobei nicht, warum kebab-case zum Standard wurde, wie die Namensregeln von BEM tatsächlich lauten und wann ein anderer Ansatz BEM überflüssig macht.

Was in CSS zwischen Groß- und Kleinschreibung unterscheidet und was nicht

Die Syntax von CSS selbst unterscheidet im ASCII-Bereich nicht zwischen Groß- und Kleinschreibung, sodass COLOR: RED genau wie color: red funktioniert. Drei Dinge verhalten sich anders:

  • Klassennamen unterscheiden zwischen Groß- und Kleinschreibung. .Card passt nicht auf class="card". Die einzige Ausnahme ist eine Seite im Quirks-Modus, in der Browser Klassennamen ohne Unterscheidung vergleichen. Das ist ein weiterer Grund, jede Seite mit <!DOCTYPE html> zu beginnen.
  • Custom Properties unterscheiden zwischen Groß- und Kleinschreibung. --brand-color und --Brand-Color sind zwei verschiedene Variablen.
  • Namen von HTML-Elementen und -Attributen tun das nicht. In einem HTML-Dokument wählen DIV und div dieselben Elemente aus. In XML wären sie verschieden.

Am einfachsten denkst du nie wieder darüber nach, wenn du jeden Klassennamen und jede Custom Property kleinschreibst. Wie andere Sprachen und Dateisysteme mit der Groß- und Kleinschreibung umgehen, steht in unserem Vergleich der Groß- und Kleinschreibung in Programmiersprachen.

Warum sich kebab-case bei CSS-Klassennamen durchgesetzt hat

Nichts in CSS erzwingt kebab-case für Klassennamen. .cardTitle und .card_title sind beide gültig. Bindestriche ergeben Sinn, weil alles rund um einen Klassennamen sie schon verwendet: Eigenschaftsnamen, Werte wie space-between und HTML-Attribute wie aria-label und data-user-id. Eine camelCase-Klasse in einem Stylesheet voller Bindestriche sieht aus wie ein Tippfehler.

In JavaScript wird kebab-case unbequem, weil Bindestriche in Bezeichnern nicht erlaubt sind. Die eigenen Fälle löst der Browser selbst: data-user-id liest du als element.dataset.userId, und aus background-color wird element.style.backgroundColor. Klassennamen bleiben meist Strings (classList.add("is-open")), ihnen ist das also egal.

Die Ausnahme sind CSS Modules. Ein CSS Module exportiert seine Klassennamen als Objekt nach JavaScript, deshalb muss .card-title als styles["card-title"] geschrieben werden, während .cardTitle zum übersichtlicheren styles.cardTitle wird. Das ist die einzige Konstellation, in der wir Klassennamen auf camelCase umstellen würden.

BEM-Benennung: Block, Element, Modifier

BEM (Block, Element, Modifier) stammt von Yandex. Die Geschichtsseite der Methodik führt die Arbeit bis 2005 zurück, nennt die Veröffentlichung des Yandex-Frameworks Lego 2.0 im März 2009 als Beginn von BEM und datiert den Schritt zu Open Source auf 2010. Die Benennungsregeln sind kurz:

  • Block: eine eigenständige Komponente, die für sich allein Sinn ergibt, etwa .card, .search-form oder .menu.
  • Element: ein Teil eines Blocks, der außerhalb davon keine Bedeutung hat, benannt als Block, zwei Unterstriche, Element: .card__title, .menu__item.
  • Modifier: ein Flag, das Aussehen, Verhalten oder Zustand verändert, benannt als Block oder Element, zwei Bindestriche, Modifier: .card--featured, .card__button--disabled. Ein Modifier kann auch aus Schlüssel und Wert bestehen: .form--theme-xmas.

Wörter innerhalb jedes Teils werden durch einfache Bindestriche getrennt, wie in .search-form__submit-button. Hier ist eine vollständige Komponente:

<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; }

Klassisches BEM vs. der Zwei-Bindestriche-Stil

Wenn du die offizielle Website der Methodik liest, bem.info, sehen die Modifier anders aus. Das klassische Schema trennt Modifier mit einem einzelnen Unterstrich: menu_hidden, menu__item_visible, menu__item_type_radio. Die Variante mit -- ist dort als Alternative aufgeführt, der „Two Dashes style“ (Zwei-Bindestriche-Stil), und sie ist die, die getbem.com dokumentiert. Beide sind legitimes BEM; mische sie nur nicht in einer Codebasis. bem.info weist außerdem auf einen kleinen Haken bei den Bindestrichen hin: Ein doppelter Bindestrich in einem HTML-Kommentar kann die Validierung scheitern lassen.

BEM-Regeln, bei denen man leicht danebenliegt

  1. Keine Elemente von Elementen. Ein Titel im Header einer Karte heißt weiterhin card__title, nicht card__header__title. Im HTML kannst du Elemente beliebig tief verschachteln; die Namen bleiben flach. Die Begründung von bem.info: Bei verketteten Namen kannst du ein Element nicht verschieben, hinzufügen oder entfernen, ohne vorhandenen Code zu ändern.
  2. Modifier stehen nie allein. Schreibe class="button button--primary", nicht class="button--primary". Der Modifier ergänzt die Basisklasse nur.
  3. Verwende einfache Klassenselektoren. .card__title, nicht .card .card__title oder h2.card__title. Die anerkannte Ausnahme ist ein Block-Modifier, der seine Elemente verändert: .card--featured .card__title.
  4. Benenne Modifier nach ihrem Zweck. Das ist unsere Meinung und keine BEM-Regel: --featured oder --error überstehen ein Redesign, während --yellow an dem Tag zur Lüge wird, an dem sich die Markenfarbe ändert.
  5. Halte JavaScript-Hooks aus deinen Style-Klassen heraus. Auch das ist unsere Meinung: Wähle Elemente in Skripten über ein Data-Attribut wie data-action="close" aus statt über .card__button, damit das Umbenennen einer Klasse aus Styling-Gründen das Verhalten nicht kaputtmachen kann.

Einen Block später umzubenennen ist größtenteils Suchen und Ersetzen. Füge ein Template in unser Werkzeug Suchen & Ersetzen ein, schalte den Regex-Modus ein und ersetze card(__|--) durch product-card$1: Jede Element- und Modifier-Klasse zieht auf den neuen Blocknamen um, und die Trefferzahl sagt dir, wie viele sich geändert haben. Benenne die einfache Klasse card separat um, damit du keine unverwandten Wörter erwischst.

BEM mit Sass und mit nativem CSS Nesting schreiben

Der Parent-Selektor von Sass kann dem äußeren Selektor ein Suffix anhängen, und seine Dokumentation verwendet BEM als Beispiel. Natives CSS Nesting kann das nicht, und MDN weist ausdrücklich darauf hin: Ein verschachteltes &__title wird als Typselektor gelesen und erzeugt daher kein .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; }

Jenseits von BEM: Wann du es nicht brauchst

BEM soll verhindern, dass Klassennamen kollidieren, und die Struktur in einem globalen Stylesheet sichtbar machen. Wenn etwas anderes das Kollisionsproblem löst, bringen die langen Namen weniger:

  • CSS Modules begrenzen Klassennamen standardmäßig lokal, sodass ein schlichtes .title in einer Komponente nicht mit .title in einer anderen in Konflikt geraten kann.
  • Utility-first-CSS wie Tailwind ersetzt eigene Klassennamen größtenteils durch vordefinierte Utilities wie font-bold, sodass das Benennen stattdessen in deine Komponenten wandert.
  • Kleine Websites mit einer Handvoll Komponenten kommen oft gut mit schlichtem kebab-case und einem Präfix pro Komponente aus.

Auch dann bleibt kebab-case die sichere Standardwahl für jeden Klassennamen, den du schreibst.

Faustregeln

  • Kleingeschriebenes kebab-case für Klassennamen und Custom Properties, immer.
  • BEM, wenn viele Leute ein globales Stylesheet teilen: block__element--modifier, flache Elementnamen, Modifier neben der Basisklasse.
  • camelCase-Klassennamen nur, wenn ein Werkzeug wie CSS Modules sie JavaScript zur Verfügung stellt.

Du willst aus einem Komponentennamen eine Klasse machen? Tippe „Product Card“ in unseren Case-Konverter, und der Button kebab-case liefert dir product-card. Die Konventionen aller anderen Ebenen eines Projekts, von Umgebungsvariablen bis zu URLs, findest du in unserem Spickzettel für Namenskonventionen.

© 2026 ConvertCaseHQ. Alle Rechte vorbehalten.