Last active
April 7, 2017 00:43
-
-
Save IPRIT/be31cf05f291dc3822cd9be72cfe7eb0 to your computer and use it in GitHub Desktop.
The mixin provides an easy way to build `bem` classes (block, element, modifier) like in example section
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
| /** | |
| * Copyright (c) 2017 Alex Belov | |
| * MIT | |
| */ | |
| /* Prefixes */ | |
| $bem-block-prefix: ab-; // .ab-class { .. } | |
| $bem-element-prefix: __; // .ab-class__element { .. } | |
| $bem-modifier-prefix: _; // .ab-class__element_modifier { .. } | |
| /** | |
| * Helpers | |
| */ | |
| @function str-last-index($string, $substr) { | |
| $index: null; | |
| $length: str-length($string); | |
| @for $n from $length through 1 { | |
| $index: str-index(str-slice($string, $n, $length), $substr); | |
| @if $index { @return $index + $n - 1; } | |
| } | |
| @return $index; | |
| } | |
| @function unwrap-scope($scope) { | |
| @return str_slice(quote($scope), 1 + (str-last-index(quote($scope), unquote(' ')) or 0)); | |
| } | |
| @mixin bem-block($block, $at-root: true) { | |
| $scope: unwrap-scope(&); | |
| $is-class: str-index($block, unquote('.')); | |
| $selector: $block; | |
| @if (not $is-class) { | |
| $selector: unquote('.')#{$bem-block-prefix}#{$selector}; | |
| } | |
| @if ($at-root) { | |
| @at-root #{$selector} { | |
| @content; | |
| } | |
| } @else { | |
| #{$selector} { | |
| @content; | |
| } | |
| } | |
| } | |
| @mixin bem-element($element, $at-root: true) { | |
| $scope: unwrap-scope(&); | |
| $selector: #{$scope}#{$bem-element-prefix}#{$element}; | |
| @if ($at-root) { | |
| @at-root #{$selector} { | |
| @content; | |
| } | |
| } @else { | |
| #{$selector} { | |
| @content; | |
| } | |
| } | |
| } | |
| @mixin bem-modifier($modifier, $at-root: true) { | |
| $scope: unwrap-scope(&); | |
| $selector: #{$scope}#{$bem-modifier-prefix}#{$modifier}; | |
| @if ($at-root) { | |
| @at-root &#{$selector} { | |
| @content; | |
| } | |
| } @else { | |
| &#{$selector} { | |
| @content; | |
| } | |
| } | |
| } | |
| /** | |
| * Usage example: | |
| * | |
| * @include bem($block: block) { | |
| * background: #faf; | |
| * @include bem($element: element) { | |
| * color: #8496F3; | |
| * @include bem($modifier: modifier) { | |
| * border: 1px solid #f5f; | |
| * &:hover { | |
| * background: #000; | |
| * } | |
| * } | |
| * } | |
| * } | |
| * | |
| * or | |
| * | |
| * @include bem-block(block) { | |
| * background: #faf; | |
| * @include bem-element(element) { | |
| * color: #8496F3; | |
| * @include bem-modifier(modifier) { | |
| * border: 1px solid #f4f; | |
| * &:hover { | |
| * background: #000; | |
| * } | |
| * } | |
| * } | |
| * } | |
| * | |
| * Outputs: | |
| * .ab-block { | |
| * background: #faf; } | |
| * .ab-block__element { | |
| * color: #8496F3; } | |
| * .ab-block__element.ab-block__element_modifier { | |
| * border: 1px solid #f5f; } | |
| * .ab-block__element.ab-block__element_modifier:hover { | |
| * background: #000; } | |
| * | |
| */ | |
| @mixin bem($block: null, $element: null, $modifier: null, $at-root: true) { | |
| @if ($element and $modifier) { | |
| @include bem-element($element, $at-root) { | |
| @include bem-modifier($modifier, $at-root) { | |
| @content; | |
| } | |
| } | |
| } @else if ($element) { | |
| @include bem-element($element, $at-root) { | |
| @content; | |
| } | |
| } @else if ($modifier) { | |
| @include bem-modifier($modifier, $at-root) { | |
| @content; | |
| } | |
| } @else { | |
| @include bem-block($block, $at-root) { | |
| @content; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment