关于CSS:使用SCSS以编程方式创建的可见性类

 2021-04-27 

Programmatically created visibility classes with SCSS

我想基于已定义的对象(具有成对的键和值)创建一组类。这些类的应用并不重要,但出于这个问题,让我们说我想在某些视口上将display值分配给block,在另一个视口上分配none。 >

在代码中,所需的输出将如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.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;
  }
}

我遇到的问题是第二个媒体查询条件(因此该元素显示在某些尺寸之间,而不是某些尺寸的UP TO或DOWN TO之间)。

到目前为止我尝试了什么?

用预定义的断点声明对象:

1
2
3
4
5
6
$viewport-breakpoints: (
  xs: 320px,
  sm: 576px,
  md: 768px,
  lg: 992px
);

并遍历对象,创建适当的类,同时尝试应用简单的算术

1
2
3
4
5
6
7
8
9
@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()

访问该键值对的每个部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$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)。这是SassMeister中的一个工作示例。