/css-clean-structured-short

Convention for naming selectors and structuring stylesheets (and other people who don't like BEM ;)

css-clean-structured-short

Convention for structuring stylesheets and naming selectors (and people who don't like BEM ;) I began to hate having these BEM-style, amazing long selectors. They waste bandwidth and contain a lot of duplication. Especially in combination they started owning my source code. They force me to use thousands of keystrokes while editing. They are hard to find within LESS/SCSS if & was used a lot. So I tried to find a balance between specificity and code amount …

TL;TR

  • Never ever select tag names!
  • Differentiate between elements, components, modules
  • Use PascalCase for your defined elements, components, modules …
  • … and camelCase for their own parts

HTML example

<!-- Module -->
<div class="TeaserList">

  <!-- Element -->
  <p class="Headline -primary">Latest Updates</p>

  <!-- Component -->
  <article class="Teaser -large  grid-span-all">
    <header class="header">

      <!-- Element -->
      <p class="Headline -tertiary">Universe on panic</p>

      <!-- Element -->
      <h1 class="Headline -secondary">42 not the answer to life, the universe and everything!</h1>

    </header>

    <p class="body _expanded">
      Further studies revealed: 42 is not the answer to life, the universe and everything. It's 43!
      Someone made a off by one error within the calculation algorithm.
    </p>

    <!-- Element -->
    <a class="Link -arrowRight" href="/article/42-not-answer-to-life.html">Read more</a>

    <!-- Component -->
    <footer class="ArticleFooter -small">
      <p>
        published on <time class="publishDate" datetime="2017-06-05 13:58">June 5th, 2017</time> by

        <!-- Element -->
        <a class="Link -author" href="/user/bluemoehre.html" rel="author">bluemoehre</a>
      </p>
    </footer>

  </article>

  <!-- Element -->
  <a class="Link -showMore" href="?p=2">more</a>

</div>

Structure

We will define primary selectors (1st level scope) and secondary selectors (2nd level scope). Primary selectors are written in PascalCase and grouped into …

  • elements Uncomplex compounds like headlines, buttons, pictures with icons or action buttons.
  • components Less complex compounds without own context like article footers, form fields (including label & input) May contain elements & components & secondary (custom) elements.
  • modules Complex compounds with own context. May contain elements & components & secondary (custom) elements

Secondary selectors are written in camelCase. Global helpers (e.g. grid classes) will also use camelCase.

.PrimarySelector {}
.PrimarySelector .secondarySelector {}

Naming schema

HTML:

<div class="ComponentName -variantName _stateName"></div>

CSS:

.ComponentName.-variantName._stateName {}

General Naming

.fooBar                    Foobar class
.fooBar.-variant           Foobar class inheriting from .fooBar but with modifications
.fooBar.-n-2               Foobar class inheriting from .fooBar but with counter as a helper selector
.fooBar._collapsed         Foobar class in collapsed state
.fooBar._active            Foobar class in active state
#fooBar.-variant._active   Same rules for IDs
#fooBar-variant_active     Similar rules for special IDs

Modules/Components/Elements Naming

.FooBar                    Foobar module/component
.FooBar.-variant           Foobar module/component variant inheriting from .FooBar but with some different styles
.LargeFooBar               Foobar module/component which is too different from .FooBar to use inheritance
.FooBar .Headline          Headline of .FooBar using inheritance from global headline component
.FooBar .headline          Headline of .FooBar without any inheritance
#FooBar.-variant           Same rules for IDs
#FooBar-variant_active     Similar rules for special IDs

Body-Switches

.ifFooBarPresent_hide       Hide this element if HTML-Element has class "fooBarPresent"
.ifFooBarError_show         Show this element if HTML-Element has class "fooBarError" (display: initial)
.ifFooBarError_showInline   Show this element if HTML-Element has class "fooBarError" (display: inline)
.ifFooBarError_showBlock    Show this element if HTML-Element has class "fooBarError" (display: block)

JS-Selectors

Please use own selectors for JS so your scripts will never crash, when layout is modified, classes renamed or moved etc. You can use normal selectors if they can be configured inline with HTML.

jsFoobar                   For selecting an element to handle with Foobar function/Plugin
jsFoobarButtons

Order of things

Due to cascading/inheritance keep order of classes here like DOM-Tree.

  • single/standalone elements (need default formattings, so keep them first)
  • outer blocks (may contain same classes as their inner blocks …)
  • inner blocks (… so to raise priority of latter blocks define them at the end)