그럼에도 불구하고

👨‍💻

[Sass] mixin, extend, 모듈화(import/use) 본문

HTML, CSS/CSS Preprocessors

[Sass] mixin, extend, 모듈화(import/use)

zenghyun 2023. 1. 10. 01:15

 

mixin, extend, 모듈화(import/use)에 대해 알아보자

 

 

 

[ @ 문법 ]

Sass는 작업을 편하게 해 줄 @으로 시작하는 At-Rules라는 문법이 있다.

 

기본 CSS에서도 @으로 시작하는 문법들이 몇 개 있다. (@font-face 또는 @counter-style, @media 등)

Sass에서는 여기에 더해 추가적인 기능들을 제공하는 at-rules 들이 추가된다.

 

예를 들면

  • @mixin / @include : 스타일 청크(묶음)를 쉽게 재사용할 수 있다.
  • @extend : 여러 선택자가 스타일을 상속받도록 할 수 있다.
  • @import / @use : 다른 스타일시트에 있는 변수, 함수, 믹스인 등을 불러와 결합해서 쓸 수 있다.
  • @function : SassScript에서 사용할 수 있는 사용자 정의 함수를 만들 수 있다.
  • @if / @each / @for : 상황에 맞춰 CSS가 적용되도록 흐름을 제어할 수 있다.

 

 


 

 

[★ mixin ]

믹스인을 사용하면 내가 필요할 때마다 사용할 수 있는 스타일을 정의할 수 있다.

 

이렇게 반복되는 속성을 하나하나 타이핑 할 필요가 없어진다. 

또한, 수정할 때도 믹스인을 변경하면 알아서 바뀌기 때문에 유지보수 하기에도 좋다. 

 

믹스인에 인자(Arguments)를 줄수도 있다.

 

즉, 호출될 때마다 다르게 정의할수 있다.  속성은 동일하게 지정하지만 값을 다르게 주고 싶다면 아래처럼 인자를 달리 설정하면 된다.

 

 

모든 인자를 다 넘겨받는 대신, 일부 인자에는 기본값을 주거나 특정 인자만 따로 넘기는 것도 가능하다.

 

이렇게 반복되는 부분을 줄이고 인자만으로 배경 이미지를 쉽게 넣을 수 있다. 

이때 인자는 차례대로 넣어야 하기 때문에 특정 인지만 넣는 경우 $format:"jpg"와 같이 정확히 작성해야한다.

 기본값이 없는 인자는 필수값으로 취급되므로, @include bg(); 처럼 사용하면 에러가 발생한다.

 


 

[ mixin에 내용 덧붙이기 ]

@content 구문을 쓰면 @include로 불러와 쓸 때 내용을 추가로 입력할 수 있다.

 

// 1) 믹스인을 만들고
@mixin hover {
    &:hover {
        font-weight: bold;
        @content;
    }
    &.on {
        @content;
    }
}
 
button {
   // 2) 불러와 쓸 때 내용을 입력한다.
    @include hover {
        color: red;
    }
}
 
/*
 * 출력결과:
 
 button:hover {
   font-weight: bold;
   color: red;
 }
 
 button.on {
   color: red;
 }
*/

 

 


 

[ @extend ]

말그대로 '확장'을 의미하며, 기본 내용에서 뭔가를 덧붙일 때 사용한다.

사용법은 이미 존재하는 셀렉터를 @extend로 지정해주면 된다.

 

extend 해줄 파일을 만들고, 

 

 

import후 extend 해주면 된다.

 


 

@mixin vs. @extend

그럼 이쯤 들어 생기는 의문, 믹스인과 익스텐드는 꽤 비슷하게 생겼는데 뭐가 다른 걸까?

둘 다 스타일을 캡슐화하고 재사용하기에 좋은 방식이지만 약간의 차이가 있다.

 

@mixin
- 인자를 넣을 수 있다.
- 선택자 관리가 쉬워서 전역으로 쓰기 편하다.
- 컴파일된 CSS가 길어진다.

 

@extend
- 연관성 있는 셀렉터들을 묶어 관리할 수 있다.
- 미디어쿼리 등으로 셀렉터가 묶일 수 없다면 쓸 수 없다.

 

 

 

앞서 컴파일된 CSS를 보면 알 수 있듯이

  • @mixin: 미리 정의한 속성을 복사해서 따로 적용
  • @extend: 선택자를 함께 묶어 속성을 한번에 적용

한다는 차이점이 있고, 여기서의 핵심은 "얼마나 연관성이 있는가"이다.

 

선택자끼리 의미론적 관계가 있다면 @extend를, 그렇지 않고 단순히 속성만 겹치는 관계라면 @mixin을 쓰는 것을 추천한다. 

 

 

 


 

 

[ 모듈화 ]

스타일 시트를 쪼개놓은 것을 '모듈'이라고 한다. 

일반적으로 CSS는 보통 하나의 파일을 쓰지만, 그렇다고 해서 작업할 때도 한 곳에 몰아 쓸 필요는 없다. 

 

예를 들어 헤더 / 메인 / 푸터 각 영역의 스타일을 분리해서 작성한다면 더 효율적으로 스타일시트를 관리할 수 있다.

 

특히 헤더랑 푸터는 공통 영역이므로 어디서든 불러와 쓸 수 있으면 유지보수가 편해집니다.

 

 

[ @import ]

내가 사용할 CSS를 @import로 불러오면 된다. 

 

@import "common.css";
@import "header.css";

