sass css:来自孩子的目标父类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9293891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 02:59:26  来源:igfitidea点击:

sass css: target parent class from child

csssass

提问by Zeljko

I am using sass and found a problem. This is an example of what I am trying to do:

我正在使用 sass 并发现了一个问题。这是我正在尝试做的一个例子:

.message-error {
    background-color: red;

    p& {
        background-color: yellow
     }
  }

Expected css:

预期的CSS:

.message-error {
    background-color: red;
}
p.message-error {
    background-color: yellow ;
}

The idea: all elements with .message-error will be red, except if it is p.message-error. This is not real-life situation, just to show an example.

想法:所有带有 .message-error 的元素都将是红色的,除非它是 p.message-error。这不是现实生活中的情况,只是举个例子。

SASS is not able to compile this, I even tried string concatenation. Is there some plugin that will do exactly the same?

SASS 无法编译这个,我什至尝试过字符串连接。是否有一些插件可以完全相同?

NOTE: I know I can put another css definition like

注意:我知道我可以放置另一个 css 定义,例如

p.message-error{....}

under, but I would like to avoid that and use one place for all .message-error definitions.

下,但我想避免这种情况,并为所有 .message-error 定义使用一个地方。

Thanks.

谢谢。

回答by cimmanon

As of Sass 3.4, this is now supported. The syntax looks like this:

从 Sass 3.4 开始,现在支持此功能。语法如下所示:

.message-error {
    background-color: red;

    @at-root p#{&} {
        background-color: yellow
    }
}

Note the @at-rootdirective and the interpolation syntax on the ampersand. Failure to include the @at-rootdirective will result in a selector like .message-error p.message-errorrather than p.message-error.

请注意@at-root&符号上的指令和插值语法。不包含该@at-root指令将导致选择器类似于.message-error p.message-error而不是p.message-error.

回答by piouPiouM

Natalie Weizenbaum(the lead designer and developer of Sass) says it will never be supported:

Natalie Weizenbaum(Sass 的首席设计师和开发者)说它永远不会得到支持:

Currently, &is syntactically the same as an element selector, so it can't appear alongside one. I think this helps clarify where it can be used; for example, foo&barwould never be a valid selector (or would perhaps be equivalent to foo& baror foo &bar). I don't think this use case is strong enough to warrant changing that.

目前,&在语法上与元素选择器相同,因此它不能与元素选择器一起出现。我认为这有助于阐明它的用途;例如,foo&bar永远不会是一个有效的选择器(或者可能等同于foo& barfoo &bar)。我认为这个用例不足以保证改变它。

Source: #282 – Element.parent selector

来源:#282 – Element.parent 选择器

To my knowledge, there is no possible workaround.

据我所知,没有可能的解决方法。

回答by justnorris

The best thing to do would be probably this (assuming you have a little more in your .message-error class than just background color.

最好的办法可能是这样(假设您的 .message-error 类中不仅仅是背景颜色。

.message-error {
  background-color: red;
}

p.message-error {
  @extend .message-error;
  background-color: yellow
}

This approach doesn't offer that close grouping, but you can just keep them close to each other.

这种方法不提供紧密的分组,但您可以让它们彼此靠近。

回答by Quentin Veron

I had the same problem so I made a mixin for that.

我遇到了同样的问题,所以我为此做了一个 mixin。

@mixin tag($tag) {
  $ampersand: & + '';
  $selectors: simple-selectors(str-replace($ampersand, ' ', ''));

  $main-selector: nth($selectors, -1);
  $previous-selectors: str-replace($ampersand, $main-selector, '');

  @at-root {
     #{$previous-selectors}#{$tag}#{$main-selector} {
      @content;
    }
  }
}

To make it work, you will need a string replacement functionas well (from Hugo Giraudel):

为了使其工作,您还需要一个字符串替换函数来自 Hugo Giraudel):

@function str-replace($string, $search, $replace: '') {
  $index: str-index($string, $search);
  @if $index {
    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
  }
  @return $string;
}


How it works:

这个怎么运作:

SCSS

社会保障局

.foo {
  color: blue;

  @include tag(p) {
    color: red;
  }
}

Output

输出

.foo {
  color: blue;
}

p.foo {
  color: red;
}

Use case
This method works with nested selectors but not whit compound ones.

用例
此方法适用于嵌套选择器,但不适用于复合选择器。

回答by Dominic

This is how you do it

这就是你的方法

.Parent {
  $parentClass: &;

  &-Child {
    #{$parentClass}:focus & {
      border: 1px solid red;
    }

    #{$parentClass}--disabled & {
      background-color: grey;
    }
  }
}

It works at any level afaik, and however deep you want to go.

它适用于任何级别的 afaik,无论您想走多深。

回答by ScottS

I think if you want to keep them grouped by parent selector, you might need to add a common parent:

我想如果你想让它们按父选择器分组,你可能需要添加一个共同的父:

