Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save radermacher/e9eb6d12ae6d90d330bd77d5d7952c1b to your computer and use it in GitHub Desktop.
Save radermacher/e9eb6d12ae6d90d330bd77d5d7952c1b to your computer and use it in GitHub Desktop.
<div class="class">asd</div>
// ----
// Author: Tat&Kraft
// Forked from http://sassmeister.com/gist/6dac17c87fcf2d1555c4
// Article: https://medium.com/@marcmintel/pushing-bem-to-the-next-level-with-sass-3-4-5239d2371321
// ----
$elementSeparator: '__';
$modifierSeparator: '--';
$state-prefix: 'is';
@function containsModifier($selector) {
$selector: selectorToString($selector);
@if str-index($selector, $modifierSeparator) {
@return true;
} @else {
@return false;
}
}
@function containsState($selector) {
$selector: selectorToString($selector);
@if str-index($selector, ":") {
@return true;
} @else {
@return false;
}
}
@function selectorToString($selector) {
$selector: inspect($selector); //cast to string
$selector: str-slice($selector, 2, -2); //remove brackets
@return $selector;
}
@function getBlock($selector, $seperator) {
$selector: selectorToString($selector);
$seperatorPosition: str-index($selector, $seperator) - 1;
@return str-slice($selector, 0, $seperatorPosition);
}
@mixin block($block) {
.#{$block} {
@content;
}
}
@mixin element($element) {
$selector: &;
@if containsModifier($selector) {
$block: getBlock($selector, $modifierSeparator);
@at-root {
#{$selector} {
#{$block+$elementSeparator+$element} {
@content;
}
}
}
} @else if containsState($selector) {
$block: getBlock($selector, ':');
@at-root {
#{$selector} {
#{$block+$elementSeparator+$element} {
@content;
}
}
}
} @else {
@at-root {
#{$selector+$elementSeparator+$element} {
@content;
}
}
}
}
@mixin modifier($modifier) {
@at-root {
#{&}#{$modifierSeparator+$modifier} {
@content;
}
}
}
@mixin state($state, $prefix: $state-prefix) {
&.#{$prefix}-#{$state} {
@content;
}
}
// SAMPLE
@include block("test") {
background: red;
&:hover {
@include element("element") {
background: green;
}
}
@include element("element") {
font-size: 14px;
@include modifier("big") {
font-size: 18px;
}
}
@include modifier("modifier") {
color: blue;
&:hover {
@include element("subelement") {
background: yellow;
}
}
@include state("active") {
color: blue;
&:hover {
@include element("subelement") {
background: gray;
}
}
}
}
@include state("active") {
color: blue;
}
}
.test {
background: red;
}
.test__element {
font-size: 14px;
}
.test__element--big {
font-size: 18px;
}
.test--modifier {
color: blue;
}
.test--modifier .test__subelement {
background: gray;
}
<div class="class">asd</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment