티스토리 뷰

Written by John W. Long on August 28, 2011 Translated by Chuck Lee
이 글은 The Sass Way에 있는 글 Leveraging Sass mixins for cleaner code를 번역한 글로 많은 의역이 포함되어 있습니다.

의심의 여지없이, Sass에서 가장 강력하고 유용한 기능은, 작성된 코드를 재사용이 가능하도록 만들어주는 믹스인(mixin)입니다.

매크로 같은 믹스인

믹스인은 Sass의 매크로라고 할 수 있습니다. 만약 개발을 프로그래밍을 해본 경험이 있다면, 함수(functions), 프로시저나 메소드처럼 생각해도 괜찮습니다. 하지만 기술적으로는 이런 개념들과는 완전히 다르게 런타임으로 코드를 실행시키는 것이 아니고, 컴파일할 때 코드를 생성하는 목적으로 사용됩니다.

믹스인은 어떻게 작동하는가

Compass 프로젝트는 당신을 편하게 만들어줄 다양한 믹스인들로 구성되어 있습니다. CSS3부터 타이포그라피, 레이아웃, 이미지 가공등, 해당 기능을 방탄 CSS로 작성하기 쉽게 만들어줍니다. 우리는 Compass를 Sass의 표준 라이브러리로 생각하고 있습니다.

Compass에서 CSS3에 대한 지원은 가장 끝내주는 기능이라 할 수 있습니다. Compass는 아래 예제와 같이, 새로운 기능들을 모든 브라우저에서 사용할 수 있게 해주는 CSS3 믹스인들을 제공합니다.

예를 들면, border-radius믹스인은 border-radius를 간단하게 사용할 수 있게 해줍니다.

a.button {
    background: black;
    color: white;
    padding: 10px 20px;
    @include border-radius(5px);
}

이 코드의 결과물:

a.button {
    background: black;
    color: white;
    padding: 10px 20px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
    -khtml-border-radius: 5px;
    border-radius: 5px;
}

border-radius믹스인이 6줄의 코드로 변한 결과물을 볼 수 있습니다. 이 6줄은 모든 최신 웹브라우저에서 border-radius를 사용할 수 있게 해줍니다(만약 당신이 직접 작성한다면, 아마 Opera(-o)나 Konquerer(-khtml)를 지원하는 코드는 작성하지 않았을 수도 있을거에요. 하지만 Compass는 전부 무료로 작성해줍니다!)

위에서 사용된 @include는 Sass에게 믹스인을 사용하겠다고 말하는 것입니다. 이것은 border-radius라는 믹스인의 이름을 그대로 사용합니다. 괄호안에는 믹스인에게 전달하는 아규먼트를 사용합니다. border-radius믹스인은 하나의 아규먼트만 가집니다. 이 경우에는 5px이 아규먼트 입니다.

자기 코드 작성해보기

border-radius의 소스를 살펴보도록 합시다. 실제 Compass에 사용된 버전은 조금 더 복잡하지만, 개념 정림을 위해 단순화된 버전을 보여줄 것입니다. 이 정도면 자기 코드를 작성하기 위한 개념을 잡는 데는 충분합니다.

@mixin border-radius($radius) {
    -moz-border-radius: $radius;
    -webkit-border-radius: $radius;
    -ms-border-radius: $radius;
    border-radius: $radius;
}

@mixin이라는 선언으로 시작되고, 그 다음에는 믹스인의 이름이 나옵니다. 이 경우에는 border-radius가 되겠죠. 믹스인의 이름은 여백만 없다면 어떠한 문자 조합도 사용이 가능합니다. 그 다음에는 (...)의 형태로 괄호안에 아규먼트를 리스트로가 들어옵니다. 위에 나온 믹스인은 하나의 아규먼트인 $radius만 가집니다. 아규먼트는 콤마로 나눠질 수 있는 한도 내에서는 계속해서 사용될 수 있습니다.

그 다음에 믹스인의 정의는 {...}안에 들어옵니다. 믹스인에는 어떤 CSS속성이라도 사용할 수 있습니다. 여러 속성들과 선택자들을 조합해서 선언할 수 있는 것이지요.