body {
    & .message-error {background-color: red;}
    & p.message-error {background-color: yellow}
}

Of course, bodycould be replaced with some other common parent, such as #Contentor another divname that will contain all the error messages.

当然,body可以替换为其他一些常见的父级,例如#Contentdiv包含所有错误消息的另一个名称。

UPDATE (Another Idea)

更新(另一个想法)

If you leverage @forand liststhen it seems like this should work (what I don't know for sure is if the list will allow the .(period).

如果您利用@for列表,那么这似乎应该有效(我不确定列表是否允许.(句点)。

@for $i from 1 to 3 {
  nth(. p. ul., #{$i})message-error {
    background-color: nth(red yellow cyan, #{$i}));
  }
}

Should compile to something like:

应该编译为:

.message-error {
   background-color: red;}
p.message-error {
   background-color: yellow;}
ul.message-error {
   background-color: cyan;}

回答by Tian

@Zeljko It is no possible to do what you want via SASS.

@Zeljko 通过 SASS 做你想做的事是不可能的。

See Nex3 comment: https://github.com/nex3/sass/issues/286#issuecomment-7496412

见 Nex3 评论:https: //github.com/nex3/sass/issues/286#issuecomment-7496412

The key is the space before the '&':

关键是'&'之前的空格:

.message-error {
    background-color: red;

    p & {
        background-color: yellow
     }
  }

instead of:

代替:

.message-error {
    background-color: red;

    p& {
        background-color: yellow
     }
  }

回答by Adam Youngers

I have ran into this before as well. Bootstrap 3 handles this using a parent selector hack. I've tweaked it slightly for my own purposes...

我以前也遇到过这种情况。Bootstrap 3 使用父选择器 hack 来处理这个问题。为了我自己的目的,我已经稍微调整了它......

@mixin message-error() {
  $class: '.message-error';
  #{$class} {
    background-color: red;
  }
  p#{$class} {
    background-color: yellow;
  }
}
@include message-error();

wheresrhys uses a similar approach above, but with some sass errors. The code above allows you to manage it as one block and collapse it in your editor. Nesting the variable also makes it local so you can reuse $class for all instances where you need to apply this hack. See below for a working sample...

wheresrhys 使用了上面类似的方法,但有一些 sass 错误。上面的代码允许您将其作为一个块进行管理并在编辑器中折叠它。嵌套变量也使其成为本地变量,因此您可以在需要应用此 hack 的所有实例中重用 $class。请参阅下面的工作示例...

http://sassmeister.com/gist/318dce458a9eb3991b13

http://sassmeister.com/gist/318dce458a9eb3991b13

回答by imkremen

I made a mixin that solves this problem.

我做了一个混合来解决这个问题。

Github: https://github.com/imkremen/sass-parent-append

Github:https: //github.com/imkremen/sass-parent-append

Example: https://codepen.io/imkremen/pen/RMVBvq

示例:https: //codepen.io/imkremen/pen/RMVBvq



Usage (scss):

用法(scss):

.ancestor {
  display: inline-flex;

  .grandparent {
    padding: 32px;
    background-color: lightgreen;

    .parent {
      padding: 32px;
      background-color: blue;

      .elem {
        padding: 16px;
        background-color: white;

        @include parent-append(":focus", 3) {
          box-shadow: inset 0 0 0 8px aqua;
        }

        @include parent-append(":hover") {
          background-color: fuchsia;
        }

        @include parent-append("p", 0, true) {
          background-color: green;
        }
      }
    }
  }
}

Result (css):

结果(CSS):

.ancestor {
  display: inline-flex;
}
.ancestor .grandparent {
  padding: 32px;
  background-color: lightgreen;
}
.ancestor .grandparent .parent {
  padding: 32px;
  background-color: blue;
}
.ancestor .grandparent .parent .elem {
  padding: 16px;
  background-color: white;
}
.ancestor:focus .grandparent .parent .elem {
  box-shadow: inset 0 0 0 8px aqua;
}
.ancestor .grandparent .parent:hover .elem {
  background-color: fuchsia;
}
.ancestor .grandparent .parent p.elem {
  background-color: green;
}

回答by Darex1991

I created package/mixin with a similar solution :) (Maybe it will help U)

我用类似的解决方案创建了 package/mixin :)(也许它会帮助你)

https://github.com/Darex1991/BEM-parent-selector

https://github.com/Darex1991/BEM-parent-selector

so writing:

所以写:

.calendar-container--theme-second-2 {
  .calendar-reservation {
    @include BEM-parent-selector('&__checkout-wrapper:not(&--modifier):before') {
      content: 'abc';
    }
  }
}

This mixin will add selector only for the last parent:

这个 mixin 只会为最后一个父级添加选择器:

.calendar-container--theme-second-2 .calendar-reservation__checkout-wrapper:not(.calendar-reservation--modifier):before {
   content: 'abc';
 }

More info on the repo.

有关回购的更多信息。