-
Notifications
You must be signed in to change notification settings - Fork 1
Creating a Module
Please read the Cell Naming Convention page for full context before reading this guide.
To generate styles for a module, simply call the Module mixin with your desired arguments.
@include module('button') {
display: block;
}
.button,
[class*="button--"] {
display: block;
}
<div class="button">Button</div>
@include module('header') {
@include component('menu') {
float: left;
}
}
.header__menu,
[class*="header__menu--"] {
float: left;
}
<div class="header">
<div class="header__menu">
...
</div>
<div>
As with BEM, nesting Components can be confusing, awkward, and complex, and should be avoided where possible. However, it is possible by using the sub-component()
mixin.
Take the following example of a Cell Sub-Component:
<div class="header">
<ul class="header_menu">
<li class="header_menu_item">...</li>
<li class="header_menu_item">...</li>
<li class="header_menu_item">...</li>
</ul>
</div>
The elements with the header_menu_item
class in the above example would be considered Sub-Components, and represented by Cell as:
@include module('header') {
@include component('menu') {
@include sub-component('item') {
...
}
}
}
Without using sub-components, you might think to do the same thing like this (which wouldn't work as expected):
@include module('header') {
@include component('menu') {
@include component('item') {
...
}
}
}
...which would actually be equivalent to:
@include module('header') {
@include component('item') {
...
}
}
In this particular exmaple, the recommendation would probably be to make menu
its own module, and have item
be a regular component of that module; but sometimes Sub-Components are difficult to avoid.
Modifiers can be added to modules, components and sub-components, and can be created by using the Modifier/Is mixins.
@include module('header') {
@include is('fixed') {
position: sticky;
}
@include component('menu') {
@include is('small') {
font-size: 0.85em;
}
@include sub-component('item') {
@include is('special') {
background-color: pink;
}
}
}
}
[class*="header--"][class*="--fixed"] {
position: sticky;
}
[class*="header__menu--"][class*="--small"] {
font-size: 0.85em;
}
[class*="header__menu__item--"][class*="--special"] {
background-color: pink;
}
<div class="header--sticky">
<div class="header__menu--small">
<div class="header__menu__item">...</div>
<div class="header__menu__item--special">...</div>
<div class="header__menu__item">...</div>
</div>
...
</div>
Modifiers can be nested should you need to style an element when more than one modifier is applied:
@include module('myModule') {
@include modifier('someModifier') {
@include modifier('anotherModifier') {
background-color: green;
}
}
}
[class*="myModule--"][class*="--someModifier"][class*="--anotherModifier"] {
background-color: green;
}
<div class="myModule--someModifier--anotherModifier">...</div>
Consider a project with separate header
and menu
modules. We may wish to apply custom styles to the menu
module when it is inside the header
module. This can be done in two ways.
@include module('header') {
@include module('menu') {
@include component('item') {
display: inline-block;
}
}
}
See the Context mixin for more information
@include module('menu') {
@include context('header') {
@include component('item') {
display: inline-block;
}
}
}
...or:
@include module('menu') {
@include component('item') {
@include context('header') {
display: inline-block;
}
}
}
The output is the same for all examples
.header .menu__item,
.header [class*="menu__item--"],
[class*="header--"] .menu__item,
[class*="header--"] [class*="menu__item--"] {
display: inline-block;
}
In case you need to call a module multiple times with different configurations to generate separate sets of CSS, you can create your module within a mixin.
Note that if you use JavaScript for theming and configuration this section will likely not apply to you, otherwise the approach outlined in this section is recommended
First let's take a base module with some configuration as an example (read the Module Configuration page for more information):
$config: (
'name': 'myModule',
'font-size': 20px,
'background-color': #0155a0
);
@include module {
display: flex;
position: relative;
cursor: pointer;
}
Let's say we want to use the core of this module to create two different modules with different names and different configurations passed to them to give a different look and feel. This can be done by
- Wrapping the above code in a mixin
- Passing a
$custom
parameter to the mixin - Calling the
create-config()
utility function passing the module's default configuration and the$custom
argument - ...and assiging the result to the
$config
variable
@mixin myModule($custom: ()) {
$config: create-config((
'name': 'myModule',
'font-size': 20px,
'background-color': #0155a0
), $custom);
@include module {
display: flex;
position: relative;
cursor: pointer;
}
}
Now to generate the default CSS for this module you would call the mixin:
@include myModule;
.myModule, [class*="myModule--"] {
font-size: 20px;
background-color: #0155a0;
display: flex;
position: relative;
cursor: pointer;
}
To call the module with a different configuration set, pass the new values when calling the mixin:
@include myModule((
'name': 'somethingElse',
'font-size': 16px,
'background-color': #444444,
'text-align': center
));
.somethingElse, [class*="somethingElse--"] {
font-size: 16px;
background-color: #444444;
text-align: center;
display: flex;
position: relative;
cursor: pointer;
}