https://github.com/one-nexus/cell
Style BEM DOM elements using Sass
https://github.com/one-nexus/cell
bem modules sass stylesheets styling synergy ui-components
Last synced: 6 months ago
JSON representation
Style BEM DOM elements using Sass
- Host: GitHub
- URL: https://github.com/one-nexus/cell
- Owner: One-Nexus
- License: mit
- Created: 2018-09-06T13:39:46.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2023-01-07T02:27:50.000Z (over 2 years ago)
- Last Synced: 2025-04-12T15:06:53.219Z (6 months ago)
- Topics: bem, modules, sass, stylesheets, styling, synergy, ui-components
- Language: SCSS
- Homepage:
- Size: 1.39 MB
- Stars: 20
- Watchers: 2
- Forks: 1
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://github.com/One-Nexus/Cell/blob/master/LICENSE)
[](https://travis-ci.com/One-Nexus/Cell)
[]((https://www.npmjs.com/package/@onenexus/cell))
[](https://www.npmjs.com/package/@onenexus/cell)> Style BEM DOM elements using Sass [[View SassDocs](https://one-nexus.github.io/Cell/sass/)]
* [Overview](#overview)
* [Installation & Setup](#installation--setup)
* [Creating a Module](https://github.com/One-Nexus/Cell/wiki/Creating-a-Module)
* [Mixins](#mixins)
* [Utility Functions](#utilities)
CodeSandbox Demos
Standard Demo
JavaScript Demo
React Demo
Basic Sass-Only Demo
## Overview
Cell is used for styling DOM elements that follow the [Cell naming convention](https://github.com/One-Nexus/Cell/wiki/Cell-Naming-Convention) (which is almost identical to [BEM](http://getbem.com/)).
> [Learn how to integrate with React components](#using-with-react)
* Cell is used for creating modular, configurable and scalable Sass components
* Works with any Sass implementation (Ruby, Dart, Node...)
* Requires Sass 3.4+ (4.9+ if using Node-Sass)
* [Import themes/configuration into your Sass/Cell components as JavaScript/JSON](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration#usage)
* Built for the [Synergy framework](https://github.com/One-Nexus/Synergy)
* [Compatible with Cell Query](https://github.com/One-Nexus/Synergy-Front-End-Guides/wiki/Cell-Query)### Example
Given the following markup for an accordion with an active panel component:
> [View CodeSandbox Demo](https://codesandbox.io/s/cell-demo--basic-p55bc)
> Unlike traditional BEM, you do not need separate classes for modifiers
```html
foo
bar
fizz
buzz
```This can be styled with Cell like so:
```scss
@include module('accordion') {
@include component('panel') {
...@include is('active') {
@include component('content') {
display: block;
}
}
}@include component('title') {
...
}@include component('content') {
...
display: none;
}
}
```### Using `context()`
The above examples use the traditional _cascading_ paradigm to apply styles under certain conditions. You can see that to _show_ the `content` component above, the `display` property is applied in a cascading fashion _inside_ the `panel` component.
Cell allows you to go about this in a dfferent way, allowing you to keep all styles pertaining to a single component in one place, thanks to the [`context()`](https://github.com/One-Nexus/Cell/wiki/Context()) mixin, as seen in this example (this will produce identical CSS to the previous example):
```scss
@include module('accordion') {
@include component('panel') {
...
}@include component('title') {
...
}@include component('content') {
...
display: none;@include context(($this, 'panel'), 'active') {
display: block;
}
}
}
```### Using [Cell Atoms](https://github.com/One-Nexus/Cell/wiki/Atoms)
> [Learn more about Cell Atoms](https://github.com/One-Nexus/Cell/wiki/Atoms)
Continuing from the previous example, the `display` Atom can instead be used to handle the `display` property:
```scss
@include module('accordion') {
@include component('panel') {
...
}@include component('title') {
...
}@include component('content') {
...
@include display((($this, 'panel'), 'active'), block, none);
}
}
```### Using [Cell Query (CQ)](https://github.com/One-Nexus/Synergy-Front-End-Guides/wiki/Cell-Query)
Cell can interpret and parse CQ by passing a CQ compatible Sass map as the second parameter to the `module()` mixin, allowing the `accordion` example to be re-written as:
```scss
@include module('accordion', (
'panel': (
...
),'title': (
...
),'content': (
...
'display': none,'panel-is-active': (
'display': block
)
)
));
```> [Learn more about Cell and Cell Query (CQ)](https://github.com/One-Nexus/Cell/wiki/Cell-Query)
## Installation & Setup
```
npm install --save @onenexus/cell
``````scss
// this path will vary depending on where the library is being imported
@import '../../node_modules/@onenexus/cell/dist/cell';
```If you are using Node Sass, you can import the library anywhere using:
```scss
@import '~@onenexus/cell/dist/cell';
```> See the [JavaScript Configuration](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration) page for instructions on how to use JavaScript/JSON configuration
## Using with JavaScript
Cell can be used with JavaScript for things like [theming](https://github.com/One-Nexus/Cell/wiki/Theming) and [module configuration](https://github.com/One-Nexus/Cell/wiki/Module-Configuration).
> [View CodeSandbox Demo](https://codesandbox.io/s/cell-demo--js-iklx3)
> [Using React?](#using-with-react)
### Example
```
modules/
|--myModule/
| |--config.js
| |--styles.scss
themes/
|--myTheme.js
app.scss
```###### themes/myTheme.js
```js
export default {
colors: {
primary: '#00d4ff',
secondary: '#58ed02'
},
breakpoints: {
small: '720px',
large: '1400px'
}
}
```###### modules/myModule/config.js
```js
export default (theme) => ({
name: 'myModule',
background: theme.colors.primary,
gutter: '1em'
});
```###### modules/myModule/styles.scss
```scss
@import 'config.js';@include module {
display: block;
margin-top: this('gutter');@media (min-width: theme('breakpoints', 'small')) {
display: inline-block;
}
}
```###### app.scss
```scss
@import '~@onenexus/cell/dist/cell';
@import 'themes/myTheme.js';
@import 'modules/myModule/styles';
```###### CSS Output
```css
.myModule, [class*="myModule--"] {
background: #00d4ff;
display: block;
margin-top: 1em;
}@media (min-width: 720px) {
.myModule, [class*="myModule--"] {
display: inline-block;
}
}
```> Note that the `background` property is output to CSS despite not being hard-coded inside `styles.scss` - this is because configuration properties that correspond to CSS properties can be automatically parsed as CSS - read the [Cell Query page](https://github.com/One-Nexus/Cell/wiki/Cell-Query) to learn more
> Read the [JavaScript Configuration page](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration) for setup instructions and more information
## Using with React
Using Cell with React can be as simple as configuring your Webpack to use [Sass-Loader](https://github.com/webpack-contrib/sass-loader). See how the below React accordion component can be styled by importing its corresponding Cell module (`styles.scss`):
> [View CodeSandbox Demo](https://codesandbox.io/s/cell-demo--react-hygf9)
###### modules/Accordion/index.js
```jsx
import React, { useState } from 'react';
import './styles.scss';const Accordion = ({ panels, ...props }) => {
const [activeIndex, toggle] = useState(0);return (
{panels.map(({ heading, content }, index) => (
toggle(index)}>
{title}
{content}
))}
);
}export default Accordion;
```### Using with Lucid (React Library)
[Lucid](https://github.com/One-Nexus/Lucid) is a React library for working with the Cell/BEM naming convention. If using Lucid, the above React component could be rewritten as:
```jsx
import React, { useState } from 'react';
import { Module, Component } from '@onenexus/lucid';
import './styles';const Accordion = ({ panels, ...props }) => {
const [activeIndex, toggle] = useState(0);return (
{panels.map(({ heading, content }, index) => (
toggle(index)}>
{heading}
{content}
))}
);
}export default Accordion;
```This solution offers all the practical benefits of scoped styling (thanks to the underlying Cell/BEM naming convention) without any of the uglyness that BEM usually brings, and without any of the overhead that CSS-in-JS techniques (and actual *scoping*) bring, keeping everything clean and tidy.
## Useful Wiki Pages
* [Creating a Cell Module](https://github.com/One-Nexus/Cell/wiki/Creating-a-Module)
* [Module Configuration](https://github.com/One-Nexus/Cell/wiki/Module-Configuration)
* [Theming](https://github.com/One-Nexus/Cell/wiki/Theming)
* [Cell Query (CQ)](https://github.com/One-Nexus/Cell/wiki/Cell-Query)
* [Using with JavaScript](https://github.com/One-Nexus/Cell/wiki/JavaScript-Configuration)
* [Atoms](https://github.com/One-Nexus/Cell/wiki/Atoms)## Mixins
Cell comes with the following mixins to help create and structure your modules in the most efficient way possible:
* [Module](https://github.com/One-Nexus/Cell/wiki/Module())
* [Component](https://github.com/One-Nexus/Cell/wiki/Component())
* [Modifier](https://github.com/One-Nexus/Cell/wiki/Modifier())
* [Option](https://github.com/One-Nexus/Cell/wiki/Option())
* [Value](https://github.com/One-Nexus/Cell/wiki/Value())
* [Extend](https://github.com/One-Nexus/Cell/wiki/Extend())
* [Context](https://github.com/One-Nexus/Cell/wiki/Context())
* [Pseudo-State](https://github.com/One-Nexus/Cell/wiki/Pseudo-State())
* [Wrapper](https://github.com/One-Nexus/Cell/wiki/Wrapper())## Utility Functions
* [Create Config](https://github.com/One-Nexus/Cell/wiki/utilities#create-config)
* [Enabled](https://github.com/One-Nexus/Cell/wiki/utilities#enabled)
* [Value Enabled](https://github.com/One-Nexus/Cell/wiki/utilities#value-enabled)
* [Option](https://github.com/One-Nexus/Cell/wiki/utilities#option)
* [Setting](https://github.com/One-Nexus/Cell/wiki/utilities#setting)
* [This](https://github.com/One-Nexus/Cell/wiki/utilities#this)
* [Theme](https://github.com/One-Nexus/Cell/wiki/utilities#theme)## BEM Inspired Motivation
The initial motiviation behind creating Cell is twofold:
* Address the uglyness of BEM
* Address the practical implementation of BEM using SassBEM solves very real problems like no other solution due to [its inherent nature](https://itnext.io/thinking-of-bem-as-a-ui-philosophy-instead-of-a-css-naming-convention-9727e2cf9328), however it is [often considered quite ugly](https://hackernoon.com/bem-should-not-exist-6414005765d6); the `__` and `--` thrown into your HTML along with [repeated keywords when using modifiers](https://stackoverflow.com/questions/32052836/sass-bem-avoid-modifier-duplication-when-element-is-inside-a-modifier) (`block__component block__component--modifier-1 block__component--modifier-2`) make the HTML extremely jarring to look at. Cell solves these issues by abstracting the logic into mixins and making use of CSS's [wildcard attribute selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
Since the initial conception, Cell has evolved to become a fully-fledged framework for writing scalable and maintainable CSS.
---