SCSS의 문법 nesting, mixin, extend , partial

SCSS의 여러 문법들에 대해 알아본다
nesting, media query 사용하기, mixin, extends 등등을 살펴본다.

css Preprocessor (전처리기)

SASS, SCSS, Less .. 이 들은 css 전(예비)처리기이다.
즉 css 동작 전에 사용하는 기능인데 css가 주지 못하는 불편한 과정들을 이들이 도와주게 된다.
웹에서는 오직 css만 동작하므로, 보통 전처리기로 작성한 뒤, 이 파일을 css로 컴파일하는 과정을 거치게 된다.

그림 1 SCSS 컴파일러 되는 과정

SASS vs SCSS

SASS
SASS : SCSS를 작성하는데 있어서 구조적 차이가 있고 작성이 번거롭고 복잡할 수 있다.
SCSS : 기존 CSS와 유사하게 작성할 수 있어 친근하게 느껴져 배우기 쉽다.

가장 큰 차이는 {}, ; 에서 나타난다.

sass
1
2
3
4
5
//sass
.box
width:100px
a
color:red
scss
1
2
3
4
5
6
7
//scss
.box{
width:100px;
a{
color:red;
}
}

sass는 들여쓰기로 범위를 구분하고 ;을 쓰지 않는다.
scss는 {}로 적용 범위를 구분하고 ;을 쓴다. css와 거의 유사한 형태이다.

SCSS 에서 변수 사용하기

$로 시작해야하고
$bk123-_ (영어,숫자,대시,언더스코어)가 들어갈 수 있다.

1
2
3
4
5
6
7
8
$red: #f53535;
$yellow: #f2fa1a;

.box{
width:50px;
height:50px;
background-color: $red; //background-color:#f53535;
}

scss 문법 공부를 하기에 앞서

예제링크를 들어가 html과 css 파일을 받는다. : https://codepen.io/blueweber/pen/WzvWPp

basic.html 예제코드html
1
2
3
4
5
6
7
8
<div id="box1">
box1<br>
<a href="#">button1</a>
<div id="box2">
box2<br>
<a href="#">button2</a>
</div>
</div>
basic.css 예제코드css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
html {
font-size: 18px;
}

body {
margin: 20px;
background-color: #fff4ef;
}

div {
color: #333;
padding: 20px;
}

a {
display: inline-block;
margin: 10px 0;
}

#box1 {
font-size: 40px;
background-color: #ffcccc;

border-radius: 20px;
border: 3px solid #f00;
box-shadow: 0px 3px 11px 0px rgba(0, 0, 0, 0.75);
}

#box1 > a {
color: #a22;
text-decoration: none;
}

#box1 > a:hover {
color: #000;
text-decoration: underline;
}

#box1:hover {
background-color: #ccc;
}

#box1 #box2 {
font-size: 20px;
background-color: #e9e9e9;

border-radius: 20px;
border: 3px solid #f00;
box-shadow: 0px 3px 11px 0px rgba(0, 0, 0, 0.75);
}

#box1 #box2 > a {
color: #ee6633;
text-decoration: none;
}

#box1 #box2 > a:hover {
color: #a22;
text-decoration: underline;
}

본격적으로 SCSS 문법을 들어가보자.

nesting

Nesting은 SCSS의 유용한 확장 기능으로 선언을 중첩(Nesting)하는 것이다.
HTML과 같은 방식으로 CSS 선택자를 중첩할 수 있다.
‘&’는 자기자신(상위선택자)를 가리킨다.

basic.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 기존 css 코드 */
#box1 {
font-size: 40px;
background-color: #ffcccc;
border-radius: 20px;
border: 3px solid #f00;
box-shadow: 0px 3px 11px 0px rgba(0, 0, 0, 0.75);
}

#box1:hover {
background-color: #ccc;
}

#box1 > a {
color: #a22;
text-decoration: none;
}

#box1 > a:hover {
color: #000;
text-decoration: underline;
}

(...)
basic.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* nesting된 코드 */
#box1{
font-size: 40px;
background-color: #ffcccc;
border-radius: 20px;
border: 3px solid #f00;
box-shadow: 0px 3px 11px 0px rgba(0, 0, 0, 0.75);