Sass가 아닌 일반 CSS에서도 스타일시트 내 다른 스타일시트를 임포트 할 수 있다.

 

하지만 위와 같이 CSS를 불러오는 건 별로 권장하지 않는다. 이유는 브라우저가 각각의 CSS를 직렬로 불러오기 때문이다. 

 

한편, Sass에서 @import를 통해 다른 스타일시트를 불러오는 것은 조금 다르다.

Sass의 임포트는 "컴파일 과정에서 처리되기 때문에" 브라우저가 HTTP 요청을 여러 번 하지 않아도 되기 때문이다.

 

다음 예시를 보자

 

_common.scss 파일을 만든다. 

 

style.scss 파일을 만들고 common을 import 한다.

 

그 후 컴파일하면 위와 같이 _common.scss와 style.scss의 내용이 모두 들어가 있는 style.css 파일 하나만 생성된다.

 

즉, 공통 스타일의 경우 _common.scss에다 몰아놓고, 필요할 때마다 다른 scss 파일에서 가져와 쓸 수 있다.

또한 @import를 통해 변수, 믹스인도 가져올 수 있다. 이들만 따로 모아서 _variable.scss, _mixin.scss 등으로 분리하는 것도 좋다.

 

언더바_는 무시한다 (__);

여기서 알 수 있는 점은 이름 앞에 언더바(_)가 붙은 scss는 컴파일되지 않는다는 것이다. 

언더바 없이 작성한 스타일시트는 모두 독립적으로 컴파일된다.

 

 

또한, 위의 예시처럼 스타일시트를 불러올 때 언더바나 확장자 없이 @import "commom"; 만으로 가져올 수 있다. 

그리고 임포트 할 때는 현재 파일을 기준으로 찾는다.

 

 


 

[ @use ]

 

@import는 쉽고 빠르게 다른 스타일시트를 가져올 수 있도록 해주지만,
Dart Sass를 쓰고 있다면 @import 대신 @use를 사용하는 것이 좋다.

 

이유는 @import는 대상을 전역으로 불러오기 때문이다.

변수, 믹스인, 함수 등(Sass에서는 이걸 '멤버'라고 부른다.)에 전역으로 접근할 수 있기 때문에, 각 멤버가 어디서 정의되었는지 파악하기가 어렵고 이름이 충돌할 수 있다는 단점이 있다.

 

 

// style.scss
 
@import 'module1';
@import 'module2';
@import 'module3';
 
h1 {
  font-weight: $font-weight;
}

 

 

세 개의 스타일시트를 불러와 사용하는 style.scss 파일입니다.

 

각각의 모듈 파일을 열어보면

 

 

$font-weight라는 동일한 이름의 변수가 module1에도 있고 module2에도 있다. 게다가 3은 2를 부르고 있다.

 

컴파일된 결과는 확인해 보자

 

 

200은 어디서 받아온 것인가?

 

 

어디선가 변수를 받아와서 썼다는 건 알겠는데, 어디서 받아왔고 누가 덮어쓴 건지 알 수가 없다. 

또, 주석을 보면 알 수 있지만 같은 모듈을 여러 번 @import하면 전부 컴파일한다는 단점도 있다.

 

이러한 단점을 해결하기 위해 개발된 것이 @use이다. 

 

@use의 특징

 

1. 항상 파일 시작 부분에 쓰여야 한다. (스타일 규칙에 포함될 수 없다.)

2. 가져온 멤버는 모두 네임스페이스를 갖는다.

3. 여러 번 @use를 사용해도 중복해서 가져오지 않는다.

4. 언더바(_) 또는 하이픈(-)으로 시작하는 멤버는 프라이빗으로 취급하므로 가져오지 않는다.

 

@use도 @import와 비슷하게 @use <불러올 scss 파일>로 작성한다.

차이점이 있다면 멤버를 사용할 때 네임스페이스를 지정해 줘야 한다는 것이다.

 

@use "module1";
@use "module2";
@use "module3";
 
h1 {
  font-weight: module1.$font-weight;
}

이렇게 하면 어느 모듈에서 가져온 변수인지 한눈에 알 수 있다.

 

함수, 믹스인 등 다른 멤버들에게도 동일하게 네임스페이스를 붙이면 된다.

@include할 때는 어느 파일의 믹스인인지 이름을 적어야 한다.

 

@use를 쓰면 네임스페이스를 같이 적어야 하므로 이름을 지을 때 간단하게 짓는 게 좋다.

@import를 쓸 때는 충돌을 피하기 위해 최대한 구체적으로 지었던 것과 비교된다.

 

@use "<url>" as <namespace> 이렇게 하면 더 짧게 호출하거나 동일한 이름으로 여러 모듈을 불러오는 것도 가능하다.

 

@use "module1" as m;
@use "module2" as mmmmm;
 
h1 {
  color: mmmmm.$color;
}

 

이것마저 귀찮다면, 네임스페이스 부분을 * (와일드카드)로 쓰면 네임스페이스 없이 모듈을 불러올 수 있다.

 

@use "module1" as *;
@use "module2" as *;
 
h1 {
  color: $color; //단, 동일한 변수가 있는 경우 충돌
}

 

하지만 멤버 이름이 쉽게 충돌날 수 있기 때문에 주의하여 사용해야 한다.

'HTML, CSS > CSS Preprocessors' 카테고리의 다른 글

[Sass] 조건문 이용하여 반응형 웹 만들기  (0) 2023.01.15
[Sass] 기본 작성법 익히기  (0) 2023.01.09
[Sass] Sass란?  (0) 2023.01.09
Comments