재사용의 출발점은 아마도 변수의 활용일 것이다. CSS에서는 동일하게 사용되어야 하는 값이 있을 때 변수를 적용할 수가 없었다. 따라서 변경이 필요할 때 모든 값을 일일이 변경해줘야 하는 번거로움이 있었다.
이번 포스트에서는 SCSS에서의 변수 활용에 대해서 살펴보자.
변수의 사용
$를 이용한 변수의 선언 및 사용
SCSS에서 변수의 선언은 $ 기호를 사용한다. 변수를 선언할 때는 위치에 따라 stylesheet의 root에 선언하는 전역 변수와 style 블록 내부에서 사용되는 지역 변수로 나뉠 수 있다.
// 전역 변수
$base-color: blue;
.variable {
// 지역 변수
$sub-color: rgba($base-color, 0.5);
@warn $base-color $sub-color;
color: $base-color;
background-color: $sub-color;
}
.variable {
color: blue;
background-color: rgba(0, 0, 255, 0.5);
}
Scss 코드에서 각각 전역 레벨과 지역 레벨에서 변수를 선언하고 활용하는 모습을 볼 수 있다. 이제 blue를 설정하기 위해서는 그냥 $base-color를 참조하면 된다.
scss 중간에 있는 @warn은 중간에 로그를 확인해보기 위한 장치이다. 위 scss를 컴파일해보면 아래와 같은 메시지를 확인할 수 있다.
Warning: blue rgba(0, 0, 255, 0.5)
01_declare.scss 5:5 root stylesheet
약간 재미있는 점이 있는데 SCSS에서는 변수명에서 '-'와 '_'를 동일하게 취급한다. 따라서 $base_color와 $base-color는 동일한 녀석이다. (초기 SASS에서는 _만 가능했는데 최근에 -가 가능해졌다고 한다. 개인적인 생각으로는 처음에는 프로그래머의 관점으로 접근해서 snake case를 사용했고 아마 버전업이 되면서 HTML의 kebab case를 도입하지 않았을까 생각해본다.
변수의 유효범위와 재정의
전역 레벨에서 선언한 변수는 문서 전체에서 사용할 수 있고 지역 레벨에서 선언한 변수는 해당 {} 내에서만 사용할 수 있다. 지역 레벨에서 전역 레벨의 변수와 동일한 이름의 변수를 선언해서 값을 변경하면 전역 변수와는 별도의 유효범위를 가지기 때문에 별도의 지역 변수가 생성된다. 이를 shadowing 이라고 한다.
그럼 지역에서는 전역 값을 변경할 수 없는 것인가? 만약 지역에서 전역 변수의 값을 변경하려면 !global 키워드를 사용하면 된다.
$my-var: global1;
$your-var: global2;
@warn "global 1: "$my-var $your-var; // "global 1: " global1 global2
.scope {
@warn "local 1: "$my-var $your-var; // "local 1: " global1 global2
$my-var: local1; // shadowing
$your-var: local2 !global; // global 변경
@warn "local 2: "$my-var $your-var; // "local 2: " local1 local2
}
@warn "global 2: "$my-var $your-var; // "global 2: " global1 local2
참고로 SCSS에서는 제어문의 사용이 가능한데 제어문에서는 shadowing이 발생하지 않기 때문에 !global 없이 전역 변수의 수정이 가능하다.
$dark-theme: true;
$primary-color: blue;
$accent-color: purple;
/* "초기 설정: primary-color: " blue ", accent-color " purple*/
@warn "초기 설정: primary-color: "$primary-color ", accent-color "$accent-color;
@if $dark-theme {
// 로컬 영역이지만 제어문에서는 전역 변수 수정 가능
$primary-color: darken($primary-color, 60%);
$accent-color: lighten($accent-color, 60%);
}
/* "dark-theme? " true "primary-color: " black ", accent-color " #ffb3ff */
@warn "dark-theme? "$dark-theme "primary-color: "$primary-color ", accent-color "$accent-color;
사용된 변수의 확인
프로그래밍 과정에서 의도치 않게 변수를 중복해서 사용하면 오류가 발생하지 않고 shadowing 되기 때문에 힘들때가 있다. 이때는 sass에서 제공해주는 variable-exists 와 같은 함수를 이용해볼 수 있다.
- meta.variable-exists(variable_name)
- meta.global-variable-exists(variable_name)
@use "sass:meta" as meta;
@warn "data-theme 변수 유무: " meta.global-variable-exists('dark-theme')
참고로 @use는 문서의 맨 처음에 등장해야 한다.
기타
default 값 활용 : !default
!default는 느낌 상 기본값을 선언하는 것 같지만 그건 아니고 기존에 설정된 값이 있다면 그것을 사용하겠다라는 선언이다. 예를 들어 외부 라이브러리를 가져와서 사용중인데 그 라이브러리에서 color라는 이름의 변수를 사용하고 있다고하자. 만약 이 값을 바꿔버리면 전체적으로 스타일에 문제가 발생할 것이다. 이런 경우 해당 변수가 이미 선언되어있다면 그 값을 default로 쓰고 그렇지 않은 경우 지정한 스타일을 적용시킬 수 있다.
$base-color: green;
.default {
$base-color: red !default; // 기존에 설정된 값이 있으면 사용
color: $base-color;
$sub-color: blue !default; // 재정의
border: 1px solid $sub-color;
@warn $base-color $sub-color; /* green blue */
}
위 코드의 경우 base-color가 green으로 선언된 상태이다. 즉 base-color는 기본 값이 green이다.
이제 .default의 스타일 영역에서 base-color에 red를 설정하면서 !default가 있기 때문에 red가 아닌 green이 설정된다. sub-color는 기존에 설정된 값이 없기 때문에 blue가 설정된다.
내장 변수
변수 중에는 SCSS의 내장 모듈에 선언된 것 들도 있다. 이것들은 상수처럼 재정의 할 수는 없다.
@use "sass:math" as math;
@warn "math.$pi값: " math.$pi ", math.$e 값: " math.$e;
/*"math.$pi값: " 3.1415926536 ", math.$e 값: " 2.7182818285*/