CSS를 작성하는 더 편한 방법: LESS와 SASS

프로그래밍 언어를 다루는 입장에서 보기에 HTML 마크업과 CSS라는 분야는 굉장히 번거로운 작업처럼 보인다. 같은 내용을 몇 번이고 입력해야하는데 그 방법이라는게 복붙(Copy&Paste)밖에 없다. 더군다나 최근처럼 CSS 파일 하나에 1000라인쯤은 훌쩍 넘기는 일이 많아지는 경우에는 이런 성질이 굉장히 귀찮게 보였다.

다행히 이런 생각을 나만 한 것은 아니었나보다. 오래 전부터 이런 문제를 해결하려는 노력이 있어왔고 오늘 소개할 두 개의 프로젝트, LESSSASS도 그런 노력의 결과이다. 두 프로젝트에서 제공하는 여러 요소를 살펴보고, 각자의 장단점을 비교해보았다.

CSS 변환

어찌보면 당연한 것이지만, 두 방식 모두 CSS를 보다 편리하게 작성하기 위한 몇 가지 추가 문법을 제공하고 이렇게 작성한 코드를 CSS로 변환하는 기능을 제공한다. 심지어 LESS의 경우, 자바스크립트 파일을 하나 읽어들이면 .less 파일을 그대로 사용할 수도 있다(물론 권장하는 방법은 아니다).

LESS는 NodeJS를 엔진으로 사용하는데 NodeJS 설치 후 간단하게 다음 명령어를 실행하면 관련 모듈과 변환기가 설치된다(그러나 자바스크립트로 작성된 프로그램이라 Rhino 엔진에서도 실행된다).

$ npm install less

작성한 LESS 문법에 따라 코드를 작성한 후 이를 CSS 파일로 변환하려면 명령행에서 다음과 같이 실행한다.

$ lessc style.less & style.css

SASS는 Ruby 언어로 작성된 변환기가 있고 역시 다음과 같은 명령어를 사용해 간단하게 설치할 수 있다.

$ gem install sass

SASS 파일을 CSS로 변환할 때는 다음과 같은 명령어를 사용한다.

$ sass style.scss:style.css

특이한 점은 --watch 옵션을 사용하면 .sass 파일이 변경될 때마다 자동으로 .css 파일로 변환해준다는 것이다.

$ sass --watch style.scss:style.css

변수

임의의 변수를 선언할 수 있으며 선언하는 방법과 사용하는 방법은 비슷하지만, LESS는 변수의 접두어로 @를 사용하고 SASS는 $를 사용한다는 점이 다르다. 예를 들어, LESS에서는 다음과 같이 변수를 사용한다(@를 $로만 바꾸면 SASS에서도 같은 결과를 반환한다).

@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;

#header { color: @light-blue; }

위의 코드는 16진수로 표현된 색상에 특정 값을 더했다. 이 코드를 CSS로 변환하면 다음과 같다.

#header { color: #6c94be; }

SASS에서는 !default 플래그를 사용해 값이 정의되지 않은 경우에만 사용할 값을 정의할 수도 있다.

@content : "First";
@content : "Second" !default;

#main { content : @content; }

위 코드를 컴파일하면 content 속성의 값은 “First”가 되는데 @content 변수에 “Second”를 할당할 때는 이미 값이 정의되어 있었기 때문이다.

반면, LESS에서만 제공하는 기능으로는 유효 범위(scope)가  있다. 예를 들어, 다음과 같은 코드가 있다고 하자.

@color : red;
#header {
    @color : blue;
    border: 1px solid @color;
}
#footer {
    border: 1px solid @color;
}

@를 $로 바꾸면 SASS용 코드도 된다. 하지만 LESS에서 컴파일한 CSS와 SASS에서 컴파일한 결과는 서로 다른데, LESS에서는 #header 블럭 안에서 정의한 변수가 전역 변수에 영향을 미치지 않기 때문이다. 반면, SASS에서는 전역/지역 변수의 구분이 없기 때문에 세 번째 줄의 코드를 실행하면 첫 번째 줄에서 정의한 @color의 값이 blue로 변경된다.

