[SCSS] SCSS 문법5 - @mixin & @include

Bam·2022년 5월 6일
1

CSS

목록 보기
26/35
post-thumbnail

Mixins?

이번 포스트에서는 SCSS(SASS)의 또 다른 강력한 문법인 @Mixin@include(보통 둘이 합쳐 Mixins이라고 부르는 사람들도 있습니다.)에 대해서 알아보도록 하겠습니다.

Mixins은 스타일시트에서 재사용이 가능한 스타일을 정의할 수 있도록 하는 문법이라고 공식문서에서 소개하고 있습니다. 그러면 Mixin이 어떻게 이루어지는지에 대해서 알아보도록 하겠습니다.


@mixin

@mixin재사용이 가능한 스타일을 정의하는데 사용되는 선언입니다. 스타일 정의 앞에 @mixin이 붙게 되면 해당 스타일 시트 내부에서 얼마든지 재사용이 가능합니다.

@mixin reusable-style {
  color: red;
  margin: 0;
}

mixin 내부에서 &나 또 다른 셀렉터를 포함할 수도 있습니다.


@include

@include는 mixin을 사용하기 위해 선언하는 구문입니다. 셀렉터를 지정하고 그 내부에 @include를 통해 mixin을 불러오면 됩니다.

div {
  @include resuable-style;
}

컴파일 결과

div {
  color: red;
  margin: 0;
}

@mixin의 인수

@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;
}

Content Blocks

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;
}

0개의 댓글