sass 合并符号上的选择器

sass merge selectors on ampersand

假设我有一个现有的 SASS 规则,例如:

[dir] .foo {
   background-image: ...;
   // ... some more
}

我想为 ltr / rtl 添加特定的行为,例如:

[dir] .foo {
   background-image: ...;
   [dir='ltr'] & {
     padding-right: ...;
   }
   [dir='rtl'] & {
     padding-left: ...;
   }
}

这会产生不需要的 css,例如:

[dir='rtl'] [dir] .foo {
    padding-left: ...;
}

这与我想要的不符。

假设我不能更改父选择器(由于特殊性),有什么方法可以编写这样的嵌套选择器,使其仅编译为 [dir='rtl'] .foo {...} 嵌套元素?

关于符号的一些资源:https://css-tricks.com/the-sass-ampersand/#aa-qualifying-based-on-context

我不知道如何按要求合并选择器。

由于不允许更改父选择器,我看到的唯一解决方案是使用 @at-root 规则。

@at-root

The @at-root rule is usually written @at-root { ... } and causes everything within it to be emitted at the root of the document instead of using the normal nesting. It's most often used when doing advanced nesting with the SassScript parent selector and selector functions.

sass-lang 上的定义。


这是一个例子:

[dir] .foo {
    $root: '.foo';

    background-image: linear-gradient(black, white);

    @at-root {
        [dir=ltr] #{$root} {
            padding-right: 1em;
        }

        [dir=rtl] #{$root} {
            padding-left: 1em;
        }
    }
}

这将编译为:

[dir] .foo {
  background-image: linear-gradient(black, white);
}
[dir=ltr] .foo {
  padding-right: 1em;
}

[dir=rtl] .foo {
  padding-right: 1em;
}

您可以创建一个 mixin 来帮助您:

@mixin dir($dir: ltr, $selector: &) {
    @at-root {
        [dir=#{$dir}] #{$selector} {
            @content;  
        }
    }
}

[dir] .foo {
    $root: '.foo';
    background-image: linear-gradient(black, white);

    @include dir(ltr, $root) {
        padding-right: 1em;
    }
   
    @include dir(rtl, $root) {
        padding-right: 1em;
    }
}

精神食粮

如果您不必支持 Internet Explorer,您可能需要检查 padding-inline-endpadding-inline-start 属性。

它们将使您无需为不同的方向制定不同的规则。

padding-inline-end

The padding-inline-end CSS property defines the logical inline end padding of an element, which maps to a physical padding depending on the element's writing mode, directionality, and text orientation.

MDN Docs - padding-inline-end

padding-inline-start

The padding-inline-start CSS property defines the logical inline start padding of an element, which maps to a physical padding depending on the element's writing mode, directionality, and text orientation.

MDN Docs - padding-inline-start