我喜欢嵌套我的 @media 查询断点。对我来说,这可能是 Sass 最重要的功能。也许我 选择一种方法 并像这样操作
.element {
display: grid;
grid-template-columns: 100px 1fr;
@include breakpoint(baby-bear) {
display: block;
}
}
这足够简单。但是,如果我的元素有几个子元素,并且断点也影响它们呢?有不同的方法,我从来都不确定我应该使用哪一种。
我可以为每个子元素复制断点
.parent {
@include breakpoint(desktop) {
}
.child {
@include breakpoint(desktop) {
}
}
.child-2 {
@include breakpoint(desktop) {
}
}
}
编译后的 CSS 类似于以下内容
@media screen and (min-width: 700px) {
.parent {
}
}
@media screen and (min-width: 700px) {
.parent .child {
}
}
@media screen and (min-width: 700px) {
.parent .child-2 {
}
}
或者,我可以在第一个嵌套断点下复制子元素
.parent {
@include breakpoint(desktop) {
.child {
}
.child-2 {
}
}
.child {
}
.child-2 {
}
}
这将导致
@media screen and (min-width: 700px) {
.parent .child {
}
.parent .child-2 {
}
}
.parent .child {
}
.parent .child-2 {
}
或者我可以结合两种方法。由于存在重复,因此这两种方法都不太理想,但我不确定这里是否有完美的答案。我更倾向于复制媒体查询,因为它似乎比复制选择器更不容易出错。
我使用第一种方法,并依赖构建工具来组合媒体查询(postcss 插件)
哪个 postcss 插件?
我同意,不确定是否有完美的答案。我试图最大程度地减少媒体查询的数量,但发现自己并不始终如一。
我也有同样的问题。对我来说,这取决于更改的数量和子元素的复杂性。对于复杂的子元素,我将媒体查询嵌套在子元素中。如果只需要更改某些属性,则将它们分组到一个媒体查询中。
我通常(如果嵌套不可避免)使用前一种方法进行复制,并使用一些后处理器(postcss、webpack 加载器等)优化结果以将相同的媒体查询组合到一个条目中。这样,您可以编写可重用的代码块,同时避免使 css 文件膨胀;)
我仍然将我的断点放在文件末尾,因为这样更容易看到模块在给定断点处的整体变化。在使用多个断点时,组织起来也容易得多。
模块很少大到足以让这种方法变得笨拙,而且,如果您组织项目以使断点都沿相同方向缩放,则很容易发现意大利面条代码。
这种输出冗余一直困扰着我。如果处理器识别文档中重复的媒体查询并在末尾设置每个查询一次,并将所有相关内容移动到内部,那将非常棒。
我通常尝试在可能影响该“树”中最高级别的选择器处设置断点,然后将所有受其影响的子元素放在该断点内。
这有点更容易出错,但它也使在同一个地方清楚地了解在不同断点处发生了哪些变化,而不是在寻找某个在某个断点上不太正确的内容时必须通读每个单独的选择器。
嵌套很多时非常有用的 Gulp 工具:https://github.com/hail2u/node-css-mqpacker
这完全是关于输出,对吧?我想我可以理解在输出中组合媒体查询如何节省一些字节,但我认为 gzip 使其变得微不足道,并且浏览器在速度方面似乎并不关心。我主要好奇的是创作体验。
它与大小有关,但在我们的案例中,主要与创作有关。在很多代码的情况下,第二个示例很快就会变得难以管理,尤其是在嵌套很多的情况下。而且我们也认为第一个示例更清晰易懂。
第二个,但媒体查询位于它们修改的样式之后,例如,在关闭父元素之前的最后一件事。
我非常喜欢第一种方法——将所有样式嵌套在选择器下感觉很好,而不是在媒体查询中复制选择器。这使您可以通过一次视觉扫描了解应用于选择器的所有 CSS。
我的思维方式是基于选择器的:“这个选择器在某个断点处做什么?”
而不是:“在某个断点处,让我们看看我需要的选择器是否正在更改”
当然,其他人可能有不同的思维方式。
当然,其他人可能有不同的思维方式。
绝对的!对我来说,这完全相反——我将其视为屏幕,有点像 @media 自己打开了一个 css 表格,这就是为什么我非常喜欢第二种方法的原因:如果我要手动编写代码,我会完全按照这种方式编写。
我同意你的观点,Andy,我的大脑也是这样工作的。这实际上就是我最初选择使用这种方法而不是为每个断点使用单独的 scss 样式表的原因——当样式分散时,查找/理解应用于特定选择器的所有样式非常困难。
简单的解决方案是使用 postcss 插件 mq-packer。
它捆绑媒体查询
我几个小时前也在思考这个问题,所以考虑包装 CSS 或 Sass 变量而不是嵌套媒体查询
对我来说,第二个选项更容易理解,并且为新开发人员快速了解项目提供了更好的可读性。
当每个组件只有一个断点时,查找特定断点处的特定样式要容易得多。
对于小的调整,我喜欢嵌套多个媒体查询,如下所示
这使您可以轻松跟踪正在修改的内容,而不必在类中来回切换以查看所有不同的媒体查询。
但是,这会导致混乱的编译结果
幸运的是,设置为组合媒体查询的压缩器将解决此问题
对我来说,我更喜欢使用变量和
@media
而不是使用 mixin有一个 postcss 插件可以组合媒体查询。
我使用移动优先方法,首先设置基本样式,并在下面设置一个“响应式部分”,在其中进行一些布局覆盖。这让我对级联也有最清晰的了解。你可以说大屏幕是一个功能!
我喜欢第一种方法,就像在说“好的,现在你在这个断点处执行该操作”。
此外,当您压缩 css 时,重复不是问题。
嘿,在你的最后一个示例中。子 div 元素将覆盖媒体查询中的 CSS,因为级联——
我正是这样做的。当您有上下文时,更容易理解。
我绝对同意,使用 scss 嵌套媒体查询是语法最重要的功能。
我个人选择在每个子元素中复制媒体查询,因为对我来说这是最有意义的,该元素的所有样式都保存在同一个地方。我不会忘记将样式分离到文件上半部分。
与此相关,我最近一直在努力避免编写任何嵌套的子规则。因为我发现它会使增加特异性变得更加微妙,并且我可能会在编译后的代码中开始使用非常深的的选择器,这可能会在以后给我带来问题。像普通 CSS 一样保持选择器扁平化,这使得这种增加的特异性对我来说更加明显,因为我实际上正在编写这些父级子级选择器,并且它会触发我的思考过程,以确定我是否真的需要这种嵌套。
我喜欢第二种方法,因为它更容易管理,而且重复性更少,此外,将来可以根据屏幕尺寸轻松地将其移动到单独的文件中。
我倾向于使用您提到的第一种方法。不幸的是,这会创建许多重复的媒体查询。我尝试过各种 Gulp 媒体查询组合器,但它们似乎给我提供了混合的结果。其他人尝试过这些吗?比如 gulp-combine-mq?
我真的很想尽可能避免在 Sass 中嵌套,因此我将继续使用第一种方法。然后,我将使用低特异性的选择器,并在之后将断点应用于它们。我觉得这可以清理 Sass,并且模拟处理后的 CSS 的外观,在编写时同时考虑这两个问题。
只有在单个断点上有大量更改时,我才会选择第二种方法。
通常,如果设计适合,我会创建一个断点,而不仅仅是一组断点。因此,我通常会像选项 #1 那样编写代码。
我以前使用第一种方法,但在大型项目(包含大量 SCSS 包含文件)中,编译后的 CSS 文件大小(以 KB 为单位)非常大。
我发现将所有 @media 规则保留在我使用的每个 SCSS 文件的底部很有用。因此,如果我在其 _info-box.scss 文件中有一个 .info-box 元素,我习惯于将所有 @media 规则放在 .info-box {} 块的正下方。
这就是我了解在哪里找到所有内容的方式。每个元素/组件都有自己的 SCSS 文件,其中包含所有断点信息。
我个人使用 combine MQ 插件并在子元素下方添加断点。因为我首先开发移动端,所以它更容易阅读和理解。
https://npmjs.net.cn/package/combine-mq
我很少再嵌套选择器了,但如果我确实嵌套,我通常仍然将媒体查询直接放在选择器中。这使每个选择器都保持自包含并处理其自身的位置。即使不嵌套选择器,这种方法也基本上相同,因为媒体查询会进入选择器主体。
每个项目都可能不同,在我的情况下,设计似乎总是以硬断点为基础创建的。话虽如此,我喜欢为组件、页面、结构模板等维护一个多级文件夹结构。有一个用于全局元素的文件夹,以及用于共享相同资源的项目的子文件夹。
话虽如此,我有一个主构造文件,然后导入特定设备的断点(您典型的屏幕尺寸),其中包含每个组中的所有组件、布局元素等。在每个组件文件夹中,都有一个根据宽度定义的文件集合,多个开发人员可以访问同一个文件,并且不会对在哪里放置断点感到困惑,因为这个决定是由文件的架构做出的。通常不会有更进一步的子断点,尽管某些视网膜查询最终可能会出现在其中。设置所有文件和导入操作会稍微麻烦一些,但这种结构已成功地用于许多大规模的快速开发项目。
有趣!我也使用第一种方法。我认为将所有影响一个元素的样式尽可能地放在一起更“合理”。
我不嵌套选择器。
.parent {
@include breakpoint(full-hd) {
// …
}
}
.parent__child-1 {
@include breakpoint(full-hd) {
// …
}
}
.parent__child-2 {
@include breakpoint(full-hd) {
// …
}
}
// ————————————–
// 我使用伪元素和标题注释来提高清晰度
我总是选择第一种方法。到目前为止,它对我来说更好,也更易读 :)
我一直(或至少 99% 的时间)使用 #1。所有事情都发生在该选择器内部。
我更喜欢第一种风格:定义选择器的基本样式,然后在其内部嵌套每个断点的调整。它将选择器的所有样式都保留在一个地方,这使得非常容易查看它们是否以及如何在任何特定断点处被修改。
它也更简洁、更不容易出错,因为您只需定义每个选择器一次。如果您使用相反的方法定义一组媒体查询,然后在每个查询中复制选择器,则更容易犯错而不自知(例如,在一个媒体查询下编写
.parent .child
,但在另一个媒体查询下编写.parent.child
)。我并不特别关心输出是什么样子,因为最终所有内容都会被压缩/连接。我宁愿让编写过程更易读且更不容易出错。
或者您可以使用 https://github.com/hail2u/node-css-mqpacker 然后忘记它。