//여기서 &는 #box1태그를 가리킨다 #box1
&:hover{
color: #000;
text-decoration: underline;
}

& > a{
color: #a22;
text-decoration: none;
//여기서 &는 a태그를 가리킨다 #box1 > a
&:hover{
color: #000;
text-decoration: underline;
}
}
}
(...)

너무 많은 중첩은 오히려 코드의 혼란을 가져오므로 (마치 콜백지옥같은 모양새) 상황에 맞게 사용하도록 한다.

nesting에서 media query(미디어쿼리) 사용하기

미디어 쿼리란 Responsive Web(반응형웹)을 구현하는 CSS 기술로 특정조건(주로 width)에 따라 css를 다르게 줄 수 있게 하는 것이다.

scss 에서 미디어쿼리 사용법은 기존 css 미디어쿼리 사용하는 방식이랑 거의 비슷하다. nesting 문법을 사용해서 작성한다.

media query
1
2
3
4
5
6
7
8
9
10
11
12
13
#box1 {
&:hover {
background-color: #ccc;
}
//미디어 쿼리 작성
@media screen and (max-with: 500px) {
font-size: 20px;
}

@media screen and(min-width: 501px) and (max-width: 980px) {
font-size: 50px;
}
}

mixin

믹스인은 비슷한 코드를 여러번 사용해야할 때 사용한다.
mixin을 선언 할때는 @mixin을 사용하며, 적용할때는 @include로 불러온다.
@mixin mixin명(mixin내부에서 사용할 변수){

} @include mixin명(값);

mixin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//변수 앞에 $를 붙인다.
//$fontSize, $bgColor는 오직 이 믹스인 안에서만 사용되는 변수이다.
@mixin fontSizeBgColor($fontSize, $bgColor) {
font-size: $fontSize;
background-color: $bgColor;
}

#box1{
/*위 코드는
font-size: 40px;
background-color: #ffcccc;
와 완전히 같습니다.
*/
@include fontSizeBgColor(40px, #ffcccc);
}

#box1 #box2{
/*위 코드는
font-size: 20px;
background-color: #e9e9e9;
와 완전히 같습니다.
*/
@include fontSizeBgColor(20px, #e9e9e9);
}

extend

완전히 똑같은 코드를 하나로 묶어서 재사용할 때 사용한다.
extend를 선언할 땐 : %extend명{속성값}
extend를 불러올 땐 : @extend %extend명

extend
1
2
3
4
5
6
7
8
9
10
11
12
13
%boxShape {
border-radius: 20px;
border: 3px solid #f00;
box-shadow: 0px 3px 11px 0px rgba(0, 0, 0, 0.75);
}

#box1{
@extend %boxShape;
}

#box1 #box2{
@extend %boxShape;
}

이렇게 extend를 작성하면…

extend
1
2
3
4
5
6
#box1, #box1 #box2 {
border-radius: 20px;
border: 3px solid #f00;
-webkit-box-shadow: 0px 3px 11px 0px rgba(0, 0, 0, 0.75);
box-shadow: 0px 3px 11px 0px rgba(0, 0, 0, 0.75);
}

css에서 이런식으로 변환이 되게 된다.

partial

공용 스타일을 범용으로 하나의 파일로 묶고, 이를 여러 sass 파일에 가져다쓸때 partial을 사용한다.
예를 들어, mixin으로 만든 코드를 여러 scss 파일에서 재 사용해야할때, 그때마다 mixin을 새로만드는것이 아니라
_mixins.scss 식으로 파일을 만들어 범용 코드를 넣어놓고, 그 파일을 import 해 불러오는 식으로 사용한다.

예제를 위해, scss폴더 안에 partial 라는 폴더를 만들어보자
현재 폴더구조는 이렇다.

그림 2 폴더구조