다음은 위의 코드를 각각 LESS와 SASS에서 컴파일한 결과이다.

/* LESS */
#header { border: 1px solid blue; }
#footer { border: 1px solid red; }

/* SASS */
#header { border: 1px solid blue; }
#footer { border: 1px solid blue; }

계산과 함수

앞의 예제에서 보듯 변수의 뺄셈을 포함한 사칙 연산이 가능하다. 뿐만 아니라 많지는 않으나 CSS에서 사용하기에는 충분한 정도의 유용한 함수도 제공한다. 예를 들어 10% 밝은 파란색을 원한다면 다음과 같이 작성할 수 있다.

#header { color : lighten(blue, 10%) }

LESS나 SASS가 제공하는 함수의 종류나 사용법은 거의 유사하지만 SASS가 조금 더 많다.

선택자 상속

SASS에서만 제공하는 기능으로서, 앞서 정의한 CSS 규칙에 선택자를 추가해주는 기능을 한다.

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

위 코드를 컴파일하면 다음과 같다.

.error, .seriousError {
    border : 1px solid red;
    background-color : #fdd;
}
. seriousError {
    border-width : 3px;
}

중첩 규칙

선택자를 중첩하여 상위 선택자를 반복 입력하지 않아도 되는 기능이다(개인적으로 다른 어떤 기능보다 CSS에 도입이 필요하다고 생각한다). 두 방식 모두 다음과 같은 문법을 지원한다.

#header {
  h1 {
    font-size: 26px;
    font-weight: bold;
  }
  p { font-size: 12px;
    a { text-decoration: none;
      &:hover { border-width: 1px }
    }
  }
}

이 코드를 CSS로 컴파일하면 다음과 같다.

#header h1 {
  font-size: 26px;
  font-weight: bold;
}
#header p {
  font-size: 12px;
}
#header p a {
  text-decoration: none;
}
#header p a:hover {
  border-width: 1px;
}

특이한 부분은 수도 클래스(:hover)처럼 부모 선택자를 참조해야하는 경우에는 부모 선택자를 &로 참조한다는 점이다 (&:hover 부분).

LESS와 달리 SASS에서는 CSS 속성 이름도 중첩이 가능하다.

.fakeshadow {
  border: {
    style: solid;
    left: {
      width: 4px;
      color: #888;
    }
    right: {
      width: 2px;
      color: #ccc;
    }
}

위 코드를 CSS로 변환하면 다음과 같다.

.fakeshadow {
  border-style: solid;
  border-left-width: 4px;
  border-left-color: #888;
  border-right-width: 2px;
  border-right-color: #ccc;
}

주석

주석으로는 원래 CSS에서 제공하는 /* ... */ 블럭 주석 외에 // 한 줄 주석을 추가로 제공한다. 단, 블럭 주석은 컴파일된 CSS에서 그대로 표현되는 반면, 한 줄 주석은 사라진다. LESS에서는 한 줄 주석을 가리켜 침묵(slient) 모드라고 한다. 다음은 간단한 LESS 코드이다.

/* Header */
h1 { font-size:1.5em }

// paragraph (침묵 모드)
h2 { font-size:1.3em }

위 코드를 컴파일하면 다음과 같다.

/* Header */
h1 { font-size:1.5em }

h2 { font-size:1.3em }

믹스인(Mixin)

미리 정의한 코드를 CSS 정의 안에 포함시키는 기능이다. LESS는 CSS를 클래스를 선언하는 문법과 거의 유사하게 믹스인을 정의하는 반면, SASS에서는 @mixin이라는 특수한  키워드를 사용하여 믹스인을 정의한다. 믹스인을 포함시킬 때도 LESS는 믹스인의 이름을 그대로 사용하는 반면, SASS는 @include라는 키워드를 사용한다. 예를 들어, 다음은 모서리를 둥글게 만드는 SASS 코드이다.

@mixin rounded ($radius: 10px) {
  border-radius : $radius;
  -moz-border-radius : $radius;
  -webkit-border-radius : $radius;
}

#navbar li { @include rounded; }
#footer { @include rounded; }

이 코드를  CSS로 변환하면 다음과 같다.

#navbar li {
  border-radius: 10px;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
}

