scss

  • SUNGMIN SHIN
  • 74 Minutes
  • 2018년 2월 20일

SASS(SCSS)

SASS

소개

전처리기(preprocessor)
임의의 소스 파일을 가져와서 브라우저가 이해할 수 있는 형태로 변환해주는 도구를 뜻하며 존재하지 않는 기능을 추가하는 용도로 주로 사용되며 일반적으로 직접 동작 시킬 수 없어 컴파일이라는 변환의 과정을 거처야 합니다.
CSS를 위한 대표적인 전처리기로는 SASS, LESS, Stylus등이 있습니다.


SASS와 SCSS

SASS (Syntactically Awesome Style Sheets)

  • CSS 전처리기의 하나
  • 나름 오랜 역사를 자랑(2006년~)하며 그만큼 높은 성숙도를 가지고 있음
  • 코드의 작성은 SASS표기법과 SCSS표기법 두가지를 선택하여 사용할 수 있음

SCSS

  • SASS의 표기법 중 1가지
  • SASS 버전3부터 등장하였으며 SASS의 표준 표기법
  • SCSS 표기법은 CSS와 구문이 완전히 호환됨과 동시에 SASS의 모든 기능을 지원하는 것이 특징


표기법에 따른 차이 점의 예

SASS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* SASS */
=btn-submit($color:red)
display:inline-block
box-sizing:border-box
padding:0 15px
color: $color;

.box
width: 100px
border: 1px solid red;
div
color: red
&:last-child
+btn-submit(blue)

SCSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* SCSS */
@mixin btn-submit($color:red) {
display:inline-block
box-sizing:border-box
padding:0 15px
color: $color;
}

.box{
width: 100px;
border: 1px solid red;
div{
color: red;
&:last-child {
@include btn-submit(blue);
}
}
}


환경 설정

