SASS 간단정리

SASS

문법

모든 문법 작성은 SCSS 기준으로 작성한다.

규칙 네스팅

중괄호 속에 하위 요소에 대한 스타일을 지정하는 형태로 네스팅한다.

#main p {
    color: #00ff00;
    width: 79%;

    .redbox {
        background-color: #ff0000;
        color: #000000;
    }
}

// complied:

#main p {
    color: #00ff00;
    width: 79%;
}

#main p .redbox {
    background-color: #ff0000;
    color: #000000;
}

상위요소 참조

블럭 내에서 &를 사용하면, 블럭의 주인 즉 현재 스코프의 부모 요소를 참조하게 된다.

#main {
    color: black;
    a {
        font-weight: bold;
        &:hover { // >> a:hover
            color: red;
        }
    }
}

이는 단순한 치환자의 기능이므로 다음과 같은 조합이 가능하다.

#main {
  color: black;
  &-sidebar { border: 1px solid; }
}

// compiled:

#main { color: black; }
#main-sidebar { border: 1px solid; }

속성 네스팅

font와 같은 속성은 font-family, font-size, font-weight 등의 세부속성으로 나뉘는데, 이들 역시 다음과 같이 분해 가능하다.

.funky {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
}

// compiled:
.funky {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold; 
}

placeholder 셀렉터

%foo 등과 같은 셀렉터를 쓸 수 있는데, 이는 idclass가 될 수 있다. 이 기능은 @extend와 함께 쓰이므로 뒤에서 다시 이야기하기로한다.

#변수

변수 선언

변수는 $변수명: 값;의 형태로 선언과 동시에 적용한다. 이 값은 블럭내에서 쓰이거나 함수나 믹스인에 사용될 때, 값으로 치환된다.

$width: 5em;

.main {
    width: $width;
}

데이터 타입

sass의 데이터타입에는 다음과 같은 것들이 있다.

  • 숫자 : 1, 2 .. 10px도 숫자로 본다.
  • 문자열: 겹따옴표, 홑따옴표, 따옴표가 없는 것 모두 문자열로 인식
  • 색상: blue, #001100, rgba(255, 0, 0, 0.3)
  • 불리언: true, false
  • 널: null
  • 리스트: 괄호속에서 컴마나 공백으로 구분. (1, 2em, 3px, Arial)
  • 맵: (해시) 역시 괄호속에서 키:값 쌍이 괄호로 구분

나누기 기호 (/)

CSS의 속성에서 /기호를 통해 두 값을 같이 쓰는 경우가 있는데 (font: 10px/8px)이 때는 나눗셈을 하지 않는다. 대신 괄호로 둘러싸거나, 변수를 쓰거나,
덧셈이 함께 쓰이거나 하는 경우에는 나눗셈을 한다

p {
    font: 10px/8px; // no div
    $width: 1000px;
    width: $width / 2; // div
    width: round(1.5) / 2; // using function. div.
    height: (500px / 2); // (  ), div.
    margin-left: 5px + 8px / 2px // +, div. 
}

색상 연산

색상은 더하거나 빼거나 곱하고 나누는 것이 가능하다. 그외에 몇가지 색상 관련 함수가 있어서 색상을 특정한 규칙에 따라 변환하는 것이 가능하다.

p {
    color: #110011 + #001100; // #111111;
    color: #010203 * 2; // #020406
    color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
    // rgba(255, 255, 0, 0.75). 투명도는 합산되지 않음.

    $translucentRed: rgba(255, 0, 0, 0.5);
    color: opacify($translucentRed, 0.3); // --> 0.9 (?)
    color: transparentize($translucentRed, 0.25); // --> 0.25
}

문자열 연산

문자열 연산은 기본적으로 합쳐진다. 이 때 - 하이픈 기호는 써넣은 경우 붙여진다. 또한 공백으로 나란히 써진 문자열들은 공백을 포함한 한 덩어리로
취급한다.

