Sass 맛보기 #1

예시를 통한 Sass의 사용법


Sass 맛보기는 총 2편의 시리즈로 구성되어 있습니다.

  1. Sass 맛보기 #1 (현재글)
  2. Sass 맛보기 #2


들어가며

순수 CSS로만 작업을 진행하다가 근래 들어 sass를 사용한 운영 프로젝트를 자주 접하게 되면서 기본적인 사용법을 정리해두면 좋을 거 같다는 생각이 들어 개인적으로 공부하면서 겸사겸사 sass 사용법에 대해 아주 살포시 적어보려고 합니다.

글의 순서가 두서없더라도 (어쩔 수 없….) 양해 부탁드립니다. 보고 싶은 거부터 보았거든요…

Comments, Variables, Interpolation

  1. 주석
  2. 변수타입
  3. !default 플래그
  4. !global 플래그
  5. ’#{ }’

1. 주석

@charset "UTF-8"; // 한글 주석 처리 시 꼭 넣어줘야 해요

// 한 줄 -> 컴파일 시 포함되지 않습니다

/*
    블록 주석 처리
    두 줄 이상일 때 블라블라
*/

2. 변수 타입 (전역변수, 지역변수)

$global: #fff; // 전역변수

.main {
  $local: #000; // 지역변수
  background-color: $global; // #fff
  color: $local; // #000
}

전역변수는 말 그대로 상위에 선언해두고 전 클래스에서 사용 가능하며, 지역변수는 클래스 내부에 선언하여 해당 클래스 내부에서만 사용됩니다.

변수 재할당

$white: #fff;

$main-background: $white; // #fff

.main {
  background-color: $main-background; // #fff
}

전역변수로 선언해둔 아이를 필요에 따라 타 전역변수에 담아 사용 가능합니다.

예를 들어 같은 값이지만 용도에 따른 변수명을 설정하여 파일만 확인해도 어디에 사용하기 위한 값인지 보기 더 편할 때가 있겠죠?


3. !default 플래그 (조건부 변수 정의)

부트스트랩과 같은 라이브러리의 Sass를 적용하는 경우 거의 필수로 사용하는 것 같습니다.

!default 플래그는 변수가 정의되지 않았거나 값이 null인 경우 변수에 값을 할당해 줍니다.
(= 변수에 값이 있으면 사용이 안된다는거죠)

// _somelibrary.scss 라이브러리 또는 남 거

$var1: '텍스트' !default;
$var2: #fff !default;
$var3: 30px !default;

.main::before {
  content: $var1; // '텍스트'
  font-size: $var3; // 30px
  color: $var2; // #fff
}

위의 이미 작업 된 파일을 import 해온 후 동일한 변수에 값을 담아 사용하면 !default 값은 변수가 정의되지 않았을 때만 사용되기에 아래와 같이 적용됩니다.

// _customstyle.scss 내 거
@import 'somelibrary';

// $var2는 변수 정의 안 함
$var1: '사용자'; // 변수 정의함
$var3: 24px; // 변수 정의함

.main::before {
  content: $var1; // '사용자'
  font-size: $var3; // 24px
  color: $var2; // #fff
}

4. !global 플래그 (지역 범위 내 전역변수 값 설정 시)

.main {
  $color: #000 !global; // 지역변수가 전역변수로 바뀌는 매직
  color: $color; // #000
}

.sub {
  color: $color; // #000 .main 내부에 선언된 아이를 불러다 쓰는데 이게..됩니다. (!global 플래그 사용 시)
}

.sub2 {
  $color: #fff; // 지역변수
  color: $color; // #fff 동일 변수명일 경우 해당 영역의 지역변수 값 우선 적용합니다
}

5. #{ }

인자나 변수를 받아서 사용 가능하도록 만들어줍니다.
Vue 에서 ${}와 비슷하게 사용된다고 생각하시면 편하실 것 같아요.

// $name을 인자로 받아서 다양한 아이콘을 가진 버튼을 하나의 버튼 스타일 코드로 생성 가능

@mixin button-icon($name, $background, $color) {
  .icon-#{$name} {
    background-color: $background;
    color: $color;
  }
}

