BEM CSS scaffolding on some steroids
JavaScript CSS
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
doc
src
tasks
Gruntfile.js
LICENSE
README.md
package.json

README.md

##kaBEM

kaBEM is a grunt.js environment for quick scaffolding and tweaking of HTML with BEM CSS (Block, Element, Modifier). kaBEM is mostly useful if you have a piece of HTML which can have a lot of varying visual states. For example if you want to develop some page themes, a plugin with many possible user settings or a site with a load of responsive states.

##Who made it? [Bob Donderwinkel] (http://nl.linkedin.com/in/bobdonderwinkel), and i use kaBEM to make galleries and page layouts for [Viewbook] (http://www.viewbook.com/)

##What does kaBEM do for you?

kaBEM uses a bit of initial HTML markup with some BEM classes to scaffold out a folder structure using [Sass] (http://sass-lang.com/) to start developing on. Each Block or Element get's it's own folder, and inside that is a seperate Sass file for the block/element and modifiers CSS. Each Modifier BEM class you add get's it's own HTML file for quick testing and tweaking of just that feature.

kaBEM also gives you the use of BEM classnames with mutliple modifiers, for example:

__block__elemend__modifier1_modifier2
Just use a single BEM classname on each HTML element to rule all Block, Element and Modifier CSS.

And if you are using User Stories to define your project, and have written those in a [Structure/State] (https://github.com/viewbook/dev-kabem/blob/master/README.md#structurestate-user-stories) kinda way, it's rather easy to get some initial BEM classnames for a quick start.

And of course the kaBEM grunt.js environment also has all standard grunt niceties like HTML/CSS validation and minimizing, local servers and LiveReload. And you can add your own project specific task, just give it a whirl.

##Why BEM?

BEM stands for Block Element Modifier and was originally thought up by the people of Yandex. BEM is no more then a simple CSS class naming convention which gives them purpose and meaning to other developers. In short the benefits are:

  • See a BEM classname in your CSS and know where to use it in your HTML
  • See a BEM classname in your HTML and know where to find it in your CSS files
  • See a BEM classname and know which purpose it has

BEM is no golden highway to utter front-end developer bliss, nothing is (well a decent mug of coffee get's close). It's long classnames help in understanding your CSS and HTML, but it will also bloat your HTML and CSS, if only from a HTML/CSS esthetic point of view. It's single classname approach can prevent CSS specifity hell and helps understand it's meaning and purpose, but also when used on it's own ignores the useful cascading nature of C(cascading)SS. Luckily kaBEM does not prevent you from using it with regular CSS in the way you want. I personally just scaffold and tweak out the main structure of my HTML with kaBEM, and then augment it where needed with the Cascading power of CSS where needed, lovely.

For some more BEM reading:

##kaBEM file structure

The kaBEM scaffolding depends on a 'src' folder with an index.html holding your HTML and an index.scss. It also contains a 'css' folder where all BEM CSS folders and files will be generated, plus an empty (Sass) 'helpers' and 'vendor' folder which you can use as needed.

The scaffoling output will be placed in a 'build' folder. This includes a 'source' folder with all generated CSS and HTML, a 'bem' folder with all single modifier HTML pages for easy testing and a 'live' folder with deployable files.

##kaBEM naming conventions

kaBEM uses these class name conventions:

  • '__' starting block and elements
  • '_' starting a modifier
  • '-' for multi word block, elements and modifiers

So a kaBEM class would look like: '__page__container_modifier-name'.

kaBEM also support multople modifier classnames with a bit of semi clever-ish Sass @extend and CSS attribute selectors. It converts BEM classes like these:

.__block{
	background-color: AliceBlue;
}

.__block_modifier1{
	color: AntiqueWhite;
}

.__block_modifier2{
	color: Aqua;
}

Into:

.__block, 
*[class="__block"], 
*[class^="__block_"][class*="modifier1"], 
*[class^="__block_"][class*="modifier2"] {
  background-color: AliceBlue; 
  }

.__block_modifier1, 
*[class^="__block_"][class*="modifier1"] {
  color: AntiqueWhite; 
  }

.__block_modifier2, 
*[class^="__block_"][class*="modifier2"] {
  background-color: Aqua; 
  }

So you can simply use '__block_modifier1_modifier2' as a single BEM classname to get all Block, Element and Modifier CSS goodness, hooray.

##Structure/State User Stories?

Structure and State user stories, what are you babbling about? Well kaBEM is essentially about managing the different visual states of a single HTML block using CSS. And if you would describe a visual state using User Stories, they would end up in two main categories i guess: Structure and State.

In essence Structure describes those elements always present on screen (unless you hide them with a state, don't be nitpicky). State describes the different states and behaviours those elements can have. It just happens that this pretty much matches what BEM is about. Block and Elements are 'Structure', and Modifiers are 'State'. So how handy would it be if you could derive some BEM classnames directly from the User Stories and get started scaffolding your HTML and SASS folder sctructure. Very handy.

For example. Considder a paragraph with a title and some text. It has to be able to expand the full width, or alternatively take a fixed width. This is a rather painfully stupid example, but bare with me. Then you can write your User Stories this way;

####Structure

  • As a Visitor i want to see a paragraph some text with a nice title above it

  • It should have a title element

  • It should have a text element

  • The title should be above the text

####State

  • As a Visitor i want to see a paragraph stretching the full width of the screen

  • It should be 100% wide

  • As a Visitor i want to see a paragraph remain the same width even if the screen resizes.

  • It should be 600 pixels wide

Reading these User Stories you end up with three Structure elements, and two States. Putting those in kaBEM classnames you could end up with this:

  • __paragraph
  • __paragraph__title
  • __paragraph__text
  • __paragraph_full-width
  • __paragraph_fixed-width

Now you can startup a simple HTML structre like this (BEM classnames already suggest a certain structure to use):

<section class='__paragraph'>
 <header class='__paragraph__title'>title</header>
 <p class='__paragraph__text'>text</p>
</section>

And hitting 'grunt' inside kaBEM would give you this folder structure:

__paragraph
 __title
  __paragraph__title.scss
  __paragraph__title_modifiers.scss
 __text
   __paragraph__text.scss
  __paragraph__text_modifiers.scss
__paragraph.scss
__paragraph_modifiers.scss

And finally you can put the BEM modifier class names inside the __paragraph_modifiers.scss file, and fill them with the needed CSS to pass the User Story.

.__paragraph_full-width{ width: 100%; } .__paragraph_fixed-width{ width: 600px; }

Nice, albeit a stupid example. But you get the drift.

During development you might find that the HTML markup needs additional elements to make things actually work, no problem there. You could either modify the relevant BEM classnames with new '__elements' if those elements are in need of some CSS, or skip them altogether. kaBEM does not mind.

##Adding some dynamic HTML kaBEM supports underscore templates and you can put the data used in config/data-stub.json. You can also tweak the parse-index task (see inside the tasks folder) to use some other template.

##Adding a BEM context for testing Every BEM modifier classname you fill with some CSS will get a seperate HTML page in the build/develop folder for easy testing. But some modifiers only make sense in combination with other modifiers. So you can sum these modifier classnames up in config/bem-context.json ("default") and they will be injected in every modifier page. Or you can add them under a different name and run grunt with --context=your-bem-context.

##Adding some responsive states Using responsive states with kaBEM is rather easy. You can add some media queries mixins for Sass like (these) [https://github.com/paranoida/sass-mediaqueries] in your 'css/helpers/_utils.scss', and start using them in your block/element/modifiers scss files where needed. You might also define some global breakpoint values for min-width and the like in your 'css/helpers/_variables.scss' so you have those availble in all your media queries.

##Getting Started

  1. [install node.js] (http://nodejs.org/) and [grunt.js] (http://gruntjs.com/getting-started).
  2. Run 'npm install'
  3. Run 'grunt connect' and 'grunt watch'
  4. Take a look at the index.html in src folder, notice the example kaBEM classes, and run 'grunt'
  5. Add your HTML and fill the scaffolded BEM CSS (inside src/css/kabem/bem) with more CSS goodness and let me know how it works.

##Copyright Code released under [the MIT license] (https://github.com/viewbook/dev-kabem/blob/master/LICENSE).