#footer {
  border-radius: 10px;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
}

위의 코드를 LESS로 작성하면 다음과 같다.

.rounded (@radius : 10px) {
  border-radius: @radius;
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
}

#navbar li { .rounded; }
#footer { .rounded; }

그리고 두 방식 모두 믹스인에 인수를 전달하여 사용할 수 있다.

#navbar li { @include rounded(5px); } /* SASS */
#footer { .rounded(5px); } /* LESS */

여기에 기능 상의 차이가 약간 있는데 SASS의 경우는 속성 이름에도 변수를 사용할 수 있다는 장점이 있다.

@mixin rounded-top {
    $radius : 10px;
    $side : top;

    border-#{$side}-radius : $radius;
    -moz-border-#{$side}-radius : $radius;
    -webkit-border-#{$side}-radius : $radius;
}

반면, LESS에는 @argument라는 특수한 변수가 있어 인수가 많을 때 일일이 입력하지 않아도 된다는 장점이 있다.

.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
 box-shadow: @arguments;
 -moz-box-shadow: @arguments;
 -webkit-box-shadow: @arguments;
}
.box-shadow(2px, 5px);

임포트(import)

CSS로 컴파일 할 때 외부의 LESS 또는 SASS 파일을 읽어들인다.

@import "lib"; /* LESS and SASS */
@import "lib.less"; /* LESS */
@import "lib.css"; /* LESS */

SASS는 확장자가 없는 형태만을 허용하는 반면, LESS는 .less 파일은 물론 .css 파일도 지원한다.

문자열

두 방식 모두 문자열 타입이 존재하며 다음과 같이 변수에 문자열을 저장할 수 있다.

@base-url: "https://taegon.kim"; /* LESS */
$base-url: "https://taegon.kim"; /* SASS */

그리고 위에서 정의한 값을 문자열에 다음과 같이 삽입할 수 있다.

h1 { background:url("@{base-url}/images/bg.png"); } /* LESS */
h1 { background:url("#{$base-url}/images/bg.png"); } /* SASS */

위의 코드를  CSS 로 변환하면 다음과 같다.

h1 { background:url("https://taegon.kim/images/bg.png"); }

단, SASS에서는 다음과 같이 + 연산자를 사용한 방식도 가능하다.

h1 { background:url($base-url + "/images/bg.png"); } /* SASS */

제어문

SASS에서만 제공하는 기능으로 @if / @else 조건문, @for / @each / @while 반복문을 제공한다. 다음은 조건문의 예제이다.

