태그 보관물: Sass

Sass에서 다크모드 적용하기

점점 다크모드를 적용하는 사이트들이 늘어나고 있는데, Sass를 사용하여 다크모드를 쉽게 적용할 수 있게 코드를 만들어 봤습니다.

우선 일반 컬러 테마와 다크모드 테마를 $light-theme와 $dark-theme 맵에 각각 선언합니다. (4-13줄)
그리고 위의 맵을 사용해서 CSS에서 var()를 사용하기 위한 변수를 선언하고, 미디어쿼리도 적용해 줍니다. (15-25줄)
그러면 CSS의 1-13줄과 같이 변수가 생성됩니다.

이제 본격적으로 믹스인을 생성합니다. (28-41줄)
기본적으로 color-theme(key: value)의 형태로 한 개 이상의 키:밸류 쌍으로 된 속성을 전달할 수 있습니다. 그러나 border나 background 등과 같이 색상 이외에 다른 속성도 같이 설정할 필요가 있는 경우에 color, prefix, suffix의 속성을 가진 맵을 사용할 수 있습니다.

43-53줄과 같이 믹스인을 사용하면 CSS의 14-29줄에 해당하는 코드를 생성합니다.
같은 속성이 두 개씩 만들어 지는 것은 CSS의 변수나 미디어쿼리를 지원하지 않는 구형 브라우저에서는 첫 번째 속성의 컬러를 사용하고, 지원하는 브라우저는 변수와 미디어쿼리가 적용되도록 하기 위해서 입니다.
IE와 같은 구형 브라우저를 지원할 필요가 없다면 31, 37줄의 코드는 삭제하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@use "sass:map";
@use "sass:meta";
 
$light-theme: (
    bgc: #fff,
    txt: #333,
    brd: #ff6
);
$dark-theme: (
    bgc: #333,
    txt: #eee,
    brd: #339
);
 
:root{
    @each $k, $v in $light-theme{
        #{"--" + $k}: #{$v};
    }
}
@media (prefers-color-scheme: dark){
    :root{
        @each $k, $v in $dark-theme{
            #{"--" + $k}: #{$v};
        }
    }
}
 
@mixin color-theme($args...){
    @each $k, $v in meta.keywords($args){
        @if(meta.type-of($v) == "string"){
            #{$k}: map.get($light-theme, $v);
            #{$k}: #{"var(--" + $v + ")"};
        }@else if(meta.type-of($v) == "map"){
            $c: map.get($v, color);
            $p: map.get($v, prefix);
            $s: map.get($v, suffix);
            #{$k}: $p map.get($light-theme, $c) $s;
            #{$k}: $p #{"var(--" + $c + ")"} $s;
        }
    }
}
 
html, body{
	@include color-theme($color: txt, $background-color: bgc);
}
 
.border{
	@include color-theme($border: (prefix: 1px solid, color: brd));
}
 
.background{
    @include color-theme($background: (color: bgc, suffix: url(bg.jpg) no-repeat 50% 50%));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
:root {
  --bgc:#fff;
  --txt:#333;
  --brd:#ff6;
}
 
@media (prefers-color-scheme: dark) {
  :root {
    --bgc:#333;
    --txt:#eee;
    --brd:#339;
  }
}
html, body {
  color: #333;
  color: var(--txt);
  background-color: #fff;
  background-color: var(--bgc);
}
 
.border {
  border: 1px solid #ff6;
  border: 1px solid var(--brd);
}
 
.background {
  background: #fff url(bg.jpg) no-repeat 50% 50%;
  background: var(--bgc) url(bg.jpg) no-repeat 50% 50%;
}