Skip to content

Commit

Permalink
Add css style guide section on open/closed principle
Browse files Browse the repository at this point in the history
  • Loading branch information
weltenwort committed Jun 12, 2017
1 parent 27b869a commit 4fa3418
Showing 1 changed file with 108 additions and 0 deletions.
108 changes: 108 additions & 0 deletions style_guides/css_style_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- [Don't use multiple modifier classes together](#dont-use-multiple-modifier-classes-together)
- [How to apply DRY](#how-to-apply-dry)
- [Compelling reasons for using mixins](#compelling-reasons-for-using-mixins)
- [The Open/Closed Principle](#the-openclosed-principle)

## Selecting elements

Expand Down Expand Up @@ -103,6 +104,8 @@ Our CSS naming convention is based on BEM:

* [BEM 101 (CSS Tricks)](https://css-tricks.com/bem-101/)
* [Getting your head around BEM syntax (CSS Wizardry)](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/)
* [CSS for BEM (bem.info)](https://en.bem.info/methodology/css/)
* [CSS Guidelines](https://cssguidelin.es/)

## Concepts

Expand Down Expand Up @@ -461,3 +464,108 @@ border-radius changes for all buttons, you only need to change it there. Or if
the designers anticipate that all new types of buttons should have the same
border-radius, then you can just extend this mixin when you create a new button
base class.

### The Open/Closed Principle

References:

* [The Open/Closed Principle on bem.info](https://en.bem.info/methodology/css/#openclosed-principle)
* [The Open/Closed Principle in CSS Guidelines](https://cssguidelin.es/#the-openclosed-principle)
* [The Open/Closed Principle on Wikipedia](https://en.wikipedia.org/wiki/Open/closed_principle)

Formally the open/closed principle reads

> Software entities (classes, modules, functions, etc.) should be **open for
> extension**, but **closed for modification**.
Applied to CSS, this means that CSS rulesets should be treated as immutable.
Once a declaration block for a specific selector has been defined, its style
should not be overridden in a different ruleset using the same selector:

```css
// BAD
.button {
color: blue;
font-size: 1.5em;
padding: 16px;
}

.header .button {
font-size: 1em;
padding: 4px;
}
```

Not only does this example violate the semantics of a BEM block, it also
**modifies** the meaning of `.button` depending on the context. Instead, this
could be expressed using a block modifier or a completely separate class which
is kept DRY using mixins:

```css
// GOOD
.button {
color: blue;
font-size: 1.5em;
}

.button--small {
font-size: 1em;
padding: 4px;
}
```

#### Exception: Block Groups

It is a common occurrence that groups of blocks within a container should be
styled differently that single blocks in order to indicate their association.
But using pure BEM mixes of blocks and group modifiers would sometimes require
a large number of modifiers to be applied to multiple elements to achieve that,
e.g.:

```css
.kuiCard { /* ... */ }

.kuiCard__description { /* ... */ }

.kuiCardGroup { /* ... */ }

.kuiCardGroup__card { /* ... */ }

.kuiCardGroup__cardDescription { /* ... */ }
```

```html
<div class="kuiCardGroup">
<div class="kuiCard kuiCardGroup__card">
<div class="kuiCard__description kuiCardGroup__cardDescription">
Card Description
</div>
</div>
</div>
```

To avoid the combinatorial explosion of classes with such groupings and its
modifiers, it is permissible to nest a block's selector under another block's
selector if:

* The relationship is a if a very narrow `element` to `elementGroup` kind that
is apparent from the block names.
* The rulesets are colocated in the same component directory.

```css
.kuiCard { /* ... */ }

.kuiCard__description { /* ... */ }

.kuiCardGroup { /* ... */ }

.kuiCardGroup .kuiCard { /* ... */ }

.kuiCardGroup .kuiCard__description { /* ... */ }
```

#### Exception: Normalization/Reset

When working with the browser default styles or third-party stylesheets the
selectors are sometimes overly broad so that they have to be re-used in order
to integrate the styles into the project.

0 comments on commit 4fa3418

Please sign in to comment.