컴파일 하기

  1. cli를 이용(ruby, node등)
  2. 어플리케이션 번들러를 사용(webpack, parcel, gulp, grunt 등)
  3. web app (EX> https://www.sassmeister.com)
  4. gui를 이용(EX> http://koala-app.com)


디버깅

  1. 소스맵

    1. 컴파일 과정을 거친 코드는 그 자체로 알아보기 힘들다는 문제가 있음
    2. 이러한 문제를 해결하기 위해 대 부분의 최신 전처리기들에는 일명 소스맵(source map)이라고 불리는 기능을 지원
    3. 소스맵이란 컴파일 된 파일과 그 소스 사이의 관계를 만들어주는 역활을 하는 것으로 JSON 기반 매핑 형식으로 작성
  2. 소스맵의 사용 예(크롬)

    • 크롬에서 소스맵을 사용하지 않은 경우 사진과 같이 컴파일된 css의 위치만 확인할 수 있음
    • 소스맵이 존재하는 경우 .scss의 경로를 안내


문법 (http://sass-lang.com/guide)

1. 주석

1
2
3
4
5
// 한줄 주석 입니다.

/*
여려줄 주석 입니다.
*/


2. 중첩(nest)

중첩

중첩기능은 선택자의 반복을 피하고(특히 상위선택자) 코드만으로 마크업의 구조를 예상할 수 있어 편리합니다.

HTML
1
2
3
<button class="btn_submit" type="button">
<span>SUBMIT</span>
</button>
SCSS
1
2
3
4
5
6
7
8
button{
border:1px solid red;
background:#ccc;
span{
color:#fff;
line-height:20px;
}
}


[ 속성 중첩 ]

복수의 값을 가지는 일부 속성들은 중첩된 형태로 사용할 수 있습니다.

SCSS
1
2
3
4
5
6
7
8
9
10
div{
margin:{
top: 50px;
left: 20px;
};
padding: {
bottom: 70px;
right: 60px;
};
}


[ 상위 선택자 참조 (&) ]

중첩 안에 “&“ 키워드를 사용하면 상위 선택자를 참조할 수 있습니다.

HTML
1
2
3
<button class="btn_submit" type="button">
<span>SUBMIT</span>
</button>
SCSS
1
2
3
4
5
6
7
8
9
10
11
12
button{
border:1px solid red;
background:#ccc;
span{
color:#fff;
line-height:20px;
}
// &.btn_submit => button.btn_submit
&.btn_submit{
border-color:blue;
}
}


중첩(nest) 벗어나기 ( @at-root)

@at-root“ 를 사용하면 중첩 안의 변수등 값을 참조하여 사용하지만 구조적으로는 밖에서 사용되어야 하는 경우 유용하게 사용할 수 있습니다.

SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
button{
$btn-width: 200px;
$btn-height: 300px;
border:1px solid red;
background:#ccc;
span{
color:#fff;
line-height:20px;
}
@at-root .link{
width:$btn-width;
height:$btn-height;
}
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
10
11
12
button {
border: 1px solid red;
background: #ccc;
}
button span {
color: #fff;
line-height: 20px;
}
.link {
width: 200px;
height: 300px;
}


2. 변수

여러번 사용될 값이라면 변수로 선언하여 사용할 수 있습니다.

SCSS
1
2
3
4
5
$font-color-default: #ccc;

button{
color: $font-color-default;
}


변수의 유효범위

변수는 블록 “{ }“ 단위로 유효 범위를 가집니다.

SCSS
1
2
3
4
5
6
7
8
9
10
11
$color: red;

.box1{
$color: blue;

color:$color;
}

.box2{
color:$color;
}
컴파일 된 CSS
1
2
3
4
5
6
7
.box1 {
color: blue;
}

.box2 {
color: red;
}


변수의 재선언, 재할당

변수는 유효범위 내에서 재선언 및 재할당할 수 있습니다.

SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
$color: red;
$bgColor: blue;

$color: yellow;
$bg-color: gray;


.box{
// 재선언된 $color
color:$color;
// $bg-color는 $bgColor의 재할당
background-color:$bg-color;
}
컴파일 된 CSS
1
2
3
4
.box {
color: yellow;
background-color: gray;
}


!default

!default“ 는 만약변수가 이미 선언되어 있다면 사용하지 않겠다는 의미로 사용되는 키워드로 외부 SASS나 다수의 작업자가 공통적으로 작업하는 경우 이전에 선언된 값이 존재한다면 바뀌는 것을 막는 용도로 사용 됩니다.

SCSS
1
2
3
4
5
6
7
$color: red;

.box{
// 변수 $color가 존재한다면 선언되지 않습니다.
$color: blue !default;
color:$color;
}
컴파일 된 CSS
1
2
3
.box {
color: red;
}


!global

!global“ 은 변수 선언의 범위와 관계 없이 전역으로 설정하는 키워드로 전역에 동일한 이름의 변수가 존재한다면 재선언됩니다.

SCSS
1
2
3
4
5
6
7
8
9
10
$color: red;

.box1{
// 전역 $color의 값이 변경
$color: blue !global;
color:$color;
}
.box2{
color: $color;
}
컴파일 된 CSS
1
2
3
4
5
6
.box1 {
color: blue;
}
.box2 {
color: blue;
}


#{} (문자 보간)

#{}“ 를 이용하면 코드의 어디든지 변수 값을 넣을 수 있습니다.

SCSS
1
2
3
4
5
6
7
8
9
$on: on;
$file-name: "ko_remembrance_48x48.png";

.box{
background:url(https://www.google.com/images/hpp/#{$file-name});
&.#{$on} {
border:1px solid red;
}
}
컴파일 된 CSS
1
2
3
4
5
6
.box {
background: url(https://www.google.com/images/hpp/ko_remembrance_48x48.png);
}
.box.on {
border: 1px solid red;
}


데이터 타입

종류 사용 예 설명
숫자(number) 1, 2, 0.5px 숫자(px등의 단위를 갖는 값도 숫자로 인식)
문자(string) bold, color, img-section 따옴표는 선택적으로 사용
색상(color) blue, #001100, rgba(255, 0, 0, 0.3) 색상에 관련된 문자도 포함
블린(boolean) true / false
널(null) null 아무 것도 없다는 의미의 값으로 속성 값이 null인경우 컴파일되지 않습니다.
리스트(list) (apple, orange, banana) / apple orange 공백이나 ‘,’로 구분된 값의 목록이며 괄호는 선택적으로 사용
맵(Maps) (apple: a, orange: o, banana: b) 괄호안에 선언되여하며 키:값의 형태로 선언


연산

산술연산자
종류 설명 비고
+ 더하기
- 빼기
* 곱하기 하나 이상의 값이 반드시 숫자
/ 나누기 오른쪽의 값이 반드시 숫자
% 나머지


비교 연산자
종류 설명
== 같음
!= 같지 않음
< 작음
>
<= 작거나 같음
>= 크거나 같음


논리 연산자
종류 설명
and 그리고
or 또는
not 부정


연산 사용 시 주의 사항
숫자가 아닌 연산 가능한 요소

3. 가져오기(import)

@import 디렉티브를 사용하면 외부에서 SASS(SCSS), CSS 파일을 가져올 수 있습니다.
이렇게 가져온 파일은 모두 단일 CSS 파일로 병합되어 출력 됩니다.

SCSS
1
2
3
4
// style.scss
@import "reset.scss";
@import "common.scss";
@import "layout.scss";

위의 구조를 컴파일하는 경우 reset, common, layout을 합쳐놓은 style이 컴파일 됨과 동시에 reset, common, layout모두 css파일로 함께 컴파일 됩니다.

partial(파일분할)

규모가 큰 서비스라면 파일단위로 나누어 관리하는 것이 더 편리할 수 있습니다. 단독으로 사용되지 않는 파일들은 파일 이름 앞에 ‘_’를 붙여 작성하면 컴파일하지 않습니다.

SCSS
1
2
3
4
// style.scss
@import "_reset.scss";
@import "_common.scss";
@import "_layout.scss";

위의 구조라면 reset, common, layout을 합쳐놓은 style만이 컴파일 됩니다.

컴파일 도구에서도 컴파일 되지 않을 파일들을 설정할 수 있지만 파일의 이름만으로 구조와 목적을 이해할 수 있다는 점을 생각하면 파일명에 ‘_’를 붙여 사용하는 것이 좋습니다.


4. 확장(extend)

@extend 디렉티브는 정의 되어 있는 셀렉터(플레이스홀더)의 속성을 그대로 가져옵니다.

SCSS
1
2
3
4
5
6
7
8
// placeholder는 @extend될때만 사용
.box{
border:1px solid red;
}

.block{
@extend .box;
}
컴파일 된 CSS
1
2
3
.box, .block {
border: 1px solid red;
}


placeholder

셀렉터는 아니지만 속성과 값을 정의해놓은 것으로 이름의 앞에 “%“ 를 붙여 작성합니다.
셀렉터가 아니기 때문에 @extend 디렉티브를 통해 사용하는 경우에만 출력 됩니다.

SCSS
1
2
3
4
5
6
7
8
// placeholder는 @extend될때만 사용
%box{
border:1px solid red;
}

.block{
@extend %box;
}
컴파일 된 CSS
1
2
3
.block {
border: 1px solid red;
}


5. 흐름제어

조건문(@if, @else if, @else)

조건문은 조건 식이 참인 경우 블록의 내용을 포함시킵니다.

SCSS
1
2
3
4
5
6
7
8
9
10
11
$width: 300px;

.block{
@if $width < 200 {
width: 200px;
} @else if $width < 250 {
width: 250px;
} @else {
width: $width;
}
}
컴파일 된 CSS
1
2
3
.block {
width: 300px;
}


@for

@for는 순차적으로 반복되는 작업에 사용합니다.

SCSS
1
2
3
4
5
@for $i from 1 through 2 {
.list#{$i} {
background-image:url(img/bg-list#{$i}.jpg);
}
}
컴파일 된 CSS
1
2
3
4
5
6
7
.list1 {
background-image: url(img/bg-list1.jpg);
}

.list2 {
background-image: url(img/bg-list2.jpg);
}


@each

@each는 javascript의 for in문과 유사한 형태로 리스트를 순회하여 반복 합니다.

SCSS
1
2
3
4
5
6
7
$animals: (puma, sea-slug, egret, salamander);

@each $animal in $animals {
.#{$animal}-icon {
background-image: url('/images/bg-#{$animal}.png');
}
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.puma-icon {
background-image: url("/images/bg-puma.png");
}

.sea-slug-icon {
background-image: url("/images/bg-sea-slug.png");
}

.egret-icon {
background-image: url("/images/bg-egret.png");
}

.salamander-icon {
background-image: url("/images/bg-salamander.png");
}


@while

@while은 조건이 거짓일때까지 반복되는 반복문 입니다.

SCSS
1
2
3
4
5
6
7
8
9
$i: 3;

@while $i > 0 {
.list#{$i} {
width: 2em * $i;
}
// $i의 값에 -1
$i: $i - 1;
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
10
11
.list3 {
width: 6em;
}

.list2 {
width: 4em;
}

.list1 {
width: 2em;
}


6. 믹스인

mixin(@mixin)

@mixin은 @extend하여 사용하던 것과 유사하지만 매개변수(인자)와 @content를 활용하여 더 사용하면 더 강력한 기능을 제공합니다.
mixin의 선언은 @mixin으로 사용은 @include 디렉티브를 사용합니다.

기본적인 mixin의 사용
SCSS
1
2
3
4
5
6
7
8
9
10
11
@mixin section {
width:200px;
height:200px;
&.on{
border:1px solid red;
}
}

.section{
@include section;
}
컴파일 된 CSS
1
2
3
4
5
6
7
.section {
width: 200px;
height: 200px;
}
.section.on {
border: 1px solid red;
}


매개변수를 이용한 mixin의 사용
SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 매개변수 선언 시 값을 넣으면 기본 값으로 사용되며 값이 null인 경우에는 선언되지 않습니다.
@mixin section($width, $height:200px, $border:null) {
width:$width;
height:$height;
border:$border;
}

.section1{
// 매개변수는 변수명 없이 순서대로 넣거나
@include section(100px, 100px);
}
.section2{
// 매개변수는 변수명을 포함하여 순서에 상관없이 넣을 수 있습니다.
@include section($height:50px, $width:100px, $border:1px solid red);
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
10
.section1 {
width: 100px;
height: 100px;
}

.section2 {
width: 100px;
height: 50px;
border: 1px solid red;
}


가변인수

인수의 갯수가 불확실한 경우 사용할 수 있으며 가변 인수는 매개변수 뒤에 ‘…’을 붙여줍니다.

SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@mixin font ($style: normal, $weight: normal, $size: 16px, $family: sans-serif) {
font: {
style: $style;
weight: $weight;
size: $size;
family: $family;
}
}

.text1{
// 매개변수 순서와 개수에 맞게 전달
$font-values: italic, bold, 16px, sans-serif;
@include font($font-values...);
}
.text2{
// 필요한 값만 키워드 인수로 변수에 담아 전달
$font-values: (style: italic, size: 22px);
@include font($font-values...);
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
.text1 {
font-style: italic;
font-weight: bold;
font-size: 16px;
font-family: sans-serif;
}

.text2 {
font-style: italic;
font-weight: normal;
font-size: 22px;
font-family: sans-serif;
}

가변으로 선언한 인수는 그 자체로 리스트로 인식됩니다.

SCSS
1
2
3
4
5
6
7
8
9
10
11
12
@mixin make-list($args...){
// 리스트로 인식되기 때문에 @each를 사용할 수 있음
@each $i in $args {
&.list#{$i} {
background-image:url(img/bg-list#{$i}.jpg);
}
}
}

li{
@include make-list(1, 2, 3, 4);
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
10
11
12
li.list1 {
background-image: url(img/bg-list1.jpg);
}
li.list2 {
background-image: url(img/bg-list2.jpg);
}
li.list3 {
background-image: url(img/bg-list3.jpg);
}
li.list4 {
background-image: url(img/bg-list4.jpg);
}


mixin안에서 mixin의 사용
SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@mixin section($width:200px, $height:200px) {
width:$width;
height:$height;
// 먼저 선언되지 않아도 참조할 수 있습니다.
@include border;
}
@mixin border($color:red) {
border:1px solid $color;
}

.section1{
@include section(100px, 100px);
}
.section2{
@include section($height:50px, $width:100px);
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
10
11
.section1 {
width: 100px;
height: 100px;
border: 1px solid red;
}

.section2 {
width: 100px;
height: 50px;
border: 1px solid red;
}


7. 함수

함수는 mixin과 달리 (지정된 스타일이 아님) 을 @return 디렉티브를 통해 반환 합니다.

SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@function half($num) {
@return $num / 2;
}

div{
position:absolute;
left: 50%;
top: 50%;
width:300px;
height:300px;
margin:{
left: -(half(300px));
top: -(half(300px));
}
}
컴파일 된 CSS
1
2
3
4
5
6
7
8
9
div {
position: absolute;
left: 50%;
top: 50%;
width: 300px;
height: 300px;
margin-left: -150px;
margin-top: -150px;
}


참고