Sass[SCSS] 기초 이론 5 - 그룹 선언하기, 사용하기, 선택자 속성 사용 (@mixin, @include, @extend)
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;
}
이렇게 .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;
}