Created
June 18, 2014 07:23
-
-
Save danielguillan/33f4f92cc079148900ec to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
This file contains hidden or 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
// ---- | |
// Sass (v3.3.7) | |
// Compass (v1.0.0.alpha.18) | |
// ---- | |
// ============================================================================= | |
// Mixin-driven BEM definitions | |
// | |
// I still don't know whether i like this idea or not. | |
// | |
// Conceptually, it looks good: | |
// — A consitent way of defining BEM objects | |
// — Element and modifier syntax independence | |
// — Prevents block duplication | |
// — Prevents errors in class names (they're all dynamically generated) | |
// — Better code output (it encourages the use of extends) | |
// | |
// But it also looks verbose: | |
// — It might not be as easy to read as plain class names | |
// | |
// ============================================================================= | |
$bem: () !global; | |
$bem-element-separator: '__' !default; | |
$bem-modifier-separator: '--' !default; | |
$bem-modifier-extends: false !default; // not working yet | |
@function already-defined($list, $target) { | |
@each $item in $list { | |
@if $item == $target { | |
@return true; | |
} | |
} | |
@return false; | |
} | |
@function block-already-defined($block) { | |
@each $item in $bem { | |
@if map-get($item, block) == $block { | |
@return true; | |
} | |
} | |
@return false; | |
} | |
@mixin block($block) { | |
@if block-already-defined($block) { | |
@warn 'Block `#{$block} has already been defined.'; | |
} @else { | |
$bem: append($bem, (block: $block, elements: (), block-modifiers: (), element-modifiers: ())); | |
.#{$block} { | |
@content; | |
} | |
} | |
} | |
@mixin element($element) { | |
$current: nth($bem, length($bem)); | |
$current-elements: map-get($current, elements); | |
@if already-defined($current-elements, $element) { | |
@warn 'Element `#{$element}` already exists.'; | |
} @else { | |
$new-elements: append($current-elements, $element, comma); | |
$bem: set-nth($bem, length($bem), map-merge($current, (elements: $new-elements))); | |
@at-root &#{$bem-element-separator}#{$element} { | |
@content | |
} | |
} | |
} | |
@mixin modifier($modifier, $modifies-block: false) { | |
$current: nth($bem, length($bem)); | |
$current-block: map-get($current, block); | |
$current-block-modifiers: map-get($current, block-modifiers); | |
$current-element-modifiers: map-get($current, element-modifiers); | |
// Check if $modifier is not within the Block | |
// If it's within the block, ignore $modifies-block and modifie the block | |
// warn the use? | |
@if $modifies-block { | |
@if not already-defined($current-block-modifiers, $modifier) { | |
$new-block-modifiers: append($current-block-modifiers, $modifier, comma); | |
$bem: set-nth($bem, length($bem), map-merge($current, (block-modifiers: $new-block-modifiers))); | |
} | |
@at-root .#{map-get(nth($bem, length($bem)),block)}#{$bem-modifier-separator}#{$modifier} & { | |
@if ($bem-modifier-extends) { | |
@extend .#{map-get(nth($bem, length($bem)),block)}; | |
} | |
@content; | |
} | |
} @else { | |
// We can't currently get the current element without Sassscript access to `&` | |
//@if already-defined($current-element-modifiers, $modifier) { | |
//$current-element: '&'; | |
//@warn 'Modifier `#{$modifier}` already exists for element `#{$current-element}`'; | |
//} @else { | |
$new-element-modifiers: append($current-element-modifiers, $modifier, comma); | |
$bem: set-nth($bem, length($bem), map-merge($current, (element-modifiers: $new-element-modifiers))); | |
@at-root &#{$bem-modifier-separator}#{$modifier} { | |
@content | |
//} | |
} | |
} | |
} | |
@include block('flag') { | |
display: table; | |
width: 100%; | |
@at-root %flag-items-display { | |
display: table-cell; | |
vertical-align: middle; | |
} | |
@at-root %align-top { vertical-align: top; } | |
@at-root %align-bottom { vertical-align: bottom; } | |
@include element('image') { | |
@extend %flag-items-display; | |
padding-right: 10px; | |
> img { | |
display: block; | |
max-width: none; | |
} | |
@include modifier('rev') { | |
padding-right: 0; | |
padding-left: 10px; | |
} | |
@include modifier('top', $modifies-block: true) { | |
@extend %align-top; | |
} | |
@include modifier('bottom', $modifies-block: true) { | |
@extend %align-bottom; | |
} | |
} | |
@include element('body') { | |
@extend %flag-items-display; | |
width: 100%; | |
@include modifier('top', true) { | |
@extend %align-top; | |
} | |
@include modifier('bottom', true) { | |
@extend %align-bottom; | |
} | |
} | |
} | |
.debug { | |
bem: inspect($bem); | |
} |
This file contains hidden or 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
.flag { | |
display: table; | |
width: 100%; | |
} | |
.flag__image, .flag__body { | |
display: table-cell; | |
vertical-align: middle; | |
} | |
.flag--top .flag__image, .flag--top .flag__body { | |
vertical-align: top; | |
} | |
.flag--bottom .flag__image, .flag--bottom .flag__body { | |
vertical-align: bottom; | |
} | |
.flag__image { | |
padding-right: 10px; | |
} | |
.flag__image > img { | |
display: block; | |
max-width: none; | |
} | |
.flag__image--rev { | |
padding-right: 0; | |
padding-left: 10px; | |
} | |
.flag__body { | |
width: 100%; | |
} | |
.debug { | |
bem: (block: "flag", elements: ("image", "body"), block-modifiers: ("top", "bottom"), element-modifiers: (("rev",))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment