diff --git a/style_guides/css_style_guide.md b/style_guides/css_style_guide.md index 61822d3217e3..9c4cd6799a0c 100644 --- a/style_guides/css_style_guide.md +++ b/style_guides/css_style_guide.md @@ -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 @@ -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 @@ -461,3 +464,115 @@ 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 +