媒体查询scss断点的最佳实践



我和我的团队负责人就媒体查询的使用问题发生了一些争吵。关于使用媒体查询,有两种方法(据我所知)。

方法1:

@media only screen and (max-width: 600px) {
.container {
width: 100%;
}
}
@media only screen and (min-width: 600px) {
.container {
width: 90%;
}
}
@media only screen and (min-width: 768px) {
.container {
width: 80%;
}
}

方法2:

.container {
@media only screen and (max-width: 600px) {
width: 100%;
}
@media only screen and (min-width: 600px) {
width: 90%;
}
@media only screen and (min-width: 768px) {
width: 80%;
}
}

我是一名初级开发人员,我发现第二种方法更容易使用和理解。但我的老板告诉我要用第一种方法。老实说,我到处找了一个使用我喜欢的第二种方法的示例项目,但找不到!

所以我的问题是为什么?

在我看来,如果我想在这个例子中添加一些类来包装容器,在方法1中,我需要在每个断点中添加它,而在方法2中,我只需要添加一次!那么,第一种方法如何才是正确的做法呢?我错过了什么?

我认为这是一个很好的问题,我经常觉得分歧是由老派程序员造成的,他们习惯了SASS之前的生活,拒绝进入SASS和嵌套CSS的新时代。

方法1

优点

您可以将针对断点的每个媒体查询放在一个位置,这样当您想要进行多个更改时,更容易找到诊断到页面模板。

缺点

这很混乱,最终会出现多个类声明地方,所以在编辑一个元素或添加新元素时元素到HTML中,您最终不得不跨多个难以追踪的区域。

这需要大量的上下滚动才能找到媒体查询,然后编辑该单个类元素。

方法2——Jamie Murphy将这种范式称为"媒体查询气泡",类似于模块化CSS技术,如Block__Element——Modifier(BEM)

优点

所有东西都放在一个地方,很容易看到类并编辑其中使用的所有断点。

还可以快速添加新的断点来应用快速修复

它也更容易阅读和理解,一目了然。

缺点

老派开发商可能不喜欢它!!

有时候不好。如果你有一个固定的模板,你知道它不会改变。将整个CSS放在整个页面或区域使其更易于使用。您可以编辑多个类对于一个断点,所有断点都在一个位置。

结论

这取决于情况。我不认为这是我的方式或高速公路类型的场景,而是两者的混合。

在构建组件时,您通常希望将CSS保持在一个块中,如方法1中所示。但是,当您诊断一个已经组合在一起的整个站点并为特定元素插入单个断点时,使用方法2会变得更有意义。

我发现,我们创建的网站越多,我就越善于找出最适合这种情况的方法,上面的规则往往会引导我朝着正确的方向前进。

非常好的问题,我认为这值得一个完整的主题,这个答案有助于@Unbranded分享的所有东西。

我不认为在决定哪一个是更好的还是最好的做法时有对错之分。坚持一个并不意味着这一切都是正确的,这一切都与造型师习惯的方法有关,最重要的是它是如何使用的,成败都在这里。

我想你已经知道并熟悉这两种方法的最终编译CSS,当然,最终的束大小也是优化的一个考虑因素。

这就是方法2似乎失去意义的地方。

方法2 SCSS

.container {
width: 100%;

@media screen and (min-width: 768px) {
width: 50%;
}
&.red {
@media screen and (min-width: 768px) {
background: red;
width: 75%;
}
}
}

这就是上面CSS的编译方式,你可能会清楚地看到重复的字符串。扩大到一个真正的项目,这可能是一件需要考虑的事情。

方法2 CSS

.container { width: 100%; }
@media screen and (min-width: 768px) {
.container {
width: 50%;
}
}
@media screen and (min-width: 768px) {
.container.red {
background: red;
width: 75%;
}
}

M1您将主要在旧项目中看到,可能要追溯到2015年之前,并且每个响应查询可能都在一个单独的文件中。例如:

反应灵敏。移动。scss

@media screen and (max-width: 768px) {
// All the stuff
}

反应灵敏。平板电脑。scss

@media screen and (min-width: 768px) and (max-width: 1024px) {
// All the stuff
}

在过去,我曾处理过一个项目,当你有大约4个响应查询时,像这样的响应事件变成了一场噩梦(另外,视网膜或肖像/风景都有自己的位置)。在维护这样一个项目时,你有很大的困难,你不知道一个变化可能会影响其他变化,而且出于某种原因,你的客户会改变主意。在这样一个场景中,他也想为移动应用肖像平板电脑的造型,我相信你知道这会导致什么。

因此,M2挽救了局面。

