我正在设计一个媒体查询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。
有关如何实现这一目标的任何创意建议?我错过了一些明显的东西吗?