Sass

CSS preprocessor

CSS는 쉽고 간단하게 HTML을 디자인하는 언어이다. 태그를 선택하고, 선택된 태그를 꾸며주는 단순한 원리를 가지고 있다. 그러나 규모가 커질수록 CSS 유지보수가 어렵다.

자바스크립트와 같은 동적인 언어들은 변수나 함수를 이용해 코드 재활용성을 높여주고 소스 양을 줄여주는데 CSS는 갈수록 길어지기만 한다.

이런 CSS의 태생적 한계를 극복하고자 CSS preprocessor, 즉 CSS 전처리 도구들이 생겨났다.

이들은 CSS에 변수, 함수, 확장/상속 등의 기능을 추가해 CSS를 좀 더 체계적으로 사용할 수 있게 도와주는 도구이다.

CSS preprocessor 종류

Less, Sass, Stylus, CSS-Crush, Myth, Rework 등등 생각보다 많은 CSS preprocessor 가 존재한다.

이중 가장 많이 사용하는 CSS preprocessor는 Less, Sass, Stylus라고 한다.

less vs. STYLUS vs. Sass

less

  • js로 구동 (기초는 Ruby)
  • 브라우저단에서 동작가능 → 따라서 환경을 갖추기 쉽고 이 이유때문에 LESS를 많이 사용
  • CSS3 작성을 돕는 LESS Hat 라이브러리 제공
  • github repo 기준으로 제일 큰 커뮤니티 보유
  • 3대 CSS preprocessor 중 기능이 제일 적음.

less vs. STYLUS vs. Sass

STYLUS

  • 3대 CSS preprocessor 중 가장 따끈따끈한 녀석
  • js(node.js)로 구동
  • 문법이 굉장히 유연하다 - CSS의 문법 자체를 비틀어 버렸다. 물론 기존에 CSS를 작성하던 방식 그대로도 가능은 하다. 다만 초보자가 접근하기엔 쉽지 않음.
  • CSS3 지원을 도와주는 Nib이라는 라이브러리가 있다.
  • 기능이 막강하다. Sass보다 낫다고 한다.
  • 반면 성숙도는 제일 낮다. 가끔 당황스러운 버그들을 만나게 된다.

less vs. STYLUS vs. Sass

Sass

  • 역사가 제일 오래되었다. 그만큼 성숙도가 높고, 커뮤니티도 크다.
  • 기능이 막강하다. 특히 parent selector의 강력함이 주무기라 한다.
  • ecosystem이 제일 발달되어 있다. Scut, Compass라는 강력한 라이브러리와 함꼐 사용하면 최강이라고 한다.
  • 그외에도 그리드 시스템, 미디어쿼리 제어, 스타일링용 라이브러리 등이 다양하게 준비되어 있다

https://windtale.net/blog/why-i-choose-sass/ 참조

가장 많이 사용하는 CSS preprocessor?

결론적으로 LESS는 3중 가장 접근하기 쉽지만 기능이 제일 떨어진다. 속성 이름 중첩 불가, 믹스인을 지원하기는 하지만 함수로만 사용할 수 있다. 프로그램적 처리가 불가하다.

STYLUS는 아직 해결되지 않은 오류들이 속속히 있다. 게다가 문법이 너무 유연하여 여러사람이 작업하는 경우 작성이 쉽지 않다. 큰 프로젝트에는 부적합하다.

Sass는 ruby셋팅만 배재한다면 친숙한 문법과 강력한 기능으로 무장한 좋은 툴이다. SASS에서는 속성 이름에도 변수를 사용할 수 있다. @if / @else 조건문, @for / @each / @while 반복문을 제공으로 프로그램적 처리가 가능하다.

https://windtale.net/blog/why-i-choose-sass/ 참조

Sass란?