在现代网络应用时代;分量ed";,我认为M1不再有帮助,出于某种原因,你会看到很多关于M2的FE教程,原因很简单。它很干净,而且直截了当。忘记在响应上下文之间切换吧,这种方法证明了FE人员调整他的风格是有用的。

方法2与新手/初级玩家

因为它很简单,M2变得很熟悉,直到它的目的出错。

实际上,M1是关于在多个位置/文件中具有样式。每个响应样式都位于自己的文件中,M2是关于组件的样式,其中所有样式都位于一个位置。

想想这个场景,这也成为维护的噩梦:

响应式查询混合不良的方法2

.container {
width: 100%;
.button {
background: red;
@media screen and (min-width: 768px) {
background: green;
}
}
&.red {
background: red;

@media screen and (min-width: 768px) {
background: darken(red, .15);
width: 75%;
}
}

@media screen and (min-width: 768px) {
width: 50%;
}
}

具有良好混合响应查询的方法2


.container {
width: 100%;
.button {
background: red;
}
&.red {
background: red;
}

@media screen and (min-width: 768px) {
width: 50%;
.button {
background: green;
}
&.red {
background: darken(red, .15);
width: 75%;
}
}
}

第一个块是新人在第一次尝试时会尝试的M2,而不会识别最终结果。这个例子只提供了一个单一的媒体查询,想想多个查询。

当然,第二个是有过M2造型经验的人,它很清晰,更容易维护。

就我个人而言,我曾经使用M1,现在在我的作品中完全切换到M2。我的大多数项目样式都是7:3的比例,其中70%M2应用于特定组件,30%M1用于全局/通用样式。我发现这是最好的。更不用说,现在我们也有JCSS或样式组件加入游戏。

如前所述,你的团队领导者可能是一个习惯于在方法1中看到CSS的人,他有自己的观点。这完全取决于您的特定项目范围,哪种方法可能比另一种效果更好。

我为此制作了一个有用的助手mixin。

$break-points: (
mobile:     480px,
tablet:     720px,
desktopS:   960px,
desktop:   1240px,
desktopHD: 1920px
);
/** Helper to build @media query. Use named arguments only! */
@mixin breakpoint-range($mode: screen, $from: false, $to: false, $extra: ()) {
/** Checking arguments consistency */
@each $key in ($from, $to) {
@if $key and not map.has-key($break-points, $key) {
@error "Available values for ($from, $to) args are: #{map.keys($break-points)}";
};
};
/** Accumulator */
$conditions: $mode;
/** Combining breakpoints dependencies */
@each $key, $value in (
min-width: $from,
max-width: $to,
) {
@if $value {
$modifier: if($key == 'max-width', -1px, 0px);
$condition: " and (#{$key}: #{map.get($break-points, $value) - $modifier})";
$conditions: string.insert($conditions, $condition, -1);
}
}
/** Combining rest dependencies */
@each $key, $value in $extra {
$condition: " and (#{$key}: #{$value})"
}

/** Building final media query */
@media #{$conditions} { @content; }
}

用途:

.element {
/** Both bp arguments */
@include breakpoint-range($from: mobile, $to: desktop) {
/* Result: @media screen and (min-width: 480px) and (max-width: 1240px) */
}
/** One bp argument */
@include breakpoint-range($to: desktop) {
/* Result: @media screen and (max-width: 1240px) */
}
/** Just changing view mode */
@include breakpoint-range($mode: print) {
/* Result: @media print */
}
/** Or add anything else */
@include breakpoint-range(
$from: mobile, 
$to: desktop, 
$extra: (orientation: landscape)
) {
/* Result: @media screen 
and (min-width: 480px) 
and (max-width: 1240px)
and (orientation: landscape)
*/
}
}

我喜欢把它用作的混合

@mixin handset-portrait() {
@media screen and (max-width: 599.98px) and (orientation: portrait) {
@content;
}
}
// usage
.responsive {
width: 100vw;
@include handset-landscape() {
width: 50vw;
}
}

断点是@angular/cdk
内容块sass lang 的简略

偏好第一种方法而不是第二种方法有一个原因,只有一个原因。向后兼容性。

https://caniuse.com/mdn-css_at-rules_media_nested-queries

在这一点上,除非你必须回到2015年之前的支持,否则这是不值得的,因为第二种方式确实更容易书写/理解。这就是为什么他们首先在官方规范中提供支持。

然而,用第二种方式写它还有另一个好处。

在您的示例中,请注意第二个方法.container类不必重复。

虽然在这个例子中它可能看起来微不足道,但外推一下。想象一下,两个样式表包含数百甚至数千个类,其中一个只使用方法1,另一个使用方法2。

问题:如果有一种方法使用明显较少的字符来实现相同的结果,那么哪种方法的文件大小较小?因此可能会加快加载时间?这样更好的用户体验?

最新更新