最近,我在Angular构建的项目中遇到了媒体查询的问题。我不记得是什么限制使我编写了mixin来简化工作,但是我真的想分享结果并获得反馈。我遇到了许多其他类似的示例,但是对于工作而言,使用此示例更加清晰,便捷。
通常,为方便起见,我为自己提出了以下要求:
- 屏幕尺寸必须分别渲染,以便您可以在一处全局更改行为(例如,代替“ 320px”,只需传输“ xs”)。
- 与媒体查询的这种混合可以在多个方向上进行(例如,并非总是仅最大宽度)。
- Mixin可以单独使用,覆盖内部的描述类,或在父级主体中描述,覆盖其属性。
因此,让我们定义所需的任何权限。例如:
$sizes: ("xs":320px, "sm":576px, "md":768px, "lg":992px, "xl":1200px);
首先,让我们编写一个mixin来接受所需的范围前缀和分辨率,但受限于此:
@mixin media($minmax, $media) {
@each $size, $resolution in $sizes {
@if $media == $size {
@media only screen and (#{$minmax}-width: $resolution) {
@content;
}
}
}
}
简而言之,我们传递所需的屏幕分辨率的名称,在$ Size变量中先前声明的值中查找它的值。找到它之后,我们将其与传递的min或max($ minmax变量)一起替换。
使用示例,包括在另一个mixin中:
@mixin blocks-width {
width: 400px;
@include media("max", "md") {
width: 100%;
}
}
从这个简单的示例中,我们将获得一个混合块,它将<768px处的块宽度从400px更改为100%。以下示例应给出相同的结果。
在类中使用的示例:
.blocks-width {
width: 400px;
@include media("max", "md") {
width: 100%;
}
}
用作独立媒体查询的示例:
.blocks-width {
width: 400px;
}
@include media("max", "md") {
.blocks-width {
width: 100%;
}
}
但是,如果您需要一个媒体查询,包括一个范围很广的媒体查询(指定一个可以在其中进行媒体查询的分辨率)怎么办?让我们扩展一下混合。
就我个人而言,方便地将分辨率描述如下:-如果需要md范围,那么我们将屏幕尺寸定在sm和md之间。如果要重写混合,以便仅通过一种分辨率,则必须从列表中查找前一个值。由于我找不到快速执行此操作的任何方法,因此我不得不编写一个函数:
@function getPreviousSize($currentSize) {
$keys: map-keys($sizes);
$index: index($keys, $currentSize)-1;
$value: map-values($sizes);
@return nth($value, $index);
}
要检查其工作原理,请使用 调试:
@debug getPreviousSize('md');
接下来,我们稍微重做的代码:
@mixin media($minmax, $media) {
@each $size, $resolution in $sizes {
@if $media == $size {
@if ($minmax != "within") {
@media only screen and (#{$minmax}-width: $resolution) {
@content;
}
} @else {
@if (index(map-keys($sizes), $media) > 1) {
@media only screen and (min-width: getPreviousSize($media)+1) and (max-width: $resolution) {
@content;
}
} @else {
@media only screen and (max-width: $resolution) {
@content;
}
}
}
}
}
}
逻辑与以前的功能相同。但是,如果只想在范围内(例如md)应用媒体查询,则在调用mixin时编写以下内容:
@include media("within", "md") {
.blocks-width {
width: 100%;
}
}
之后,我们将看到以下已编译的CSS:
@media only screen and (max-width: 768px) and (min-width: 577px)
.blocks-width {
width: 100%;
}
而且,如果我们指定最小的屏幕尺寸(xs),例如:
@include media("within", "xs") {
.blocks-width {
width: 100%;
}
}
然后我们得到一个从0到对应的最小分辨率的范围:
@media only screen and (max-width: 320px)
.blocks-widthh {
width: 100%;
}
当然,您可以从另一个方向重写这些媒体查询,但就我个人而言,我习惯于从大到小的布局。
感谢您的关注!
UPD:mixin已稍作校正,因此有限范围内的分辨率不会重叠:)谢谢您的关注E_STRICT