@include button-icon('confirm', #000, #fff);


At-Rules

  1. @at-root
  2. @import
  3. @debug, @warn, @error
  4. @use
  5. @forward
  6. @mixin, @include
  7. @function
  8. @extend
  9. @if, @else
  10. @each
  11. @for
  12. @while

1. @at-root

클래스 내부에 있는 콘텐츠지만 최상위로 끌어내서 사용해야 하는 경우 사용됩니다.
(내부 지역변수 사용+최상위 가능)

.main {
  $main-var1: #fff;
  $main-var2: relative;

  position: $main-var2;
  @at-root .sub {
    background: $main-var1; // .main의 지역변수를 사용하면서 최상위로 올려 사용 가능.
  }
}

// 컴파일 후
.main {
  position: relative;
}
.sub {
  background: #fff;
}

2. @import

다들 아시잖아요… (세상 불친절한 설명)

@import '가져올 파일명'; // 단일
@import '가져올 파일명1', '가져올 파일명2', '가져올 파일명3'; // 다수

3. @debug, @warn, @error

@debug는 스타일 사용 시 변수 or 표현 식의 값을 확인하는 용도로 사용합니다.

@warn는 mixin과 function 작업 시 사용자가 인수나 특정 값을 잘못 전달했을 경우 확인할 수 있게 해줍니다.

@debug, @warn의 경우 콘솔창에 직접 출력되며 컴파일 시 표기되지만 @error는 컴파일 자체를 중지하고 실행 중인 시스템에 오류 발생을 알립니다.

$text-var: '텍스트';
$test-var: '디버깅 ' + $text-var;

@debug 'debug value: #{$test-var}' // 디버깅 텍스트
  @mixin prefix($property, $value, $prefixes) {
  @each $prefix in $prefixes {
    @if not index($known-prefixes, $prefix) {
      @warn "Unknown prefix #{$prefix}.";
    }
  }
}

@mixin reflexive-position($property, $value) {
  @if $property != left and $property != right {
    @error "Property #{$property} must be either left or right.";
  }
}

4. @use

mixin 함수, 변수 등을 로드하고 여러 스타일 시트의 css를 결합할 수 있습니다.

// used.scss

$color: #fff;

@mixin usecolor {
  border-color: $color;
}

// use.scss

// type1
@use 'used';

.button {
  border-width: 1px;
  border-style: solid;
  @include used.usecolor;
  color: used.$color;
}

// type2
// 혹시 다른 네임스페이스을 붙이고 싶은 경우 as 를 사용합니다.

@use 'used' as u;

.button {
  border-width: 1px;
  border-style: solid;
  @include u.usecolor;
  color: u.$color;
}

// type3
// 네임스페이스 없이 사용하고 싶을 경우
// 막상 보고나니.. 이건 잘 써야할 것 같죠? 여러개 @use로 데려오면 동일변수나 동일이름은 충돌할 수도...

@use 'used' as *;

.button {
  border-width: 1px;
  border-style: solid;
  @include usecolor;
  color: $color;
}

!default 플래그를 사용하여 정의해놓고 @use로 데려와서 변경 사용 가능한 것 같아요.

// _somelibrary.scss 라이브러리 또는 남 거 (위에 있던거 똑같이 가져옴)

$var1: '텍스트' !default;
$var2: #fff !default;
$var3: 30px !default;

// _customstyle.scss 내 거

@use 'somelibrary' with (
  $var2: #222,
  $var3: 20px
);

5. @forward

@use와 @forward는 비슷한 것 같지만 차이점은 @forward는 forward 한 모듈의 요소(variables, functions, mixins)를 사용할 수 없습니다.


6. @mixin, @include

@mixin은 재사용 가능한 스타일을 정의하고 @include로 호출하여 사용할 수 있습니다.

@mixin float-clear {
  content: '';
  display: block;
  clear: both;
}

ul:after {
  // float 해제가 필요한 경우 재사용 가능
  @include float-clear;
}

7. @function

스타일시트 전체에서 재사용 가능한 함수 정의하고 클래스 내부에서 함수를 선언하여 사용 가능 합니다.
@mixin과 비슷한 것 같지만 @function은 @return을 통해 값을 반환해줍니다.

$content-width: 1000px;
$content-padding: 20px;

@function grid-width($num) {
  @return ($content-width - ($content-padding * 2)) / $num;
}

.grid-wrap {
  width: grid-width(2);
}

// 컴파일 후
.grid-wrap {
  width: 480px;
}

8. @extend

특정 클래스를 상속할 때 사용합니다.

.btn {
  display: inline-block;
  font-family: 'NanumSquare';
  font-weight: 400;
}

.btn-extend {
  @extend .btn;
  font-size: 20px;
}

오래전 문서이지만 한 번쯤 보시는 것도 좋을 것 같아 참고 문서도 올려두겠습니다.


9. @if, @else

Sass에서의 if ~ else는 JS와 유사하게 사용 가능하지만 다른 점은 조건 부분에 괄호를 사용하지 않는다는 것입니다.

$thema-black: #000;
$thema-white: #fff;
$thema-gray: #888;

@mixin bg-thema($bg-color) {
  @if $bg-color == $thema-black {
    background-color: $thema-black;
  } @else if $bg-color == $thema-gray {
    background-color: $thema-gray;
  } @else {
    background-color: $thema-white;
  }
}

10. @each

변형이 많지 않은 반복적인 스타일 작업 시 유용하게 사용 가능합니다.

$sizes: 40px, 50px, 80px;

@each $size in $sizes {
  .icon-#{$size} {
    font-size: $size;
    height: $size;
    width: $size;
  }
}

11. @for

JS의 반복문 문법과 같이 사용합니다.

@for $i from 0 to 10 {
  .sprite-icon-#{$i} {
    background-position: 0px - (40 * $i) px;
  }
}

@for $j from 1 through 3 {
  .grid-#{$j} {
    width: (100% / $j);
  }
}

12. @while

JS의 문법과 같이 주어진 조건이 충족될 때까지 실행됩니다.
Sass 내부에서 반복문 중단 처리를 위해 복잡한 작업이 필요하기에 잘 사용하지는 않는다고 합니다.
공식 문서에서조차 @each 또는 @for가 컴파일 속도도 더 빠르다고 하네요.

@function count($value) {
  @while $value < 3 {
    $value: 100 * $value;
  }
  @return $value;
}

마치며

저는 프로젝트를 통해 경험하면서 아~ 이런 게 있구나.. 뭔가 이런 건 더 간단하게 할 수 있는 무언가 있지 않을까? 싶었던 부분들이 많았기에 Sass를 자세히 보게 되었고 포스팅을 진행하면서 개인적으로도 더 정리할 수 있었던 것 같아 좋았습니다.
아마 저희 그룹 분들께서는 대게 다 아는 내용이실 테지만요…
몇몇 부분들은 더 자세한 내용들이 그룹 노션에 있으니 같이 확인하시면 좋을 것 같아요 😊
Sass에서 사용하는 또 다른 규칙들은 다음 Sass 맛보기 #2 에서 정리할 예정입니다.
그럼 안녕히…👋 -To Be Continue (?)-

참고문서