SASS(SCSS)
소개 전처리기(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의 모든 기능을 지원하는 것이 특징
표기법에 따른 차이 점의 예
SASS1 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)
SCSS1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @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); } } }
환경 설정 컴파일 하기
cli를 이용(ruby, node등)
어플리케이션 번들러를 사용(webpack, parcel, gulp, grunt 등)
web app (EX> https://www.sassmeister.com )
gui를 이용(EX> http://koala-app.com )
디버깅
소스맵
컴파일 과정을 거친 코드는 그 자체로 알아보기 힘들다는 문제가 있음
이러한 문제를 해결하기 위해 대 부분의 최신 전처리기들에는 일명 소스맵(source map)이라고 불리는 기능을 지원
소스맵이란 컴파일 된 파일과 그 소스 사이의 관계를 만들어주는 역활을 하는 것으로 JSON 기반 매핑 형식으로 작성
소스맵의 사용 예(크롬)
크롬에서 소스맵을 사용하지 않은 경우 사진과 같이 컴파일된 css의 위치만 확인할 수 있음
소스맵이 존재하는 경우 .scss의 경로를 안내
1. 주석
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 { 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 ; 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
!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 @import "reset.scss" ; @import "common.scss" ; @import "layout.scss" ;
위의 구조를 컴파일하는 경우 reset, common, layout을 합쳐놓은 style이 컴파일 됨과 동시에 reset, common, layout모두 css파일로 함께 컴파일 됩니다.
partial(파일분할) 규모가 큰 서비스라면 파일단위로 나누어 관리하는 것이 더 편리할 수 있습니다. 단독으로 사용되지 않는 파일들은 파일 이름 앞에 ‘_’를 붙여 작성하면 컴파일하지 않습니다.
SCSS 1 2 3 4 @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 .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 %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 : $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 @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 $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 ; }
참고