따옴표가 없어도 문자열로 취급되지만, 따옴표를 쓰면 내부에 #{ }를 써서 표현식의 결과를 동적으로 삽입할 수 있다.

p {
    cursor: e + -resize; // e-resize
    content: "Foo " + Bar; // "Foo Bar"
    font-family: sans- + "serif"; // sans-serif
    margin: 3px + 4px auto; // 7px auto
    $value: 13;
    content: "I ate #{$value} pies!" // "I ate 13 pies!"
}

이름 치환

위에서 문자열의 표현식을 치환하는 부분은 셀렉터나 속성명에 대해서도 적용이 가능하다.

$foo: bar;
p{
    $fontSize: 12px;
    $lineHeight: 30px;
    font: #{$fontSize}/#{$lineHeight};
    .#{$foo} {
        color: red;
    }
}
// compiled:
p{ font: 12px/30px; }
p.bar { color: red; }

디렉티브

임포트

CSS의 임포트 구문과 동일하다면 css 파일을 임포트한다. 만약 해당 .css 파일이 없거나 미디어쿼리나 url함수가 쓰이지 않은 CSS 표준 임포트 구문이 아니라면 scss 파일이나 sass 파일을 임포트하게 된다.

네스티드 임포트

블럭내에서 @import 지시어를 쓰면 파일의 최상위 레벨 셀렉터의 내용을 가져온다.

.example { color: red; }
.main {
    @import "example";
}
// compiled:
.main .example {
    color: red;
}

미디어쿼리

…는 다음 기회에

확장

@extend 지시어는 다른 곳에서 정의한 셀렉터의 스타일을 그대로 가져온다. 즉 상속받는다. @import는 다른 곳에서 정의한 셀렉터를 현재 블럭의 부모의 하위로 들여오는 것임에 비해 @extend는 상속의 개념으로 이해하면 된다.

.error {
    border: 1px #f00;
    background-color: #fdd;
}
.seriousError {
    @extend .error;
    border-width: 3px;
}

한 셀렉터의 블럭 내에서 다른 여러 셀렉터를 상속받는 것도 가능하며, 이렇게 다른 셀렉터를 상속받은 셀렉터를 다시 제3의 셀렉터에서 상속받는 체인닝도 가능하다.

연속 시퀀스

.foo .bar.foo + .bar와 같은 셀렉터 시퀀스를 상속할 수는 없다. 하지만 반대로 이들 연속 시퀀스는 다른 셀렉터를 상속받을 수는 있다.

.link .fake-links {
    @extend a;
}
a {
    color: blue;
    &:hover {
        text-decoration: underline;
    }
}

사실 이러한 상속은 상속이라기보다는 병합에 가깝다.

플레이스 홀더

좀 어렵다. 플레이스홀더는 컨텍스트를 정의한다.

#context a%extreme {
    color: blue;
    font-weight: bold;
    font-size: 2em;
}
.notice {
    @extend %extreme;
}
// compiled:
#context a.notice {
    color: blue;
    font-weight: bold;
    font-size: 2em;
}

플레이스홀더로 지정한 셀렉터는 그 자체로 렌더링되지 않고, 이후 자신을 상속하는 셀렉터에만 효력을 가진다. 또한, 그 상속하는 대상이 플레이스 홀더에 들어가게 된다.

@at-root

이는 네스팅 블럭내에서 최상위 계층 셀렉터를 정의하고자 할 때 쓴다. (특정 셀렉터의 계층 위치에 따른 속성을 비슷한 위치에서 정의할 때 쓴다.)

.parent{
    @at-root {
        .child1 { ... }
        .child2 { ... }
    }
    ...
}
// compiled:
.parent {...}
.child1 {...}
.child2 {...}

흐름제어 디렉티브

if() / @if

@if는 블럭내에서 조건식이 참이면 자신의 블럭의 내용을 포함시킨다. 물론 @else if, @else도 사용가능하다.