Sass는 문서의 구조를 깔끔하고 구조적으로 기술하는데 사용하는 기술인 CSS의 상위에 있는 메타언어로, 자바스크립트처럼 특정 속성의 값을 변수로 선언하여 필요한 곳에 선언된 변수를 적용할 수도 있고, 반복되는 코드를 한번의 선언으로 여러 곳에서 재사용할 수 있도록 도와주는 일종의 CSS전처리기(pre-processor)이다. 즉, 일반 언어처럼 재사용성을 높이고 활용성을 높여주는 역할을 한다.

https://baepower.wordpress.com/2012/07/31/1장-sass-개요-1-2-sass로-할-수-있는-것들/ 참조

Sass의 메리트

알기쉬운 코드
네스트로 작성이 가능하므로 코드분석이 쉽고, 구조나 모듈의 단위가 알기 쉽다. CSS에는 출력되지 않는 코맨트를 사용해서 내부적인 코맨트를 남겨둘수 있다.
유지보수의 편의
동일한 코드를 호출하도록 해두면 호출당하는 곳의 코드만 변경하는 것만으로 유지보수가 종료된다. 사전에 변경이 예측되는 곳에는 변수를 사용함으로서 원활하게 대응이 가능하다.
코딩작업의 스피드업
동일한 스타일을 반복작성할 필요가 없으므로 작성하는 코드의 양이 줄어든다. 스타일을 컴포넌트화해서 다수의 안건에서 반복사용이 가능하다. 벤터프리픽스는 다 Sass에게 전담을 하기 때문에 CSS3의 지정과 수정도 간단해진다. 16진수(#FFFFFF)를 rgb값(255,255,255)으로 변환이 가능하므로 rgba의 지정이 간단해진다.
표시속도의 개선
CSS를 압축할 수 있어서 파일사이즈를 줄일수 있다. CSS를 하나로 만들수 있으므로 HTTP리퀘스트를 줄일수 있다. CSS Sprites도 간단하게 할 수 있어서 이미지의 리퀘스트수도 줄일수 있다. 복수의 셀렉터를 간단하게 정리할 수가 있어서, CSS 화일 사이즈를 줄일수 있다. 서포트하는 브라우저를 정의하여 불필요한 코드를 출력하지 않도록 함으로서 CSS의 파일사이즈를 줄일 수 있다.

https://baepower.wordpress.com/2012/07/31/1장-sass-개요-1-2-sass로-할-수-있는-것들/ 참조

Sass의 메리트

코드의 재사용
사전에 이름을 붙혀놓은 스타일셋을 사용하고 싶은 곳에서 호출하여 사용할 수 있다.(Sass에서는 이걸 mixin이라고 부른다.) 또한 변수를 사용하여 특정의 값을 이름을 붙혀서 반복사용이 가능해진다.
프로그램 처리
조건분기 등의 반복처리 같은 프로그램 처리가 가능하다.
셀렉터 기술의 간략화
셀렉터의 부자관계를 네스트로 간략하게 표현할수 있다.
효율적인 코멘트
CSS에는 출력되지 않는 Sass파일 안에서만 사용할수 있는 코맨트가 있다.
에러 표시
코드에 실수가 있는 경우, 에러를 알려준다.
파일 머지
복수의 Sass파일을 하나의 CSS파일로 머지시키는게 가능하다.
CSS의 압축
개행이나 들여쓰기, 공백등을 삭제할 수가 있다.

https://baepower.wordpress.com/2012/07/31/1장-sass-개요-1-2-sass로-할-수-있는-것들/ 참조

Sass사용이 적합한 환경

대규모 안건에서 다수의 맴버가 동시에 작업을 진행하는 경우 mixin을 호출하는 작업을 하는 것이라서 전원이 작업하는 코드를 통일화 할 수 있다. 나중에 수정을 하게 되는 경우에도 한 곳이 수정되면 모든 곳이 수정되어 반영된다. 파일을 분할해서 작업하여 하나의 CSS로 합치기 때문에 동시진행으로 작업을 해도 충돌(conflict)발생을 줄일 수 있다.

같은 제작팀에서 CSS 초보자가 있을경우라 해도 소스코드는 간단하여 알기 쉽다. 작성실수가 있을 경우라 하더라도 에러를 알려주기 때문에 디버그가 용이하다. IE대응을 위한 CSS핵을 mixin에 넣어두면 대응법을 모르더라도 자연스럽게 대응할 수 있다. 이렇게 Sass를 사용하게 되면 CSS를 작성할때 귀찮은 부분이라던가 손이 많이 가는 작업으로부터 벚어날 수 있기 때문에 이런 곳에서 얻은 시간을 좀 더 시간을 투자할 부분에 투자할 수 있게 된다. Sass를 도입하는 메리트는 CSS코딩이 지금의 몇배나 즐거워 지는 것에 있지 않나 생각해본다.

https://baepower.wordpress.com/2012/07/31/1장-sass-개요-1-2-sass로-할-수-있는-것들/ 참조

Sass 설치

Sass는 Ruby라는 프로그래밍 언어로 만들어졌습니다.
다시 말하면, 내 PC에서 Ruby라는 언어가 동작해야 Sass를 사용할 수 있다는 말이 됩니다.

그래서 일단은 Ruby를 설치합니다! Mac OS는 Ruby가 기본적으로 설치가 되어 있어서 따로 번거롭게 설치할 필요가 없습니다.
그래서 Ruby 설치가 필요한 Windows 기준으로 설명드립니다.
Link

위 URL을 들어가보시면 다운로드 링크가 여러개 있는데.. 다 skip하시고 아래와 같이 RubyInstallers의 맨 위에 있는 링크를 클릭합니다!

commend 창에서 gem install sass 입력

Sass(CSS Preprocessor) 기초 참조

Sass 문법

문법 규칙 네스팅

규칙
Sass CSS
#main p {
   color: #00ff00;
   width: 79%;

   .redbox {
      background-color: #ff0000;
      color: #000000;
   }
}
#main p {
   color: #00ff00;
   width: 79%;
}

