CSS 使用 Sass 从媒体查询中扩展选择器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14840918/
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
Extending selectors from within media queries with Sass
提问by soundly_typed
I have an item class and a compact "modifier" class:
我有一个项目类和一个紧凑的“修饰符”类:
.item { ... }
.item.compact { /* styles to make .item smaller */ }
This is fine. However, I'd like to add a @media
query that forces the .item
class to be compact when the screen is small enough.
这可以。但是,我想添加一个@media
查询,.item
当屏幕足够小时强制类紧凑。
On first thought, this is what I tried to do:
乍一看,这就是我试图做的:
.item { ... }
.item.compact { ... }
@media (max-width: 600px) {
.item { @extend .item.compact; }
}
But this generates the following error:
但这会产生以下错误:
You may not @extend an outer selector from within @media. You may only @extend selectors within the same directive.
您不能从@media 内部@extend 外部选择器。您只能在同一指令中使用 @extend 选择器。
How would I accomplish this using SASS without having to resort to copy/pasting styles?
我将如何使用 SASS 完成此操作而不必求助于复制/粘贴样式?
回答by cimmanon
The simple answer is: you can't because Sass can't (or won't) compose the selector for it. You can't be inside of a media query and extend something that's outside of a media query. It certainly would be nice if it would simply take a copy of it instead of trying to compose the selectors. But it doesn't so you can't.
简单的答案是:你不能,因为 Sass 不能(或不会)为它组合选择器。您不能在媒体查询内部并扩展媒体查询之外的内容。如果它只是简单地复制它而不是尝试组合选择器,那当然会很好。但事实并非如此,所以你不能。
Use a mixin
使用混合
If you have a case where you're going to be reusing a block of code inside and outside of media queries and still want it to be able to extend it, then write both a mixin and an extend class:
如果您要在媒体查询内部和外部重用代码块,并且仍然希望它能够扩展它,那么编写一个 mixin 和一个扩展类:
@mixin foo {
// do stuff
}
%foo {
@include foo;
}
// usage
.foo {
@extend %foo;
}
@media (min-width: 30em) {
.bar {
@include foo;
}
}
Extend the selector within a media query from the outside
从外部扩展媒体查询中的选择器
This won't really help your use case, but it is another option:
这不会真正帮助您的用例,但它是另一种选择:
%foo {
@media (min-width: 20em) {
color: red;
}
}
@media (min-width: 30em) {
%bar {
background: yellow;
}
}
// usage
.foo {
@extend %foo;
}
.bar {
@extend %bar;
}
Wait until Sass lifts this restriction (or patch it yourself)
等到 Sass 解除此限制(或自行修补)
There are a number of ongoing discussions regarding this issue (please don't contribute to these threads unless you have something meaningful to add: the maintainers are already aware that users desire this functionality, it's just a question of how to implement it and what the syntax should be).
关于这个问题有很多正在进行的讨论(请不要对这些线程做出贡献,除非你有一些有意义的东西要添加:维护者已经意识到用户想要这个功能,这只是一个如何实现它以及它是什么的问题语法应该是)。
回答by soundly_typed
For the record, here is how I ended up solving the problem with only duplicating generated styles once:
作为记录,这是我最终仅复制生成的样式一次来解决问题的方法:
// This is where the actual compact styles live
@mixin compact-mixin { /* ... */ }
// Include the compact mixin for items that are always compact
.item.compact { @include compact-mixin; }
// Here's the tricky part, due to how SASS handles extending
.item { ... }
// The following needs to be declared AFTER .item, else it'll
// be overridden by .item's NORMAL styles.
@media (max-width: 600px) {
%compact { @include compact-mixin; }
// Afterwards we can extend and
// customize different item compact styles
.item {
@extend %compact;
/* Other styles that override %compact */
}
// As shown below, we can extend the compact styles as many
// times as we want without needing to re-extend
// the compact mixin, thus avoiding generating duplicate css
.item-alt {
@extend %compact;
}
}
回答by JHogue
I believe SASS/SCSS does not support the @extend
directive inside of a media query. http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/
我相信 SASS/SCSS 不支持@extend
媒体查询中的指令。http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/
You might need to use a mixin instead, though the code bloat needs to be weighed against your objective.
您可能需要改用 mixin,但需要根据您的目标权衡代码膨胀。
回答by Tom Genoni
This is the cleanest, partial solution I've found. It takes advantage of @extend where possible and falls back to mixins when inside media queries.
这是我找到的最干净的部分解决方案。它在可能的情况下利用 @extend 并在媒体查询中回退到 mixins。
Cross-Media Query @extend Directives in Sass
See the article for full details but the gist is that you call a mixin 'placeholder' that then decides whether to output @extend or an @include.
有关完整详细信息,请参阅文章,但要点是您调用 mixin“占位符”,然后决定是输出 @extend 还是 @include。
@include placeholder('clear') {
clear: both;
overflow: hidden;
}
.a {
@include _(clear);
}
.b {
@include _(clear);
}
.c {
@include breakpoint(medium) {
@include _(clear);
}
}
Ultimately it may not be better than just using mixins, which is currently the accepted answer.
最终它可能不会比仅仅使用 mixins 更好,这是目前公认的答案。
回答by Nesha Zoric
I use breakpoints, but it's the same idea:
我使用断点,但它的想法是一样的:
@mixin bp-small {
@media only screen and (max-width: 30em) {
@content;
}
How to use it:
如何使用它:
.sidebar {
width: 60%;
float: left;
@include bp-small {
width: 100%;
float: none;
}
}
There is a textabout mixins where you can find out more about this option.
回答by Jason M. Batchelor
Could you restructure?
你能重组吗?
.compact { //compact-styles }
.item {}
.item.compact { @extend .compact }
@media (max-width: 600px) {
.item { @extend .compact; }
}
If I understand the documentation correctly, that should work. I think the reason the way you're trying won't work is that it doesn't see .item.compact when it's parsing the @extend, but that's an uninformed guess, so take that with a truck load of salt! :)
如果我正确理解文档,那应该可行。我认为您尝试的方式不起作用的原因是它在解析@extend 时看不到 .item.compact,但这是一个不知情的猜测,所以用一卡车的盐来处理它!:)