@else if 에 공백이 있음을 유의

@for

@for는 순차적인 값에 대해서 사용한다.

@for $i from 1 through 3 {
    .item-#{$1} {
        width: 2em * $i;
    }
}

와 같이 만들 수 있다. 이 때 범위 표현은 from 1 to 3으로 쓸 수도 있다.

@each

@each는 리스트나 맵의 각 값을 순회한다. 날씨가 더워지니 요점만 간단히

  • 리스트 순회 방법은 동일하니 패스
  • 맵의 경우 변수를 $키, $값으로 준다.
  • 만약 리스트의 리스트라면 언팩킹이 가능하다.

예제

@each $animal in puma, sea-slug, egret, salamander {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
  }
}

@each $animal, $color, $cursor in (puma, black, default),
                                  (sea-slug, blue, pointer),
                                  (egret, white, move) {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
    border: 2px solid $color;
    cursor: $cursor;
  }
}

@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
  #{$header} {
    font-size: $size;
  }

위와 같이 쓰면 되니 참고.

@while

별다른 설명은 필요없고 예제로.

$i: 6;
@while $i > 0 {
    .item-#{$i} { width: 2em * $i; }
    $i: $i - 2;
}

간단하다.

믹스인

대망의 믹스인이다. 믹스인은 여러 곳에 쓰일 수 있는 sass 코드 조각에 이름을 붙인 것이다.
믹스인은 정의할 때 파라미터를 함께 정의할 수 있고 (파이썬처럼, 기본값을 붙여줄 수도 있다) 호출할 때, 키:값의 형태로 파라미터를 쓸 수 있다. 마치 믹스인 자신의 컴파일 결과를 돌려주는 함수라 생각하면 된다.

정의방법은 다음과 같고

@mixin 이름 [($파라미터[:디폴트값] ,....)] {
    ...
}

사용할 때는 @include 믹스인이름; 으로 쓴다.

예제 1. 단순 믹스인

@mixin silly-links {
  a {
    color: blue;
    background-color: red;
  }
}

@include silly-links;

예제 2. 믹스인 내에서 다른 믹스인 쓰기

@mixin compound {
  @include highlighted-background;
  @include header-text;
}

@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }

예제3. 파라미터 있는 믹스인

@mixin sexy-border($color, $width) {
  border: {
    color: $color;
    width: $width;
    style: dashed;
  }
}

p { @include sexy-border(blue, 1in); }

다중 파라미터 믹스인

다중 파라미터 믹스인의 파라미터는 그 자체가 리스트로 인식된다.

@mixin make-list($args...){
  @each $i in $args {
    .item-#{$i} {
      font-size: 1em * $i;
    }
  }
}

p {
  @include make-list(1, 2, 3, 4);
}

이는 아래와 같이 컴파일된다…

p .item-1 {
  font-size: 1em;
}
p .item-2 {
  font-size: 2em;
}
p .item-3 {
  font-size: 3em;
}
p .item-4 {
  font-size: 4em;
}

함수

믹스인의 기능이 매우 활용도가 높긴하지만, 사용성 측면에서는 매번 @include 디렉티브를 써야 한다는 점이 번거롭다. 그래서 함수 등장~

$gridWidth: 40px;
$gutterWidth: 10px;
@function grid-width($n) {
    @return $n * $gridWidth + ($n - 1) * $gutterWidth;
}

#sidebar { width: grid-width(5); }

몇몇 함수 목록

http://sass-lang.com/documentation/Sass/Script/Functions.html

함수의 양이 많다면 많고, 적다면 적은데, 분류 별로 살펴두면 유용할 듯 싶다. 특히 컬러 관련 함수는 단순한 색상 계산을 번거로움을 줄여준다.

참고로, 괄호가 비어있으면 관련된 타입의 데이터만 넣는 것이다. 보다 정확한 정보는 직접 문서를 찾아보자.