$type: monster;
p {
  @if $type == ocean {
    color: blue;
  } @else if $type == matador {
    color: red;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}

@if 키워드 다음에는 괄호가 없으며, { … } 블럭은 반드시 사용해야 한다. 위 코드를 컴파일하면 다음과 같다.

p { color: green; }

보다 자세한 내용은 SASS 온라인 문서를 참고하면 된다.

이스케이프

LESS에서만 제공하는 기능으로 .less 파일에 LESS 문법에서는 유효하지 않은 코드가 포함되어 있을 경우 해당 코드를 해석하지 않도록 만드는 방법이다. 해석하지 않을 코드를 문자열로 묶고 문자열 앞에 ~ 기호를 붙이면 된다.

.class {
    filter: ~"ms:alwaysHasItsOwnSyntax.For.Stuff()";
}

이 코드는 다음과 같이 CSS로 변환된다.

.class {
    filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
}

자바스크립트 실행

LESS에서는 자바스크립트 코드를 실행하고 그 값을 변수 등에 사용할 수 있다. 사용법은 간단하다. 실행할(정확한 용어로는 ‘평가할’=evaluate) 자바스크립트 코드를 문자열을 감싸듯 백틱 기호(backtick, `)로 감싸면 된다. 예를 들어, 다음과 같은 코드가 있다고 가정하자.

@hi : `"hello".toUpperCase() + "!"`;

이 코드는 사실 다음 코드와 같다고 볼 수 있다.

@hi : "HELLO!";

만약 .less 파일을 변환하지 않고 웹 브라우저에서 바로 사용한다면 다음과 같은 방법으로도 사용할 수 있다.

@height : `document.body.clientHeight`;

결론

지금까지 두 언어(?)의 공통점과 차이점을 살펴보았다. 개인적인 취향으로는 자바스크립트로 작성된 LESS를 선호하지만, SASS 역시 많은 장점을 지닌 언어이다. SASS의 장점은 다양한 기능과 상대적으로 잘 정리된 문서이며(개발자가 참조하기 편한 형태이다), LESS는 변환 과정을 거치지 않고 웹 브라우저에서 바로 사용할 수 있다는 점, 자바스크립트를 평가한 결과를 사용할 수 있다는 점이 강점이다. 변환기를 작성한 언어도 서로 다른데 루비를 선호하는 개발자라면 SASS를, 자바스크립트를 선호하는 개발자라면 LESS를 더 선호할 것이다.

어떤 도구를 선택하든 그것은 자유지만, 만약 여러분이 직접 CSS를 코딩하는 사람이라면 둘 중 무엇이라도 사용해보기를 권장한다. 아무런 도구없이 바닥부터 작성하기에는 CSS 자체의 스펙도 많이 증가했고, 웹 사이트에서 필요로 하는 CSS도 많아지고 복잡해져 개발은 물론 유지보수에도 많은 노력을 필요로 하기 때문이다. LESS와 SASS는 이미 여러 프로젝트에서 사용 중인데 특히 LESS는 트위터에서 공개한 Bootstrap 프로젝트에도 사용된 바 있다.

LESS는 아파치 라이선스를, SASS는 MIT  라이선스를 따른다.

업데이트 2017-03-09: 이 글을 처음 작성하고 거의 5년이 지난 현재 프론트엔드 개발에 있어 이러한 CSS 전처리 도구는 거의 필수가 되었다해도 과언이 아니다. 그 사이 SASS도 훌륭한 Node.js 변환기가 있으며 많은 프로젝트에서 사용되고 있다. 또한 위에서 언급한 Bootstrap 프로젝트는 LESS와 SASS를 동시에 지원한다. 앞서 LESS를 더 선호했던 이유는 SASS도 현재 지원하고 있으며 내가 사용하는 환경에서는 SASS가 오히려 우세라 현재는 SASS를 더 많이 다루고 있다. 개인적인 선호도 현재는 SASS쪽으로 기울어진 상태가 되었다.

  1. 태곤님께서 LESS와 SASS를 적용해보신 경험이나 선호하는 것이 있으신가요^^?
    저는 아직 실제 적용해보지는 않았지만 LESS를 사용해보려고 합니다(막연하지만 좀 더 눈이 가네요).

    1. 저도 개인적으로 LESS를 선호합니다. LESS의 경우 less.js를 다운로드 받아서 포함시키면 .less 파일을 웹 페이지에 바로 사용할 수도 있는데, 개발할 때 CSS를 계속 수정해야 하는 상황에서는 꽤 편리한 기능입니다. 문법도 왠지 LESS쪽이 더 익숙해보이더라고요. :)

  2. 우왕~ 좋은 정보 감사합니다.
    css도 프로그래밍하는 시대가 도래했군요!!
    bootstrap 들어갔다가 less 라는 게 있길래 검색해봤는데
    많이 배우고 갑니다~

  3. bootstrap에 less가 있어서 뭔지 찾다 왔습니다.
    요즘 MS프로젝트라 타입스크립트 쓰고 있는데.. 이것도 골치아픈데..
    또 공부해야하다니… 그냥 안하렵니다.^^
    대중화가 되면.. 그 때 찾아보려구요 ~
    나중에 시간되시면 장단점좀 비교 부탁드려요

Leave a Reply