BEM 生成器 mixin 想要匹配 MDL 结构
BEM generator mixin want to match MDL structure
所以我有以下 mixin 来生成我的 BEM 类:
$es: '__';
$ms: '--';
@function to-string($selector) {
$selector: inspect($selector); //cast to string
$selector: str-slice($selector, 2, -2); //remove brackets
@return $selector;
}
@function contains-modifier($selector) {
$selector: to-string($selector);
@if str-index($selector, $ms) {
@return true;
} @else {
@return false;
}
}
@function get-block($selector) {
$selector: to-string($selector);
$modifier-start: str-index($selector, $ms) - 1;
@return str-slice($selector, 0, $modifier-start);
}
@mixin blck($block) {
.#{$block} {
@content;
}
}
@mixin elem($element) {
$selector: &;
@if contains-modifier($selector) {
$block: get-block($selector);
@at-root {
#{$selector} {
#{$block+$es+$element} {
@content;
}
}
}
} @else {
@at-root {
#{$selector+$es+$element} {
@content;
}
}
}
}
@mixin modf($modifier) {
@at-root {
#{&}#{$ms+$modifier} {
@content;
}
}
}
@include blck(block) {
background: red;
@include elem(child){
color: blue;
};
@include modf(modifier) {
background: blue;
@include elem(child) {
color: red;
}
}
}
现在这实际上生成了完美的 BEM 样式代码,但我想匹配 MDL 代码结构,这意味着我想更具体地嵌套我的修饰符形成这个
.block
.block--modifer
至
.bock.block--modifier
如前所述,这样做的原因是为了匹配 MDL,可以在此处看到此格式的示例:https://github.com/google/material-design-lite/blob/master/src/card/_card.scss
现在我几乎可以通过更改此行来获得所需的效果:
@mixin modf($modifier) {
@at-root {
#{&}#{$ms+$modifier} {
@content;
}
}
}
为此:
@mixin modf($modifier) {
@at-root {
#{&}#{&}#{$ms+$modifier} {
@content;
}
}
}
但这会改变 CSS 的输出:
.block {
background: red;
}
.block__child {
color: blue;
}
.block--modifier {
background: blue;
}
.block--modifier .block__child {
color: red;
}
为此:
.block {
background: red;
}
.block__child {
color: blue;
}
.block.block--modifier {
background: blue;
}
.block.block--modifier .block.block__child {
color: red;
}
现在如您所见,这修复了修饰符特异性但破坏了修饰符子项。
期望的输出如下:
.block.block--modifier .block__child {
color: red;
}
您可以在此处查看所有操作:http://codepen.io/crashy/pen/wGWPvr
这是我通过分叉你的笔快速想出的东西:
在modf mixin中添加#{$selector}。
修改 get-block 函数,使其 returns 实际基数 class。首先我们将字符串切片到修饰符 (--) 的点,然后我们检查连接的字符串中是否有多个 classes。如果有多个,我们取第一个。
Link 来自代码笔:http://codepen.io/MKallivokas/pen/bpBYEg
$es: '__'; // Element
$ms: '--'; // Modifier
$ns: 'ns'; // Name space (Set to null if un-wanted)
@if($ns) {
$ns: $ns + '-';
}
@function to-string($selector) {
$selector: inspect($selector); //cast to string
$selector: str-slice($selector, 2, -2); //remove brackets
@return $selector;
}
@function contains-modifier($selector) {
$selector: to-string($selector);
@if str-index($selector, $ms) {
@return true;
} @else {
@return false;
}
}
@function get-block($selector) {
// do what get-block was doing in order to
// remove the modifier's part from the string
$selector: to-string($selector);
$modifier-start: str-index($selector, $ms) - 1;
$selector: str-slice($selector, 0, $modifier-start);
// remove the first dot
$selector: str-slice($selector, 2, str-length($selector));
// check if there is another dot
$modifier-start: str-index($selector, '.') - 1;
@if $modifier-start >= 0 {
// if there's another dot we slice the string up to that point
$selector: str-slice($selector, 0, $modifier-start);
}
// we insert the dot that we removed to the start
$selector: str-insert($selector, '.', 1);
@return $selector;
}
@mixin blck($block) {
.#{$ns}#{$block} {
@content;
}
}
@mixin elem($element) {
$selector: &;
@if contains-modifier($selector) {
$block: get-block($selector);
@at-root {
#{$selector} {
#{$block+$es+$element} {
@content;
}
}
}
} @else {
@at-root {
#{$selector+$es+$element} {
@content;
}
}
}
}
@mixin modf($modifier) {
$selector: &;
@at-root {
#{$selector}#{$selector+$ms+$modifier} {
@content;
}
}
}
@include blck(block) {
background: red;
@include elem(child){
color: blue;
};
@include modf(modifier) {
background: blue;
@include elem(child) {
color: red;
}
}
}
我不知道它是否完全符合您的需求或涵盖了您想要做的所有情况,但我希望它能有所帮助。
所以我有以下 mixin 来生成我的 BEM 类:
$es: '__';
$ms: '--';
@function to-string($selector) {
$selector: inspect($selector); //cast to string
$selector: str-slice($selector, 2, -2); //remove brackets
@return $selector;
}
@function contains-modifier($selector) {
$selector: to-string($selector);
@if str-index($selector, $ms) {
@return true;
} @else {
@return false;
}
}
@function get-block($selector) {
$selector: to-string($selector);
$modifier-start: str-index($selector, $ms) - 1;
@return str-slice($selector, 0, $modifier-start);
}
@mixin blck($block) {
.#{$block} {
@content;
}
}
@mixin elem($element) {
$selector: &;
@if contains-modifier($selector) {
$block: get-block($selector);
@at-root {
#{$selector} {
#{$block+$es+$element} {
@content;
}
}
}
} @else {
@at-root {
#{$selector+$es+$element} {
@content;
}
}
}
}
@mixin modf($modifier) {
@at-root {
#{&}#{$ms+$modifier} {
@content;
}
}
}
@include blck(block) {
background: red;
@include elem(child){
color: blue;
};
@include modf(modifier) {
background: blue;
@include elem(child) {
color: red;
}
}
}
现在这实际上生成了完美的 BEM 样式代码,但我想匹配 MDL 代码结构,这意味着我想更具体地嵌套我的修饰符形成这个
.block
.block--modifer
至
.bock.block--modifier
如前所述,这样做的原因是为了匹配 MDL,可以在此处看到此格式的示例:https://github.com/google/material-design-lite/blob/master/src/card/_card.scss
现在我几乎可以通过更改此行来获得所需的效果:
@mixin modf($modifier) {
@at-root {
#{&}#{$ms+$modifier} {
@content;
}
}
}
为此:
@mixin modf($modifier) {
@at-root {
#{&}#{&}#{$ms+$modifier} {
@content;
}
}
}
但这会改变 CSS 的输出:
.block {
background: red;
}
.block__child {
color: blue;
}
.block--modifier {
background: blue;
}
.block--modifier .block__child {
color: red;
}
为此:
.block {
background: red;
}
.block__child {
color: blue;
}
.block.block--modifier {
background: blue;
}
.block.block--modifier .block.block__child {
color: red;
}
现在如您所见,这修复了修饰符特异性但破坏了修饰符子项。
期望的输出如下:
.block.block--modifier .block__child {
color: red;
}
您可以在此处查看所有操作:http://codepen.io/crashy/pen/wGWPvr
这是我通过分叉你的笔快速想出的东西:
在modf mixin中添加#{$selector}。
修改 get-block 函数,使其 returns 实际基数 class。首先我们将字符串切片到修饰符 (--) 的点,然后我们检查连接的字符串中是否有多个 classes。如果有多个,我们取第一个。
Link 来自代码笔:http://codepen.io/MKallivokas/pen/bpBYEg
$es: '__'; // Element
$ms: '--'; // Modifier
$ns: 'ns'; // Name space (Set to null if un-wanted)
@if($ns) {
$ns: $ns + '-';
}
@function to-string($selector) {
$selector: inspect($selector); //cast to string
$selector: str-slice($selector, 2, -2); //remove brackets
@return $selector;
}
@function contains-modifier($selector) {
$selector: to-string($selector);
@if str-index($selector, $ms) {
@return true;
} @else {
@return false;
}
}
@function get-block($selector) {
// do what get-block was doing in order to
// remove the modifier's part from the string
$selector: to-string($selector);
$modifier-start: str-index($selector, $ms) - 1;
$selector: str-slice($selector, 0, $modifier-start);
// remove the first dot
$selector: str-slice($selector, 2, str-length($selector));
// check if there is another dot
$modifier-start: str-index($selector, '.') - 1;
@if $modifier-start >= 0 {
// if there's another dot we slice the string up to that point
$selector: str-slice($selector, 0, $modifier-start);
}
// we insert the dot that we removed to the start
$selector: str-insert($selector, '.', 1);
@return $selector;
}
@mixin blck($block) {
.#{$ns}#{$block} {
@content;
}
}
@mixin elem($element) {
$selector: &;
@if contains-modifier($selector) {
$block: get-block($selector);
@at-root {
#{$selector} {
#{$block+$es+$element} {
@content;
}
}
}
} @else {
@at-root {
#{$selector+$es+$element} {
@content;
}
}
}
}
@mixin modf($modifier) {
$selector: &;
@at-root {
#{$selector}#{$selector+$ms+$modifier} {
@content;
}
}
}
@include blck(block) {
background: red;
@include elem(child){
color: blue;
};
@include modf(modifier) {
background: blue;
@include elem(child) {
color: red;
}
}
}
我不知道它是否完全符合您的需求或涵盖了您想要做的所有情况,但我希望它能有所帮助。