색상함수

  • rgb($red, $green, $blue)
  • rgba($red, $green, $blue, $alpha)
  • red($color), green(), blue()
  • mix($c1, $c2, [$weight])
  • hsl($hue, $saturation, $lightness), hsla()
  • hue($color), saturation(), lightness()
  • adjust-hue($color, $degree)
  • lighten($color, $amount)
  • darken($color, $amount)
  • saturate($color, $amount)
  • desaturate($color, $amount)
  • grayscale($color)
  • complement($color) : 보색을 찾아준다.
  • invert($color)
  • alpha($color)
  • rgba($color, $alpha)
  • opacify($color, amount) / fade-in($color, $amount)
  • transparentize(), fade-out()

문자열 함수

  • unquote(), qoute()
  • str-length()
  • str-insert($string, $insert, $index)
  • str-index($string, $substring)
  • str-slice($string, $start-at, [$end-at])
  • to-upper-case(), to-lower-case()

숫자

  • percent()
  • round()
  • ceil()
  • floor()
  • abs()
  • min($numbers…)
  • max($numbers…)
  • random($numbers…)

리스트

리스트 함수는 중요한데, sass 문법 자체는 리스트로 뭘 어찌 해볼 수 있는게 없기 때문이다.

  • length()
  • nth($list, $n)
  • join($list1, $list2)
  • append($list, $value)
  • zip($lists….) : 파이선의 zip 함수와 동일하다.
  • index($list, $value)
    :

  • map-get($map, $key)
  • map-merge($map1, $map2)
  • map-remove($map, $key)
  • map-keys($map) : 키들을 리스트로 반환
  • map-values($map)
  • map-has-key($key)
  • keywords($args)
  • Pingback: Feedly – SASS 간단정리 | Wireframe | HGW XX/7()

  • Pingback: Michael Kwon | sass – 설치하기(Window)()

  • Bratt Park

    안녕하세요..
    잘은 모르지만 정리를 잘해놓으신듯..합니다.. ^^;

    지금 foundation 5로 홈페이지 제작하려고 시도 하고 있습니다만..
    sass를 이용하는게 더욱 편리하게 생각 되서 어렵사리 설치를 하고 코딩을 시작 하려 하는데 앞이 캄캄해서요.. 혹시 전문가이신듯 한데… 좀 배울수 있을까요? 물론 수업료는 지불 해드리구요..
    ㅜㅜ;

    부탁좀 드리고 싶습니다~

    • 제가 뭔가 가르쳐드릴만큼 전문가는 아니구요 ^^;; 시간적으로 여유가 없어서 실질적으로는 도와드리기 어려울 듯 합니다. Foundation 5 같은 UI 프레임워크는 반응형 UI 설계 구현을 보다 적은 코딩으로 할 수 있도록 미리 클래스라든지 이런 것들을 구현해놓은 걸 말합니다. 저도 파운데이션을 안써봐서 자세히는 모르지만, 내부적으로는 SASS를 써서 CSS 관리를 하는 걸로 알고 있습니다.

      CSS를 작성하다보면 중복되는 스타일 선언들이 굉장히 많아지게 되는데요, SASS는 이런 중복되는 코드들을 재사용할 수 있는 단위로 묶어서 코드를 쓰면 이걸 평범한 CSS로 치환해주는 전처리기 입니다. 비슷한 기능을하는 약간 다른 LESS라는 것도 있구요 (LESS를 더 많이 쓰는 것 같습니다만… )

      따라서 시간적으로 여유가 많이 없음 + 제작하려는 사이트가 그리드 모양에 거의 들어맞고 반응형 UI를 적용해야함. 이런 조건이시라면 일일이 모든 CSS와 UI 효과 관련 스크립트를 직접 만드시는 것 보다, UI 프레임워크를 도입해서 쓰시는 편이 좋을 것 같습니다.