• Sass[SCSS] 기초 이론 5 - 그룹 선언하기, 사용하기, 선택자 속성 사용 (@mixin, @include, @extend)

    2023. 2. 12.

    by. kimyang-Sun

    Sass[Scss]

    Sass[SCSS] 기초 5 - 그룹 선언하기, 사용하기 (@mixin, @include) 를 살펴보도록 하겠습니다.

    scss 를 사용하는 이유중 하나인데 이론은 별로 어렵지 않습니다. 그냥 그룹을 선언하여 만들어주고 그걸 그대로 사용하는 방식입니다.

    쉽게 말해 자바스크립트에서 함수와 비슷한 방식으로 사용됩니다. @mixin 으로 그룹을 만들고 @include 를 통해서 사용하면 됩니다.

    /* mixin 선언 */
    @mixin point {
      position: relative;
      padding-left: 10px;
      &::before {
        content: '';
        display: inline-block;
        position: absolute;
        top: 0;
        left: 0;
        width: 8px;
        height: 8px;
        transform: rotate(45deg);
        background-color: royalblue;
      }
    }
    
    /* mixin 사용 */
    .sub-title {
      @include point;
    }
    .description {
      @include point;
    }

    html
    적용된 css

    이렇게 .sub-title 과 .description 둘 다 point 라는 mixin이 적용된걸 확인할 수 있습니다. (파란색 마름모)

     

    여기서 주의할 점이 있는데 mixin은 항상 순서를 @include보다 위에 선언해주셔야 합니다.

    만약 아래처럼 @include로 사용을 먼저하고 그 아래에 @mixin 으로 그룹을 선언해주면 오류가 나게 됩니다.

    그냥 일반적으로 사용할때 상단에서 @mixin을 선언해주면 된다고 생각하면 편합니다.

    /* mixin 사용 */
    .sub-title {
      @include point;
    }
    .description {
      @include point;
    }
    
    /* mixin 선언 */
    @mixin point {
      position: relative;
      padding-left: 10px;
      &::before {
        content: '';
        display: inline-block;
        position: absolute;
        top: 0;
        left: 0;
        width: 8px;
        height: 8px;
        transform: rotate(45deg);
        background-color: royalblue;
      }
    }

    적용이 되지않는 모습

     

     

    추가로 mixin으로 지정해준 ::before 선택자에 소제목 부분만 색을 붉은색으로 변경하고 싶을 경우에 쉽게 사용할 수 있는 방법도 있습니다.

    우선 그 방법이 아닌 기존 방식으로 해보겠습니다.

    /* mixin 선언 */
    @mixin point {
      position: relative;
      padding-left: 10px;
      &::before {
        content: '';
        display: inline-block;
        position: absolute;
        top: 0;
        left: 0;
        width: 8px;
        height: 8px;
        transform: rotate(45deg);
        background-color: royalblue;
      }
    }
    
    /* mixin 사용 */
    .sub-title {
      @include point;
      &::before {
        background-color: crimson; /* 기존엔 이렇게 &::before을 한번 더 써주고 추가해줘야함 */
      }
    }
    .description {
      @include point;
    }

    적용된 화면

     

    원래는 이런식으로 .sub-title 에만 &::before로 따로 스타일을 추가 해주어야 합니다. 하지만 @content를 사용한다면 바로 스타일 css를 따로 전달하여 추가해줄 수 있습니다.

     

    /* mixin 선언 */
    @mixin point {
      position: relative;
      padding-left: 10px;
      &::before {
        content: '';
        display: inline-block;
        position: absolute;
        top: 0;
        left: 0;
        width: 8px;
        height: 8px;
        transform: rotate(45deg);
        background-color: royalblue;
    
        @content; /* @content 를 ::before 안에 추가해줌 */
      }
    }
    
    /* mixin 사용 */
    .sub-title {
      @include point {
        background-color: crimson; /* 해당 mixin에 괄호를 열어 css 추가 */
      };
    }
    .description {
      @include point;
    }

    똑같이 적용된 화면

    @content 를 ::before 안에 추가해주고 .sub-title에서 @include 사용할 때 괄호를 열어 css룰 추가해줬습니다.

    그러면 이제 변경된 css 값이 @content를 추가해준 위치에 들어가 적용되는걸 확인할 수 있습니다. (::before에 추가됨)


    추가로 유용한 mixin 중에서는 대부분의 분들이 자주 사용하는 말줄임(...) ellipsis를 mixin으로 설정해둔게 있습니다.

    if 문을 통해 인자로 들어온 말줄임이 될 줄 수를 체크하고 해당하는 css값을 넣어주는 mixin 입니다. :)

    @mixin ellipsis($lines: 1) {
      @if ($lines == 1) {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      } @else {
        display: -webkit-box;
        overflow: hidden;
        text-overflow: ellipsis;
        -webkit-line-clamp: $lines;
        -webkit-box-orient: vertical;
      }
    }

     


     

    mixin을 사용해서 scss 파일을 컴파일하면 css에는 그 선언해준 부분들은 컴파일되지 않고 사용하는 부분에만 값들이 들어간 상태로 컴파일됩니다.

    그래서 보통 mixin이나 변수 variable 등을 사용할때 따로 파일로 분기해서 작성해둔 후 import로 상단에 불러오는 경우가 많아요.

    @import "variables";
    @import "mixins";
    
    /* mixin 사용 */
    .sub-title {
      @include point;
    }
    .description {
      @include point;
    }

     


     

    더 나아가 mixin을 사용할때 매개변수(parameter), 인자(arguments)를 사용할 수 있는데 이것도 사용방법은 쉽습니다.

    /* mixin 선언 */
    @mixin border-style($width, $style, $color) {
      border: $width $style $color;
    }
    
    /* mixin 사용 */
    .sub-title {
      @include border-style(1px, dashed, royalblue);
    }
    .description {
      @include border-style(1px, solid, crimson);
    }

    적용된 화면

     

    여기서 mixin에 미리 기본값 매개변수(Default Parameter) 를 설정해 놓을 수도 있습니다.

    /* mixin 선언 */
    @mixin border-style($width: 1px, $style: solid, $color: crimson) {
      border: $width $style $color;
    }
     
    /* mixin 사용 */
    .sub-title {
      @include border-style(1px, dashed, royalblue);
    }
    .description {
      @include border-style;
    }

    적용된 화면

    위에 예시와 출력되는 화면은 똑같지만 이번꺼는 mixin에서 미리 값들을 지정해주고,

    .description 선택자에 인자를 넣지 않고 생략하여 그냥 mixin 이름만 사용해준걸 볼 수 있습니다. 이러면 알아서 기본값으로 적용됩니다. :)

     


     

    mixin 과 비슷한 기능으로 선택자 속성 자체를 불러오는 @extend가 있습니다.

    mixin처럼 미리 선언하고 그걸 사용하는 방식이 아닌 하나의 클래스에 적용된 css 속성 전체를 가져와서 적용할 수 있습니다.

    .sub-title {
      position: relative;
      padding-left: 10px;
      &::before {
        content: '';
        display: inline-block;
        position: absolute;
        top: 0;
        left: 0;
        width: 8px;
        height: 8px;
        transform: rotate(45deg);
        background-color: royalblue;
      }
    }
    
    .description {
      @extend .sub-title;
    }

    적용된 화면

     

    mixin과의 차이를 살펴보자면 extend는 css로 컴파일될때 다중 선택자로 지정되어 컴파일됩니다.

    mixin은 mixin 자체는 컴파일되지 않고 그 값들만 mixin이 사용된 해당 선택자에 적용되어 컴파일되었는데 extend는 아래처럼 컴파일 됩니다.

    @charset "UTF-8";
    .sub-title, .description {
      position: relative;
      padding-left: 10px;
    }
    .sub-title::before, .description::before {
      content: "";
      display: inline-block;
      position: absolute;
      top: 0;
      left: 0;
      width: 8px;
      height: 8px;
      transform: rotate(45deg);
      background-color: royalblue;
    }

     

    이렇게 컴파일을 적용하고 싶지 않은경우 사용하는 방식도 있는데 바로 플레이스 홀더 선택자 % 입니다.

    크게 다른건 없고 % 퍼센트 특수문자를 sub-title 앞에 붙혀서 선언하고 아래에서 똑같이 %를 이용해서 사용합니다.

    %sub-title {
      position: relative;
      padding-left: 10px;
      &::before {
        content: '';
        display: inline-block;
        position: absolute;
        top: 0;
        left: 0;
        width: 8px;
        height: 8px;
        transform: rotate(45deg);
        background-color: royalblue;
      }
    }
    
    /* extend 사용 */
    .description {
      @extend %sub-title;
    }

    적용된 화면

    여기서 또 특이점은 .sub-title 클래스에는 적용되던게 당연히 풀립니다. 왜냐하면 %를 사용해서 아래처럼 컴파일되었기 때문입니다.

    @charset "UTF-8";
    .description {
      position: relative;
      padding-left: 10px;
    }
    .description::before {
      content: "";
      display: inline-block;
      position: absolute;
      top: 0;
      left: 0;
      width: 8px;
      height: 8px;
      transform: rotate(45deg);
      background-color: royalblue;
    }

     

     

     

    댓글