#main p .redbox {
   background-color: #ff0000;
   color: #000000;
}
상위요소 참조
Sass CSS
#main {
   color: black;
   &-sidebar { border: 1px solid; }
}
// compiled:

#main { color: black; }
#main-sidebar { border: 1px solid; }
속성
Sass CSS
.funky {
   font: {
      family: fantasy;
      size: 30em;
      weight: bold;
   }
}
// compiled:
.funky {
      font-family: fantasy;
      font-size: 30em;
      font-weight: bold;
}

Sass 문법

변수 선언

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

$width: 990px;

.main {
   width: $width;
}
.tab li {
   width: $width/4
}

Sass 문법

데이터 타입

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.
}

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

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

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

Sass 연산

색상 연산

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

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
}

Sass 연산

문자열 연산

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

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

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!"
}

Sass

이름 치환

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

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

// compiled:
p{ font: 12px/30px; }
p.bar { color: red; }

Sass

임포트

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

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

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

// compiled:
.main .example {
   color: red;
}

Sass

확장

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

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

Sass

플레이스 홀더

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

@at-root

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

#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;
}

플레이스 홀더

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

Sass

흐름제어 디렉티브

if() / @if

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

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

@for

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

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

흐름제어 디렉티브

@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 믹스인이름;

단순 믹스인

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

@include silly-links;

복합 믹스인

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

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

파라미터 믹스인

@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);
}

Sass

함수

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

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

#sidebar { width: grid-width(5); }
몇몇 함수 목록

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

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

result

Sass를 사용하는 이유는 CSS를 작성할때 귀찮은 부분이라던가 손이 많이 가는 작업으로부터 벗어나기 위함이다.

단발성이라도 Sass를 사용해가다보면 다른 개발자가 오더라도 수정이 쉬워지고 재사용에도 많은 도움이 될 것이다.

Sass 같은 툴을 이용하여 차츰 작업속도를 개선해나가다 보면 이런 곳에서 얻은 시간을 좀 더 시간을 투자할 부분에 투자할 수 있게 되지 않을까 싶다.

참조 Site