이 경우에는, border-radius 믹스인은 모든 주요 브라우저에서 사용 가능한 형태의 border-radius 속성을 포함하고 있습니다.

$radius아규먼트나 변수는 CSS속성에 값으로 설정되고는 합니다. 이 테크닉을 사용하면 믹스인에 하나의 값만 전달하더라도 결과물에서는 4번 반복되어 나타나게 할 수 있습니다. 또한 실수로 특정 브라우저에만 잘못된 값을 사용하는 경우도 방지할 수 있으며, 타이핑 양도 많이 줄여줍니다.

디폴트 아규먼트

$radius아규먼트에 디폴트 값을 추가해서 이 믹스인을 업그레이드 할 수도 있습니다. 이렇게 말이죠:

@mixin border-radius($radius: 5px) {
    ...
}

이렇게 하면 $radius아규먼트는 optional이 됩니다. 그러면 이렇게도 사용할 수 있게 되죠:

@include border-radius;

선언할 때 사용된 디폴트 값이 결과물로 나오게 됩니다. 이 경우에는 위에서 선언했던 것 처럼 5px이 되겠네요.

꽤 유용할 것으로 판단되는 또 다른 트릭은 믹스인을 위한 디폴트 값으로 사용될 변수를 선언언한 후에 사용하는 것입니다:

$default-border-radius: 5px !default;
@mixin border-radius($radius: $default-border-radius) {
 ...
}

이렇게 하면 프로젝트끼리 코드를 공유해야 할 경우에 특히 유용합니다. 글로벌 변수로 디폴트 값을 선언하고 필요할 때만 값을 오버라이드 하면 되니까요.

키워드 아규먼트

마지막으로 설명할 믹스인 기능은 Sass 3.1에서 새롭게 소개된 키워드 아규먼트입니다. 키워드 아규먼트는 믹스인이 여러개의 야규먼트를 받아야 할 때 특히 유용합니다. 만약 아규먼트들에 디폴트 값이 설정되어 있으면, 다른 아규먼트들의 값을 전달하지 않더라도 아규먼트의 이름을 이용해서 특정 아규먼트 값만 전달할 수 있습니다.

@if구문을 이용해서, 더 발전된 버전의 border-radius믹스인을 만들 수 있습니다:

@mixin border-radius($radius: 5px, $moz: true, $webkit: true, $ms: true) {
    @if $moz    { -moz-border-radius:    $radius; }
    @if $webkit { -webkit-border-radius: $radius; }
    @if $ms      { -ms-border-radius:     $radius; }
    border-radius: $radius;
}

위의 코드는 $moz, $webkit, $ms값에 따라 Firefox, Safari, Internet Explorer를 위한 코드를 출력해줍니다. 모든 아규먼트에 디폴트값이 설정되어 있는 경우에 이렇게 하면 Internet Explorer를 위한 코드만 날려버릴 수 있습니다:

@include border-radius($ms: false);

이렇게 하면 아래처럼 이름을 사용하지 않고 모든 아규먼트 값을 넣어줘야 할 때보다 훨씬 간편하지요:

@include border-radius(5px, true, true, true);

키워드 아규먼트를 사용하면, 믹스인을 호출할 때 선언했을 때와 다른 순서로 아규먼트를 사용해도 상관없습니다.:

@include border-radius($ms: false, $radius: 10px);

결론

여기까지가 Sass 믹스인에 대한 대략적인 내용입니다. 당신이 코드를 짤 때 더 나은 아이디어를 적용시킬 수 있으려면 잘 만들어진 Sass프로젝트, Compass의 소스코드를 살펴보는 것을 권장합니다. 훌륭한 기술들을 배울 수 있는 200개도 넘는 믹스인이 포함되어 있습니다. 또한 Compass Doc에는 "View Source"링크가 제공되기 때문에 믹스인이 정확하게 어떻게 작동하는지 살펴볼 수 있습니다. Compass의 border-radius부터 어떻게 구현되었는지 시작해보는 것은 어떨까요.