使用 SCSS 以编程方式创建可见性 类
Programmatically created visibility classes with SCSS
我想根据已定义的对象创建一组 类,并使用成对的 keys 和 values。这些 类 的应用并不重要,但为了这个问题,假设我想将 display
值分配给某些视口上的 block
和 none
另一个。
在代码中,所需的输出将是这样的:
.visible-sm {
display: none;
@media screen and (max-width: 576px) and (min-width: 320px) {
display: block !important;
}
}
.visible-md {
display: none;
@media screen and (max-width: 768px) and (min-width: 576px) {
display: block !important;
}
}
.visible-lg {
display: none;
@media screen and (max-width: 992px) and (min-width: 768px) {
display: block !important;
}
}
我遇到的问题是第二个媒体查询条件(因此元素显示 BETWEEN 一些尺寸,而不是 UP TO或 向下 特定尺寸)。
到目前为止我尝试了什么?
用预定义的断点声明了对象:
$viewport-breakpoints: (
xs: 320px,
sm: 576px,
md: 768px,
lg: 992px
);
并遍历对象,创建适当的 类,同时尝试应用简单的算术
@each $breakpoint in $viewport-breakpoints {
$breakpoint-down: #{nth($breakpoint - 1)};
.visible-#{nth($breakpoint, 1)} {
display: none;
@media screen and (max-width: #{nth($breakpoint, 2)}) and (min-width: #{nth($breakpoint-down, 2)}) {
display: block !important;
}
}
}
我希望 $breakpoint-down
变量会降低迭代的索引(所以如果我们在 md
,会去 sm
,等等),但是不幸的是它不会工作(甚至无法编译)。
如果我删除第二个媒体查询条件,它会创建 类 让元素对某些断点可见,但是就像我上面提到的,我希望它们仅在某些值之间应用样式。
我错过了什么?
我们暂时不用担心第一对和最后一对对象的边缘情况。 ;)
我在这里看到过类似的话题,人们在其中解释了如何使用 SCSS 进行循环,但他们只处理列表,从不处理具有成对键和值的对象。
你已经完成了 90%。您的问题是 $breakpoint - 1
无效,因为 $breakpoint
不是数字:在这种情况下,$breakpoint
是键值对,例如 xs 320px
。幸运的是,我们可以使用 nth()
:
访问该键值对的每个部分
$map: (
xs: 320px,
sm: 576px,
md: 768px,
lg: 992px
);
@each $key, $val in $map {
$index: index($map, $key $val);
$previous-keyvalue-pair: nth($map, $index - 1);
$previous-key: nth($previous-keyvalue-pair, 1); // Not required for this question
$previous-val: nth($previous-keyvalue-pair, 2); // This is the one you need
.visible-#{$key} {
display: none;
@if ($index > 1) { // To prevent accessing nth($map, 0) which would be invalid
@media screen and (max-width: $val) and (min-width: $previous-val)) {
display: block !important;
}
}
}
}
$previous-val
的另一种写法是 nth(nth($map, $index - 1), 2)
。 Here's a working example in SassMeister.
我想根据已定义的对象创建一组 类,并使用成对的 keys 和 values。这些 类 的应用并不重要,但为了这个问题,假设我想将 display
值分配给某些视口上的 block
和 none
另一个。
在代码中,所需的输出将是这样的:
.visible-sm {
display: none;
@media screen and (max-width: 576px) and (min-width: 320px) {
display: block !important;
}
}
.visible-md {
display: none;
@media screen and (max-width: 768px) and (min-width: 576px) {
display: block !important;
}
}
.visible-lg {
display: none;
@media screen and (max-width: 992px) and (min-width: 768px) {
display: block !important;
}
}
我遇到的问题是第二个媒体查询条件(因此元素显示 BETWEEN 一些尺寸,而不是 UP TO或 向下 特定尺寸)。
到目前为止我尝试了什么?
用预定义的断点声明了对象:
$viewport-breakpoints: (
xs: 320px,
sm: 576px,
md: 768px,
lg: 992px
);
并遍历对象,创建适当的 类,同时尝试应用简单的算术
@each $breakpoint in $viewport-breakpoints {
$breakpoint-down: #{nth($breakpoint - 1)};
.visible-#{nth($breakpoint, 1)} {
display: none;
@media screen and (max-width: #{nth($breakpoint, 2)}) and (min-width: #{nth($breakpoint-down, 2)}) {
display: block !important;
}
}
}
我希望 $breakpoint-down
变量会降低迭代的索引(所以如果我们在 md
,会去 sm
,等等),但是不幸的是它不会工作(甚至无法编译)。
如果我删除第二个媒体查询条件,它会创建 类 让元素对某些断点可见,但是就像我上面提到的,我希望它们仅在某些值之间应用样式。
我错过了什么?
我们暂时不用担心第一对和最后一对对象的边缘情况。 ;)
我在这里看到过类似的话题,人们在其中解释了如何使用 SCSS 进行循环,但他们只处理列表,从不处理具有成对键和值的对象。
你已经完成了 90%。您的问题是 $breakpoint - 1
无效,因为 $breakpoint
不是数字:在这种情况下,$breakpoint
是键值对,例如 xs 320px
。幸运的是,我们可以使用 nth()
:
$map: (
xs: 320px,
sm: 576px,
md: 768px,
lg: 992px
);
@each $key, $val in $map {
$index: index($map, $key $val);
$previous-keyvalue-pair: nth($map, $index - 1);
$previous-key: nth($previous-keyvalue-pair, 1); // Not required for this question
$previous-val: nth($previous-keyvalue-pair, 2); // This is the one you need
.visible-#{$key} {
display: none;
@if ($index > 1) { // To prevent accessing nth($map, 0) which would be invalid
@media screen and (max-width: $val) and (min-width: $previous-val)) {
display: block !important;
}
}
}
}
$previous-val
的另一种写法是 nth(nth($map, $index - 1), 2)
。 Here's a working example in SassMeister.