我正在使用sass并发现问题。这是我想要做的一个例子:
.message-error {
background-color: red;
p& {
background-color: yellow
}
}
预期的css:
.message-error {
background-color: red;
}
p.message-error {
background-color: yellow ;
}
这个想法:所有带有.message-error的元素都是红色的,除非它是p.message-error。这不是现实生活中的情况,只是为了展示一个例子。
SASS无法编译这个,我甚至尝试过字符串连接。是否有一些插件可以完全相同?
注意: 我知道我可以添加另一个css定义,如
p.message-error{....}
下,但我想避免这种情况,并为所有.message-error定义使用一个地方。
感谢。
答案 0 :(得分:28)
截至Sass 3.4,现在支持此功能。语法如下所示:
.message-error {
background-color: red;
@at-root p#{&} {
background-color: yellow
}
}
注意&@at-root
指令和&符号上的插值语法。如果未包含@at-root
指令,则会产生.message-error p.message-error
而不是p.message-error
的选择器。
答案 1 :(得分:20)
Natalie Weizenbaum(Sass的首席设计师和开发人员)表示永远不会支持它:
目前,
&
在语法上与元素选择器相同,所以它 不能一起出现。我认为这有助于澄清它的位置 用过的;例如,foo&bar
永远不会是一个有效的选择器(或者会 也许相当于foo& bar
或foo &bar
)。 我不认为这样用 案件足够强大,可以保证改变它。
来源:#282 – Element.parent selector
据我所知,没有可行的解决方法。
答案 2 :(得分:9)
最好的办法可能就是这样(假设你的.message-error类中的内容多于背景颜色。
.message-error {
background-color: red;
}
p.message-error {
@extend .message-error;
background-color: yellow
}
这种方法不提供紧密的分组,但你可以让它们彼此靠近。
答案 3 :(得分:2)
我认为如果你想让它们按父选择器分组,你可能需要添加一个共同的父代:
body {
& .message-error {background-color: red;}
& p.message-error {background-color: yellow}
}
当然,body
可以替换为其他公共父级,例如#Content
或其他div
名称,其中包含所有错误消息。
更新(另一个想法)
如果您使用@for和lists,那么它似乎应该可行(我不确定的是该列表是否允许.
(句号)。< / p>
@for $i from 1 to 3 {
nth(. p. ul., #{$i})message-error {
background-color: nth(red yellow cyan, #{$i}));
}
}
应编译为:
.message-error {
background-color: red;}
p.message-error {
background-color: yellow;}
ul.message-error {
background-color: cyan;}
答案 4 :(得分:2)
@Zeljko不可能通过SASS做你想做的事。
请参阅Nex3评论:https://github.com/nex3/sass/issues/286#issuecomment-7496412
关键是'&amp;'之前的空格:
.message-error {
background-color: red;
p & {
background-color: yellow
}
}
而不是:
.message-error {
background-color: red;
p& {
background-color: yellow
}
}
答案 5 :(得分:0)
我之前也遇到了这个问题。 Bootstrap 3使用父选择器hack处理此问题。为了我自己的目的,我稍微调整了一下......
@mixin message-error() {
$class: '.message-error';
#{$class} {
background-color: red;
}
p#{$class} {
background-color: yellow;
}
}
@include message-error();
wheresrhys使用了类似的方法,但有一些sass错误。上面的代码允许您将其作为一个块进行管理并在编辑器中将其折叠。嵌套变量也使其成为本地变量,因此您可以为需要应用此hack的所有实例重用$ class。请参阅下面的工作样本......
答案 6 :(得分:0)
我做了一个解决这个问题的混音。
Github:https://github.com/imkremen/sass-parent-append
示例:https://codepen.io/imkremen/pen/RMVBvq
用法(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;
}
}
}
}
}
结果(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;
}
答案 7 :(得分:0)
我遇到了同样的问题,所以为此做了一个混音。
@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;
}
}
}
要使其正常工作,您还需要一个字符串替换功能(from 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;
}
SCSS
.foo {
color: blue;
@include tag(p) {
color: red;
}
}
输出
.foo {
color: blue;
}
p.foo {
color: red;
}
用例
此方法适用于嵌套选择器,而不适用于复合选择器。
答案 8 :(得分:0)
我使用类似的解决方案创建了package / mixin:)(也许会对您有所帮助)
https://github.com/Darex1991/BEM-parent-selector
这样写:
.calendar-container--theme-second-2 {
.calendar-reservation {
@include BEM-parent-selector('&__checkout-wrapper:not(&--modifier):before') {
content: 'abc';
}
}
}
此mixin将仅为最后一个父项添加选择器:
.calendar-container--theme-second-2 .calendar-reservation__checkout-wrapper:not(.calendar-reservation--modifier):before {
content: 'abc';
}
有关回购的更多信息。
答案 9 :(得分:0)
这就是您的操作方式
.Parent {
$parentClass: &;
&-Child {
#{$parentClass}:focus & {
border: 1px solid red;
}
#{$parentClass}--disabled & {
background-color: grey;
}
}
}
它可以在任何级别的afaik上运行,无论您想深入多深。
答案 10 :(得分:-1)
这个作弊可能有用
{
$and: .message-error;
#{$and} {
background-color: red;
}
p#{$and} {
background-color: yellow
}
}
您甚至可以使用$&
作为变量名称,但我不是100%确定它不会引发错误。
并且SASS内置了范围,这使得不必担心$and
泄漏到样式表其余部分的价值
变量仅在嵌套选择器级别内可用 他们被定义的地方。如果它们是在任何嵌套之外定义的 选择器,它们随处可用。
答案 11 :(得分:-1)
在当前版本中:选择性史蒂夫(3.4.14)现在可以使用,只需要更新一下你的代码:
.message-error {
background-color: red;
p &{
background-color: yellow
}
}
这仅适用于嵌套的一个级别,例如,如果你有这样的东西它不起作用:
.messages{
.message-error {
background-color: red;
p &{
background-color: yellow
}
}
}