SASS의 믹스인(Mixin)
이 문서에서는 SASS의 믹스인에 대해 설명합니다.
실제 예제를 통해 SASS의 믹스인에 대해 설명하겠습니다.
YouTube Video
SASS의 믹스인(Mixin)
개요 – 믹스인이란?
믹스인은 자주 사용되는 스타일 속성 집합을 재사용 가능한 함수로 정의하고 필요한 곳에서 호출할 수 있도록 해주는 메커니즘입니다. 믹스인은 CSS 클래스와 여러 속성을 DRY(Don't Repeat Yourself, 반복하지 않기)하게 유지하는 데 매우 유용합니다.
예시: 가장 간단한 믹스인
아래는 border-radius와 box-shadow를 함께 재사용하는 간단한 믹스인 예시입니다. 이 믹스인을 호출하면 여러 요소에 동일한 스타일을 적용할 수 있습니다.
1// Simple mixin that applies border-radius and box-shadow
2@mixin card-style {
3 border-radius: 8px;
4 box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
5 background: #fff;
6}
7
8.card {
9 @include card-style;
10 padding: 1rem;
11}- 이 믹스인을 사용하면 스타일을 직접 반복해서 입력할 필요가 없습니다.
- 호출은 한 줄이면 충분합니다:
@include card-style;.
인자(매개변수)를 사용하는 믹스인
믹스인은 함수처럼 인자를 받을 수 있습니다. 이 기능을 통해 동일한 논리로 스타일만 변경할 수 있습니다. 다음은 색상을 인자로 받아 사용하는 믹스인 예시입니다.
1// Mixin with parameters: accepts a color and optional radius
2@mixin colored-box($bg-color, $radius: 4px) {
3 background-color: $bg-color;
4 border-radius: $radius;
5 padding: 0.75rem;
6}
7
8.box-primary {
9 @include colored-box(#007acc);
10}
11
12.box-custom {
13 @include colored-box(#ffcc00, 12px);
14}- 기본값을 지정하면 인자가 생략되었을 때의 동작을 제어할 수 있습니다.
- 이 예시에서는 기본 radius 값이 사용되고, 배경 색상만 덮어씁니다.
가변 인자(...)를 사용하는 경우
여러 값을 받으려면 가변 인자($args...)를 사용할 수 있습니다. 이 방법은 유틸리티 클래스 생성이나 대체 리스트를 전달할 때 유용합니다.
여러 개의 글꼴 패밀리나 섀도 값을 전달할 때도 도움이 됩니다.
1// Mixin that accepts variable arguments and forwards them to box-shadow
2@mixin multi-shadow($shadows...) {
3 box-shadow: $shadows;
4}
5
6.panel {
7 @include multi-shadow(0 2px 4px rgba(0,0,0,0.08), 0 8px 16px rgba(0,0,0,0.06));
8}- 호출 시 쉼표로 구분된 여러 개의 섀도 값을 전달할 수 있습니다.
- 이렇게 하면 단순한 섀도와 복잡한 섀도 모두에 같은 믹스인을 사용할 수 있습니다.
@content와 함께 쓰는 믹스인 — 블록 수신
@content를 사용하면 믹스인이 호출자로부터 스타일 블록을 넘겨받을 수 있습니다. 이렇게 하면 믹스인은 공통 래퍼를 제공하고, 호출자는 내부 세부 스타일을 지정할 수 있습니다.
1// Mixin that sets up a responsive container and yields to caller via @content
2@mixin responsive-container($max-width: 1200px) {
3 margin-left: auto;
4 margin-right: auto;
5 padding-left: 1rem;
6 padding-right: 1rem;
7 max-width: $max-width;
8
9 @content; // place where caller's styles are inserted
10}
11
12.header {
13 @include responsive-container(1000px) {
14 display: flex;
15 align-items: center;
16 justify-content: space-between;
17 }
18}- 호출 시
@include에 블록을 추가하여 내부 스타일을 삽입할 수 있습니다. - 이 패턴은 그리드, 카드, 폼 등 레이아웃 래퍼 구현에 유용합니다.
조건문과 반복문을 활용한 고급 믹스인
@if 및 @for와 같은 제어 구조를 믹스인 내에서 사용할 수 있습니다. 이들을 이용해 유틸리티 생성 자동화나 반응형 세팅 묶기를 할 수 있습니다.
아래는 유틸리티 클래스의 폭을 자동 생성하는 예시입니다.
1@use 'sass:math';
2
3// Mixin that generates width utility classes from a list of fractions
4@mixin generate-widths($fractions) {
5 @each $name, $fraction in $fractions {
6 .w-#{$name} {
7 width: math.percentage($fraction);
8 }
9 }
10}
11
12$widths: (
13 '1-4': 0.25,
14 '1-3': 0.3333,
15 '1-2': 0.5,
16 '3-4': 0.75
17);
18
19@include generate-widths($widths);- 호출 측에서 생성하고자 하는 분수의 맵을 전달하기만 하면, 해당 유틸리티 클래스를 한 번에 자동으로 생성할 수 있습니다.
- 이 접근 방법을 사용하면 수동 스타일 정의를 줄이면서도 디자인의 일관성을 유지할 수 있다는 장점이 있습니다.
믹스인(Mixin) vs 플레이스홀더(%placeholder)
믹스인은 속성 집합을 직접 삽입하는 반면, 스타일을 상속할 때는 플레이스홀더를 @extend와 함께 사용합니다. 믹스인은 경우에 따라 중복된 CSS가 생성될 수 있지만, @extend는 특정 상황에서 더 간결한 CSS를 만들 수 있습니다.
각 방법이 생성하는 CSS의 목적과 차이점을 이해하면 가장 최적의 방식을 선택할 수 있습니다.
1// Placeholder example (for comparison)
2%btn-base {
3 display: inline-block;
4 padding: 0.5rem 1rem;
5 border-radius: 4px;
6}
7
8.btn-primary {
9 @extend %btn-base;
10 background: #007acc;
11 color: #fff;
12}
13
14.btn-secondary {
15 @extend %btn-base;
16 background: #e0e0e0;
17}@extend를 사용해 플레이스홀더를 확장하면 여러 셀렉터를 하나의 규칙으로 합칠 수 있어 더욱 간결한 CSS가 만들어집니다.- 반면에 믹스인은 필요한 위치에 속성을 직접 삽입하므로 유연성을 제공하고, 의도치 않은 셀렉터 병합을 방지하는 데 도움이 됩니다.
실무에서 자주 쓰이는 패턴(반응형, 벤더 프리픽스 등)
실제 개발에서는 벤더 프리픽스나 반응형 기능 등 공통 처리를 믹스인에 묶는 것이 좋습니다. 아래는 transform과 프리픽스 속성을 결합한 예시입니다. 브라우저 호환성을 위한 코드를 중앙화할 수 있어 유지보수가 쉬워집니다.
1// Mixin for transform with vendor prefixes
2@mixin transform($value) {
3 -webkit-transform: $value;
4 -ms-transform: $value;
5 transform: $value;
6}
7
8.icon-rotate {
9 @include transform(rotate(45deg));
10}- 사용법이 간단하며,
@include transform(rotate(10deg));와 같이 어디에서든 사용할 수 있습니다. - 앞으로 접두사가 불필요해지더라도 믹스인을 업데이트하면 코드 전반에 걸쳐 변경 사항이 반영되어 유지 관리가 더 쉬워집니다.
실용 예시: 카드와 버튼의 조합
아래는 카드 내에서 사용되는 버튼 스타일을 믹스인으로 통합하고, 테마 색상에 따라 전환할 수 있도록 한 예시입니다.
이 방법은 흔히 쓰는 '카드+버튼' 패턴을 믹스인으로 정리합니다.
1// Simple mixin that applies border-radius and box-shadow
2@mixin card-style {
3 border-radius: 8px;
4 box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
5 background: #fff;
6}
7
8// Mixin for transform with vendor prefixes
9@mixin transform($value) {
10 -webkit-transform: $value;
11 -ms-transform: $value;
12 transform: $value;
13}
14
15// Button mixin with theme and size parameters
16@mixin btn($bg, $color: #fff, $padding: 0.5rem 1rem) {
17 display: inline-block;
18 padding: $padding;
19 background: $bg;
20 color: $color;
21 border-radius: 6px;
22 text-decoration: none;
23 cursor: pointer;
24 @include transform(translateY(0)); // reuse earlier transform mixin
25}
26
27// Card mixin that accepts inner button styling via @content
28@mixin card($gap: 1rem) {
29 @include card-style; // reuse earlier card-style mixin
30 padding: $gap;
31 @content;
32}
33
34.card-feature {
35 @include card {
36 .title { font-size: 1.125rem; margin-bottom: 0.5rem; }
37 .cta {
38 @include btn(#007acc);
39 }
40 }
41}
42
43.card-warning {
44 @include card {
45 .title { font-weight: bold; }
46 .cta {
47 @include btn(#ff6600);
48 }
49 }
50}- 이러한 믹스인을 사용하면 컴포넌트를 간결하게 작성할 수 있습니다.
성능과 생성 CSS 파일 크기에 유의할 것
믹스인은 호출될 때마다 속성을 삽입하므로 동일한 규칙에 @include를 무분별하게 사용하면 최종 CSS 파일이 커질 수 있습니다. 필요 시 플레이스홀더나 컴포넌트 디자인과 조합해 최적화할 수 있습니다.
또한, 다음과 같은 대책도 효과적입니다.
- 자주 사용되는 스타일은 재사용을 위해 클래스로 만들어야 합니다.
- 공통 패턴은
@content를 이용하여 그룹화해야 합니다. - 복잡한 유틸리티의 생성은 빌드 시에만 수행되어야 합니다.
디버깅을 쉽게 하는 팁
믹스인을 활용할 때는 디버깅과 유지관리성을 향상시키기 위한 방법을 고안하는 것도 중요합니다. 믹스인 내에서 명확한 변수명을 사용하고 주석을 추가하면 나중에 코드를 검토할 때 이해하기가 더 쉬워집니다. 또한, 기능이 복잡해질 경우 믹스인을 더 작은 단위로 나누면 테스트가 쉬워지고 유지관리성이 향상됩니다.
또한, 소스맵을 활성화하면 어떤 믹스인이 어떤 CSS를 생성했는지 쉽게 추적할 수 있어 문제를 분리하는 것이 쉬워집니다.
아래는 문서화 주석이 추가된 이해하기 쉬운 믹스인의 예시입니다.
1// Example: readable mixin with clear param names and comments
2/// Adds a subtle focus ring for accessibility
3/// $color - ring color
4/// $size - thickness of the ring
5@mixin focus-ring($color: #007acc, $size: 2px) {
6 outline: none;
7 box-shadow: 0 0 0 $size rgba(blue($color), 0.15);
8}- 이렇게 정리된 문서화 주석이 있으면 팀 내에서 공유 및 이해가 쉬워집니다.
- SASS 문서 주석은 호환 도구를 사용하면 자동으로 추출할 수 있으므로, 스타일 가이드와 같은 문서를 생성하는 데에도 유용합니다.
요약
믹스인은 자주 사용하는 스타일을 묶어 재사용할 수 있게 해주므로, 코드 중복을 줄이고 유지보수성을 향상시킵니다. 또 여러 셀렉터가 동일한 규칙을 공유한다면 믹스인뿐만 아니라 @extend(플레이스홀더)도 고려하세요. 또한 @content를 사용하면 레이아웃 래퍼와 콘텐츠의 유연한 분리가 가능하지만, @include의 과도한 사용은 CSS 파일이 비대해질 수 있으니 주의가 필요합니다. 인자, 기본값, 가변 인자를 적극 활용해 범용적이고 확장하기 쉬운 믹스인을 설계하는 것이 중요합니다.
위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.