6

我已经使用 display:inline-block 为按钮设置了一个 mixin。我正在尝试找到最终将使用 mixim 的任何类的父类,因此我可以在那里添加 font-size: 0px 行以确保我不需要对我的 HTML 进行调整以避免不需要的每个按钮之间的空间。

这是一个例子......我想要。父类接收 font-size: 0px 行。

@mixin button() {
    display:inline-block;
    font-size: 1em;
    //other stuff to make a pretty button
    && { font-size: 0px; }
}

.parent{
    .child {
        @include button();
    }
}
4

4 回答 4

13

从 Sass 3.4 开始,这现在是可能的。

@mixin parent {

  @each $selector in & {

    $l: length($selector);

    @if ($l == 1) {
      @error "Used parent mixin on a top-level selector";
    } @else {

      $parent: nth($selector,1);
      @for $i from 2 to $l {
        $parent: append($parent,nth($selector,$i));
      }

      @at-root #{$parent} {
        @content;
      }

    }
  }
}

// Use
.grandparent {
  .parent{
      .child {
        font-size: 1em;
          @include parent {
            font-size: 0px;
          }
      }
  }
}

// Result
.grandparent .parent .child {
  font-size: 1em;
}
.grandparent .parent {
  font-size: 0px;
}

// Errors:
.root {
  @include parent {
    content: "Won't work";
  }
}
.grandparent .parent, .root {
  @include parent {
    content: "Also won't work";
  }
}
于 2014-09-03T15:23:36.057 回答
7

不,这是不可能的。不过,您可以执行以下操作:

@mixin button($child: '.child') {
    font-size: 0px;
    //other stuff to make a pretty button

    #{$child} {
        display:inline-block;
        font-size: 1em;
    }
}

.parent{
    @include button();
}

输出:

.parent {
  font-size: 0px;
}
.parent .child {
  display: inline-block;
  font-size: 1em;
}
于 2013-04-22T15:38:44.023 回答
2

有一个XXX!CSS 4 规范草案中的选择器,它将按照您喜欢的方式运行。如果选择器匹配,它会宣布 CSS 样式声明的主题

所以如果你有这个选择器

.a > .b! > .c

例如,它将为此匹配

<div class="a">
    <div class="b">
        <div class="c">
        </div>
    </div>
</div>

但是样式声明不会在 生效.c,而是在生效.b,因为我用感叹号声明,这个元素应该是样式 http://dev.w3.org/csswg/selectors4/#subject的主题

您现在无法立即使用它。但是有一个 jQuery 插件,它是一个 polyfill。http://dev.w3.org/csswg/selectors4/

另请参阅此堆栈:是否有 CSS 父选择器?

如何申请?好吧,我在 SASS 中并不确切知道,但在 LESS 中它会是

*! > & {
    /* ... */
}
于 2013-04-22T16:15:36.273 回答
0

虽然 Karol 的答案近乎完美,但它没有考虑伪元素或伪选择器。此外,如果使用多个复杂选择器,则会重复代码。我想出了一个简化版本:

@mixin parent {
    $parents: ();
    $parent: '';

    @each $selector in & {
        $length: length($selector);
        $index: 0;
        $last-selector: nth($selector, $length);

        @if ($length == 1) {
            @error "Used parent mixin on a top-level selector";
        } @else {
            $index: str-index($last-selector, '::');

            @if ($index) {
                $last-selector: str-slice($last-selector, 1, $index - 1);
            } @else {
                $last-selector: null;
            }
            // Inspect allows us to combine two selectors in one block.
            $parent: inspect(set-nth($selector, $length, #{$last-selector}));
            $parents: join($parents, $parent, comma);
        }
    }
    @at-root #{$parents} {
        @content;
    }
}

有第一个循环遍历选择器列表(选择器末尾带有逗号)。因为复杂的选择器也被视为一个列表,我们只需要删除列表的最后一个元素。没有循环遍历复合选择器或简单选择器,因为我们只需要丢弃最后一个。

Sass 中没有删除列表元素的功能,但我们可以使用 设置元素的值set-nth。通过将最后一个元素设为空字符串并取消引用,我们可以从列表的打印表示(字符串)中删除最后一个元素。由于选择器可以是字符串,我们只需将新字符串用作选择器。

使用以下内容时:

.grandmother,
.grandfather {
  .parent {
      .child {
        font-size: 10em;
          @include parent {
            font-size: 5em;
          }

          &::after {
            font-size: 1px;
            @include parent {
              font-weight: bold;
            }
          }
      }
  }
}

我们得到以下信息:

.grandmother .parent .child,
.grandfather .parent .child {
  font-size: 10em;
}
.grandmother .parent,
.grandfather .parent {
  font-size: 5em;
}
.grandmother .parent .child::after,
.grandfather .parent .child::after {
  font-size: 1px;
}
.grandmother .parent .child,
.grandfather .parent .child {
  font-weight: bold;
}

注意:伪元素和伪选择器不是元素的子元素,而是附加到元素上,因此它们本身没有父元素。我认为父母是指 Sass 嵌套意义上的父母。

于 2017-09-09T00:18:08.717 回答