Last active
August 29, 2015 14:05
-
-
Save BobD/e51edd989e43aaf3d74d to your computer and use it in GitHub Desktop.
Some Gulp.js which reworks a tad of BEM CSS so you can use multiple Modifiers in a single BEM class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Some Gulp.js which reworks a tad of BEM CSS so you can use multiple Modifiers in a single BEM class | |
Some BEM CSS like this: | |
.__block{display: block;} | |
.__block__element{display: inline-block;} | |
.__block__element_color-1{color: yellow;} | |
.__block__element_background-2{background: Green;} | |
.__block__element_font-3{font-family: Arial;} | |
Becomes: | |
.__block {display: block; color: red; } | |
.__block__element, *[class^="__block__element_"][class*="color-1"], *[class^="__block__element_"][class*="background-2"], *[class^="__block__element_"][class*="font-3"] {display: inline-block; } | |
.__block__element_color-1, *[class^="__block__element_"][class*="color-1"] {color: yellow; } | |
.__block__element_background-2, *[class^="__block__element_"][class*="background-2"] {background: Green; } | |
.__block__element_font-3, *[class^="__block__element_"][class*="font-3"] {font-family: Arial; } | |
So you can do: __block__element_color-1_background-2_font-3 | |
Mind you, will bloat your CSS. But nothing gzip can not fix | |
*/ | |
var _ = require("underscore"); | |
var gulp = require('gulp'); | |
var sass = require('gulp-ruby-sass'); | |
var through = require('through2'); | |
var gutil = require('gulp-util'); | |
var fs = require('fs'); | |
gulp.task('betterbem', function () { | |
return gulp.src('css/bem.scss') | |
.pipe(betterBEM()); | |
}); | |
gulp.task('default', ['betterbem'], function () { | |
return gulp.src('css/better_bem.scss') | |
.pipe(sass()) | |
.pipe(gulp.dest('css')); | |
}); | |
// produce the CSS so you can use multiple Modifiers in a single BEM class | |
function betterBEM(){ | |
var stream = through.obj(function(file, enc, cb) { | |
var css = fs.readFileSync(file.path, 'utf-8'); | |
var CSSOM = require('cssom'); | |
var CSSTree = CSSOM.parse(css); | |
var bemList = bemListing(CSSTree.cssRules); | |
var sass = require('node-sass'); | |
var scss = [], betterSCSS; | |
_.each(bemList, function(modifiers, blockElement){ | |
_.each(modifiers, function(modifier){ | |
scss.push('*[class^="' + blockElement + '_"][class*="' + modifier.substring(1) + '"]{@extend .' + blockElement + ' !optional; @extend .' + blockElement + modifier + ' !optional;}'); | |
}); | |
}); | |
betterSCSS = css + scss.join(''); | |
fs.writeFileSync('./css/better_bem.scss', betterSCSS); | |
var file2 = new gutil.File({ | |
path: './css/better_bem.scss' | |
}); | |
this.push(file2); | |
cb(); | |
}) | |
return stream; | |
} | |
// create a list of Block/Elements plus their accompanying Modifiers | |
function bemListing(cssRules){ | |
var bemList = {}; | |
_.each(cssRules, function(rule){ | |
selector = rule.selectorText; | |
bem = bemParts(selector); | |
if(_.has(bem, 'be')){ | |
if(!_.has(bemList, bem.be)){ | |
bemList[bem.be] = []; | |
} | |
if(_.has(bem, 'm')){ | |
bemList[bem.be].push(bem.m); | |
} | |
} | |
}); | |
return bemList; | |
} | |
// rip apart a selector for it Block/Element/Modifier parts | |
function bemParts(selector){ | |
if(selector.indexOf('.') == 0){ | |
selector = selector.substring(1); | |
} | |
if(selector.indexOf('__') != 0){ | |
return {selector: selector}; | |
} | |
// Only get the actual BEM classname, not particularly graceful | |
selector = selector.split(',')[0]; | |
selector = selector.split(' ')[0]; | |
selector = selector.split(':')[0]; | |
// Some extensive splitting due to kaBEM class starting with '__' (yes, i should use a better Block prefix ;) ) | |
var BE = selector.split('__'); | |
var M = BE.pop().split('_'); | |
BE.push(M.shift()); | |
var ret = {be: BE.join('__'), selector: selector}; | |
if(M.length > 0){ | |
ret.m = '_' + M[0]; | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment