Scss는 @media 등의 기존의 at-rule(@-rule) 외에 새로운 @-rule을 이용해서 기존의 CSS에 편의한 기능을 제공해준다. 이번 포스트에서는 새롭게 추가된 @-rule들에 대해 알아보자.
새롭게 추가된 @-rule들
다음은 SCSS에 새롭게 추가된 @-rule들이다.
- 작성된 스타일의 재사용
- @mixin, @include, @content, @extend
- 다른 SCSS에서 선언된 mixin, function, variable 들을 로딩하고 여러 css들의 결합
- @use, @forward,
@import(deprecated)
- 컴파일 시 발생하는 오류, 경고, 디버그 메시지 활용
- 제어문
- 기타
- @function: SASS script 표현식에서 사용할 수 있는 사용자 정의 함수의 작성
- @at-root: 작성된 스타일을 css 문서의 최상위 루트에 배치
@mixin과 @include
용도와 작성법
@mixin과 @include는 서로 짝궁처럼 사용된다.
- @mixin: stylesheet에서 재사용할 수 있는 css 스타일을 정의하기 위한 rule이다.
- @include: @mixin 내용에 대한 사용 선언
작성법은 아래처럼 간단하다. @mixin으로 블록을 선언하고 @include로 가져다 쓸 수 있다.
@mixin <name> {
/* mixin 사용*/
@include <mixin name>;
// style
}
@mixin <name>(<arguments...>) {
/* argument가 선언된 mixin 사용*/
@include <mixin name>(arguments)
// style
}
사용 예
작성법이 쉽기도 하지만 활용 예를 보면 더 쉽게 이해가 가능하다. ㅎ
@mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
@mixin horizontal-list {
@include reset-list;
li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}
nav ul {
@include horizontal-list;
}
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav ul li {
display: inline-block;
margin-left: -2px;
margin-right: 2em;
}
처음 블록에서 reset-list라는 mixin이 설정되었다. 내용은 모두 css 스타일 선언이다.
두 번째 블록에서는 horizontal-list 라는 mixin이 설정되면서 앞서 정의한 reset-list를 include로 사용하고 있다. 추가로 li 선택자에 대한 스타일도 작성되어있다. 그럼 horizontal-list를 include 하면 css style 정의 내용(reset-list를 include한 )과 함께 li에 대한 내용을 가져간다.
그 결과가 세번째 블록인 nav ul이다. 이 블록은 horizontal-list를 include 하고 있기 때문에 결과 CSS에는 style 내용인 reset-list를 그대로 가지는 블록 하나와 nav ul에 li가 추가된 블록 하나가 생성된다.
argument 활용
@mixin에는 마치 메서드 처럼 argument를 선언할 수 있고 @include에서 mixin 호출 시 값을 전달한다. 이를 통해서 동일한 @mixin을 호출할 때마다 다르게 사용할 수 있다. argument를 선언할 때는 변수 선언 때 처럼 $기호를 사용한다.
argument에는 optional argument와 keyword argument라는 것도 제공된다.
- optional argument: argument 선언 시 기본 값을 지정하고 값을 전달하지 않은 경우 기본값 사용
- keyword argument: argument의 순서에 무관하게 이름 기반으로 변수를 지정해서 argument에 값 전달 가능
- variable arguments(arbitary arguments): ...으로 여러 개의 변수 전달 가능
@mixin thumb($width, $height: 20px, $color: red) {
width: $width;
height: $height;
background-color: $color;
}
.img-1 {
@include thumb(100%)
}
.img-2 {
@include thumb(100%, $color: blue, $height: 100%)
}
.img-1 {
width: 100%;
height: 20px;
background-color: red;
}
.img-2 {
width: 100%;
height: 100%;
background-color: blue;
}
첫 번째 mixin인 thumb에서 $width, $height, $color가 선언되었다. 이때 $height와 $color에는 각각 20px, red라는 기본 값이 선언되어있다. 이것이 optional argument이다.
img-1은 thumb를 호출하면서 $height와 $color를 넘겨주지 않았기 때문에 해당 속성에는 기본 값이 적용된다.
img-2는 thumb를 호출하면서 $width에 해당하는 100%와 함께 두 개의 argument에 값을 전달하는데 선언 순서와 전달되는 값의 순서가 다르다. 대신 값을 전달할 때 어떤 값인지를 함께 넘겨주고 있다. 이런 형식이 keyword argument이다.
@mixin order($height, $selectors...) {
@for $i from 0 to length($selectors) {
#{nth($selectors, $i + 1)} {
position: absolute;
height: $height;
margin-top: $i * $height;
}
}
}
@include order(150px, "input.name",
"input.address",
"input.zip");
input.name {
position: absolute;
height: 150px;
margin-top: 0px;
}
input.address {
position: absolute;
height: 150px;
margin-top: 150px;
}
input.zip {
position: absolute;
height: 150px;
margin-top: 300px;
}
order mixin에는 $selectors가 variable arguments 형태로 선언되어있다. 이 argument는 통상 반복문과 함께 사용된다. @include에서 order를 사용하면서 input.name, input.address, input.zip 3개를 넘겨주었고 결과적으로 3개의 선택자가 선언된 것을 확인할 수 있다.
@content
@content라는 rule은 @mixin 내부에 사용되는데 값 하나가 전달되는 argument와 달리 style block을 통으로 받아서 처리할 수 있다.
@mixin hover {
&:not([disabled]):hover {
@content;
}
}
.button {
border: 1px solid black;
@include hover {
border-width: 2px;
}
}
.button {
border: 1px solid black;
}
.button:not([disabled]):hover {
border-width: 2px;
}
@mixin hover에는 @content가 선언되어 style block을 받을 준비가 되어있다.(&는 외부 블록의 선택자이다.)
.button 블록에서 hover를 사용하면서 이제 () 가 아닌 {}를 이용해서 style block을 넘겨준다. hover에는 선택자를 통해 새로운 블록이 선언되어있으므로 결과 css에는 border를 갖는 .button 블록과 .button:not([disabled]):hover 블록 2개가 생성된다.