이번 포스트에서는
SCSS(SASS)
의 또 다른 강력한 문법인@Mixin
과@include
(보통 둘이 합쳐Mixins
이라고 부르는 사람들도 있습니다.)에 대해서 알아보도록 하겠습니다.
Mixins
은 스타일시트에서 재사용이 가능한 스타일을 정의할 수 있도록 하는 문법이라고 공식문서에서 소개하고 있습니다. 그러면 Mixin
이 어떻게 이루어지는지에 대해서 알아보도록 하겠습니다.
@mixin
은 재사용이 가능한 스타일을 정의하는데 사용되는 선언입니다. 스타일 정의 앞에 @mixin
이 붙게 되면 해당 스타일 시트 내부에서 얼마든지 재사용이 가능합니다.
@mixin reusable-style {
color: red;
margin: 0;
}
mixin 내부에서 &
나 또 다른 셀렉터를 포함할 수도 있습니다.
@include
는 mixin을 사용하기 위해 선언하는 구문입니다. 셀렉터를 지정하고 그 내부에 @include
를 통해 mixin을 불러오면 됩니다.
div {
@include resuable-style;
}
컴파일 결과
div { color: red; margin: 0; }
@mixin
은 마치 함수처럼 인수(Arguments)를 가질 수 있습니다. 인수의 선언과 사용도 마치 함수처럼 사용할 수 있습니다.
@mixin mixin-with-args($props, $num) {
#{$props}: $num;
}
.box1 {
@include mixin-with-args(width, 100px);
}
컴파일 결과
.box { width: 100px; }
mixin의 인수에도 기본값을 할당할 수 있습니다. 기본값은 인수가 전달되지 않았을 경우 사용됩니다.
인수는 콜론:
을 사용하여 $매개변수:값
의 형태로 표기합니다.
@mixin default-args ($props: width, $num: 100px) {
#{$props}: $num;
}
인수에 기본값을 할당하면, 인수는 optional하게 만들 수 있습니다.
@mixin img-position($img, $x: 10%, $y: 10%) {
background: {
image: $img;
position: $x, $y;
}
}
.img {
@include img-position(url("./a.img"), 20%);
}
컴파일 결과
.img { background-image: url("./a.img"); background-position: 20% 10%; }
mixin의 세번째 인수인
$y
가 optional 해졌습니다. 그 결과로 background-position의 y축이 10%로 자동삽입 되었습니다.
키워드 인수는 인수를 명시적으로 전달할 수 있는 인수입니다. 문법은 기본값 작성하듯이 하는데, 인수를 전달할 때 사용한다는 차이점을 기억해주세요. 처음 접근하면 자칫 헷갈릴 수 있습니다.
키워드 인수의 장점은 기존 인수는 선언 순서대로 지정했던 것에 비해서 인수를 전달하는 순서에 구애받지 않는다라는 장점이 있습니다.
@mixin box-style($width: 100px, $height: 50px, $color: red) {
width: $width;
height: $heigth;
background-color: $color;
}
/* mixin을 include하는 부분을 주목해주세요! */
.box {
@include box-style($color: blue, $height: 100px);
}
컴파일 결과
.box { width: 100px; height: 100px; background-color: blue; }
키워드 인수는 인수의 이름으로 인수를 전달하기 때문에 mixin 인수의 이름을 변경할 때는 반드시 주의하여야합니다.
인수의 갯수가 고정되어있지 않은 경우도 있습니다. 이럴땐 인수 뒤에 ...
을 붙임으로써 인수를 가변 인수로 만들어서 사용합니다.
@mixin margin-size($size...) {
margin: $size;
}
.box1 {
@include margin-size(0px, 0px, 0px, 0px);
}
.box2 {
@include margin-size(0px, 0px, 0px);
}
.box3 {
@include margin-size(0px, 0px);
}
.box4 {
@include margin-size(0px);
}
컴파일 결과
.box1 { margin: 0 0 0 0; } .box2 { margin: 0 0 0; } .box3 { margin: 0 0; } .box4 { margin: 0; }
mixin에 @content
를 선언하면 해당 구역에 새로운 스타일 블록을 넣을 수 있게 됩니다. 말로만 하면 뭔소린가 싶겠지만, 예제를 보면 이 역시도 간단하다는 것을 알 수 있습니다.
@mixin box-style() {
width: 50px;
height: 50px;
@content;
}
/* @content 기능을 이용하지 않은 box1 */
.box1 {
@include box-style();
}
/* @content 기능을 이용한 box2 */
.box2 {
@include box-style() {
background-color: black;
};
}
컴파일 결과
/* @content 기능을 이용하지 않은 box1 */ .box1 { width: 50px; height: 50px; } /* @content 기능을 이용한 box2 */ .box2 { width: 50px; height: 50px; background-color: black; }
@content
블록에 전달된 스타일 블록은 mixin에 포함된 것 처럼 보이지만 @include
된 스타일 블록의 스코프(Global)을 따라갑니다.
$color: black;
@mixin box-style($color) {
color: $color;
@content;
}
div {
@include box-style(blue) {
color: $color;
};
}
컴파일 결과
div { color: blue; /* content 내부의 $color 변수는 전역 변수값을 따라서 black으로 컴파일되었습니다. 즉, @content 내의 변수는 mixin이 아닌, div에서 스코프를 가진다는 것을 의미합니다. */ color: black; }