使用Sass将嵌套选择器组合成单元素选择器?

时间:2013-09-11 18:30:22

标签: sass

我正在设计一个媒体查询mixin,它为不支持的浏览器使用回退选择器(不是我们都是吗?)在Sass中,嵌套的@media查询效果很好,但对于假媒体查询使用不是很多根元素上的类名。这是一个例子。首先,简化mixin:

@mixin contextualize($context, $what-to-output: both) {
    @if $what-to-output == query or $what-to-output == both {
        // let's assume that the media query is always the first or only element in
        // $context
        @media #{nth($context, 1)} { @content; }
    }
    @if $what-to-output == selector or $what-to-output == both {
        // similarly, the fallback selector is the second element in the context
        #{nth($context, 2)} & { @content; }
    }
}

现在是一个使用示例:

// small-device context -- media query with class-based fallback
$pocket: "(max-width: 25em)" ".pocket";
// touch support -- new CSS4 media query, again with a class-based fallback
$touch: "(pointer: coarse)" ".touch";

$output: both;

@include contextualize($pocket, $output) {
    .menu a {
        display: block;
        color: red;
        @include contextualize($touch) {
            // make sure menu items are big enough to tap
            min-height: 44px;
        }
    }
}

如果我们只是输出媒体查询(通过将$output更改为media),则效果很好:

@media (max-width: 25em) {
    .menu a {
        display: block;
        color: red;
    }
}
@media (max-width: 25em) and (pointer: coarse) {
    .menu a {
        min-height: 44px;
    }
}

但是如果我们输出回退(让我们将$output设置为selector,那么我们就不会得到回退媒体查询,只是为了保持输出简单):

.pocket .menu a {
    display: block;
    color: red;
}
// so far, so good...
.touch .pocket .menu a {
    min-height: 44px;
}
// wait, that's supposed to be .touch.pocket, not .touch .pocket -- we're only
// putting our fallback classes on the root HTML element, so it has to be a
// long string of concatenated classes.

设计原理:我希望能够嵌套我的上下文并让它正常工作。据我所知,你在Sass中无法做任何事情,因为你无法分解父选择器,Sass 3.4中的新@at-root选择器也无济于事。似乎Breakpoint人已经决定它也不可行,因为他们说

  

传入包装器时,必须编写整个包装器,并且可能包含复合包装器[...]

所以他们显然希望你以避免嵌套上下文的方式编写你的Sass。

有关如何实现这一目标的任何创意建议?我错过了一些明显的东西吗?

0 个答案:

没有答案