partial 폴더 안에 _mixins.scss 파일을 생성하고 아까 만든 mixin 변수를 넣어준다.
앞에 _(언더스코어)를 붙이는 이유는 컴파일을 하지말라는 의미인데
이 _mixin.scss는 watiching sass를 시작해도 _mixins.css로 컴파일 되지 않는다.
어차피 이 파일을 다른 scss 파일에서 가져다 쓰기 때문에 컴파일 할 필요가 없기 때문이다.
이 규칙은 scss 뿐만이 아니라 다른 언어에서도 비슷하게 적용된다.

partial 파일을 가져올때는
@import “파일명”식으로 가져온다. 단, 앞의 언더스코어(_)와 뒤의 확장자(.scss)를 붙이지 않는다

_mixins.scss
1
2
3
4
5
//기존 basic.scss에서 mixin 부분을 가져와서 복붙한다.
@mixin fontSizeBgColor($fontSize, $bgColor) {
font-size: $fontSize;
background-color: $bgColor;
}
basic.scss
1
2
3
4
5
6
7
8
9
10
11
12
//_mixin.scss을 import 한다.
//기존에 적용되었던 mixin 내용을 날린다.
@import "mixins";

#box1{
//똑같이 mixin 내용이 적용이 된다.
@include fontSizeBgColor(40px, #ffcccc);
}

#box1 #box2{
@include fontSizeBgColor(20px, #e9e9e9);
}

확장 호스트가 예기치 않게 종료되었습니다

가끔 partial파일을 import를 할 때, 스펠링등을 잘못쳐셔 실수로 없는 파일을 import 하는 경우가 있는데..
이럴경우 자꾸 vscode에서
확장 호스트가 예기치 않게 종료되었습니다 또는
extension host terminated unexpectedly
식의 에러를 발생시키게 된다..
그리고 자꾸 vscode가 튕기게 되고 watiching sass가 안켜지는 이상한 문제가 지속적으로 발생됐다.

어제 한참 고생했는데
결론부터 말하자면 color Highlight 확장때문에 발생한 문제였다. 왠지 모르겠지만 저 확장이랑 무언가 충돌이 나는듯하다.
color Highlight 확장을 사용안함으로 설정하고 다시 로드하면 더이상 에러를 발생시키지 않는다.
그리고 저거랑 비슷한 역할을 하는 colorize라는 확장이 있다..
저걸 설치하니 문제 해결..ㅠㅠ

어제 저거때문에 공부도 못하고 구글링 엄청 했는데
오늘 내가 유료로 듣는 인프런 강사님께서 해결책을 알려주셨다…
허무허무..ㅠㅠ

결론: 강의를 끝까지 듣자..

그림 3 colornize 확장

scss의 if 문 사용하기

scss에서도 if문을 사용할 수 있다.
예를들어, mixin 변수에 따른 다른 스타일 효과를 주고 싶을때 다음과 같이 사용할 수 있다.

if.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

//mixin 생성
@mixin textAndBgColor($textColor, $bgColor) {
color: $textColor;
background-color: $bgColor;
}


//분위기에 따른 테마같이 스타일을 나눠서 효과를 주고 싶을 떄
//theme mixin 생성
@mixin theme($mood) {
//$mood 변수가 "light"란 글자와 같다면
@if $mood == "light" {
//이 mixin 효과를 주겠다.(이중 mixin)
@include textAndBgColor(#333, #ff0);
}
//else if
@else if $mood == "dark" {
@include textAndBgColor(#fff, #333);
}
//else
@else {
@include textAndBgColor(#f00, #aaa);
}
}

#box1 {
//theme mixin 불러오기
@include theme("light");
}

#box2 {
@include theme("dark");
}

#box3 {
@include theme("noraml");
}

scss 작성 후 watching sass를 켜놓은 상태라면 css가 다음과 같이 컴파일 된다.

if.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
body {
margin: 50px;
}

#box1 {
color: #333;
background-color: #ff0;
}

#box2 {
color: #fff;
background-color: #333;
}

#box3 {
color: #f00;
background-color: #aaa;
}
/*# sourceMappingURL=if.css.map */
if.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="css/if.css" />
</head>
<body>
<div id="box1">box1</div>
<div id="box2">box2</div>
<div id="box3">box3</div>
</body>
</html>

이 css 파일을 html에 적용시킨 결과

그림 if 문 결과

Comentarios

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×