본문으로 바로가기

Sass 코딩 컨벤션

category StyleSheet/SASSㆍSCSS 2019. 1. 31. 07:23

Sass Coding Convention

Sass 작성을 위한 컨벤션에 대해 알아봅니다.


Table of Contents

  1. 폴더 구조 [Folder structures]
  2. 파일 구조 [File structures]
  3. 인코딩 [Encoding]
  4. 중첩 [Nesting]
  5. 들여쓰기 및 선언 순서 [Style Rules]
  6. 띄워쓰기 [Spacing words]
  7. 주석 [Comments]
  8. 네이밍규칙 [Naming]
  9. 믹스인 [Mixin]
  10. @extend [Extend]
  11. 제어구문 (@if, @each, @for 등) [Control Statements]
  12. 연산자 [Operators]




Sass 코딩컨벤션은 마크업 코딩컨벤션을 상속하여 코드 스타일링등의 기본 작성 규칙들은 마크업 코딩 컨벤션을 따르며, 그밖의 Sass만의 문법들에 대한 규칙을 정의함.



1. 폴더 구조 [Folder structures]

structures
root
ㄴ src
    ㄴ scss
        ㄴ common
        ㄴ import
            ㄴ * (선택)
        ㄴ lib (선택)
    ㄴ css
    ㄴ img
    ㄴ *.html
  • 기본구조는 마크업 코딩컨벤션의 폴더 구조 규칙을 따른다.

  • root/내에서 src/외의 폴더는 자유롭게 관리한다.

  • lib/와 import/*/은 필요에 따라 생성한다.



2. 파일 구조 [File structures]

sass 파일구조
scss
ㄴ 서비스명.scss
ㄴ common
    ㄴ _base.scss
    ㄴ _variables.scss
    ㄴ _mixins.scss
    ㄴ _placeholders.scss
ㄴ import
    ㄴ _*.scss
    ㄴ * (선택)
ㄴ lib (선택)
    ㄴ _*.scss


scss/

  • 서비스명.scss : import 구문으로 이루어진 메인


common/

  • _base.scss : CSS reset 모음
  • _variables.scss
  • _mixins.scss
  • _placeholders.scss : extend 모음


import/

  • _*.scss : 기능 또는 페이지 이름으로 자유롭게 생성


lib/ : 외부라이브러리 모음 (선택)

  • _*.scss: 외부라이브러리


import/ 내의 파일 네이밍은 강제하지 않으며, 편의를 위해 다음과 같이 사용할 수 있다.

  • 파일명에 prefix붙여 네이밍한다.
  • 하위 폴더를 생성하여 파일을 구분해 넣는다.



3. 인코딩 [Encoding]

  • windows 환경에서 컴파일 시 오류가 발생할 수 있으므로 모든 scss파일에 charset을 선언한다.
  • 컴파일 후에 charset 선언은 하나만 남게 되므로 여러 파일에서 작성해도 문제없다.


@charset 선언 전에 공백없도록 주의하여 최상단에 선언한다.


sass
@charset "UTF-8"

body {
    margin: 0;
}



4. 중첩 [Nesting]

  • 최대 3뎁스 중첩까지 사용하는 것을 권장한다 ( 셀렉터의 갯수가 아닌 scss 코드상의 중첩 )
  • 3뎁스가 넘어갈 경우는 하위연결자를 활용하거나 별도의 모듈로 뽑아내는 것을 고려한다.
  • 미디어 쿼리의 중괄호는 중첩수에 포함하지 않는다.


권장되는 사용법

sass
.foo {
    .bar {
        .baz {

        }
        .baz .qux {

        }
    }
}
.foo {
    .bar {
        .baz {

        }
        .qux {

        }
    }
}


나쁜 사용법

sass
.foo {
    .bar {
        .baz {
            .qux {

            }
        }
    }
}



5. 들여쓰기 및 선언 순서 [Style Rules]

  • 중첩 마다 들여 쓰기 한다.
  • 하위 선택자가 시작될 때 빈 줄을 추가한다.
  • extend / include 를 상단에 모아쓰고 그 뒤에 빈 줄을 추가한다.
  • 재선언이 필요한 경우 include를 필요한 위치에 추가 할 수 있다.


권장되는 사용법

sass
.foo {
    //@extend, @include는 상단에 모아쓰고 그 뒤 빈 줄을 추가한다.
    @extend %a;
    @extend %b;
    @include abc(n);

    //속성 별 개행.
    display: block;
    overflow: hidden;
    position: relative;
    z-index: 10;
    width: 100px;
    margin: 0;
    padding: 0;
    border: 1px solid red;
    background: red;
    font-weight: bold;
    letter-spacing: -1px;
    text-decoration: underline;

    //상황에 따라 하단에 위치할수도 있음.
    @include bcd(n);

    //하위 선택자가 시작될 때 빈 줄 추가.
    .bar {
        ...
    }
}


나쁜 사용법

sass
//개행 하지 않음
.foo {
    @extend %a;@extend %b;@include abc(n);display:block;overflow:hidden;position:relative;z-index:10;width:100px;margin:0;padding:0;border:1px solid red;background:red;font-weight:bold;letter-spacing:-1px;text-decoration:underline;
    .bar {...}
}
//@extend를 상단에 모아 쓰지 않음, @extend와 @include 다음 빈줄을 추가 하지 않음
.foo {
    @include abc(n);
    display: block;
    overflow: hidden;
    position: relative;
    z-index: 10;
    @extend %b;
    width: 100px;
    @extend %a;

    .bar {
        ...
    }
}
//하위 선택자 전에 빈줄을 추가 하지 않음, 들여쓰기 하지 않음
.foo {
    @extend %a;
    @extend %b;
    @include abc(n);

    display: block;
    overflow: hidden;
    position: relative;
    z-index: 10;
    width: 100px;
    .bar {
    margin: 0;
    padding: 0;
    }
}


scss 파일이 css로 변환되는 과정에서 설정에 따라 공백과 여백을 없앨 수 있다. 때문에 scss 파일에서는 css 파일과 달리 가독성에 중점을 두고 속성마다 개행 한다.

ui 별로 파일을 나누면 한 파일의 길이를 줄일 수 있다.

@extend@include 를 사용한 바로 다음 라인은 @extend, @include 가 그룹화된 느낌과 다음 라인에 오는 속성의 가독성을 위해 빈 줄을 추가한다.

하위 선택자가 시작될 때 빈 줄을 추가하면 하위 선택자의 가독성이 높아진다.

속성 선언 순서를 컨벤션 따르면 다음 작업자가 속성을 쉽게 찾을 수 있다.



6. 띄워쓰기 [Spacing words]

가독성을 높이고 개발자도구와 코드 일관성을 유지하기 위해 아래와 같이 띄워쓰기를 권장한다.

연산자(Operator)와 연결자(Combinator)는 기호 좌/우측을 한 칸 띄운다.


예시 :

sass
// - 와 * 앞/뒤를 한칸 띄운다.
$height - ($width * 2)

// > 와 +  앞/뒤를 한칸 띄운다.
.title > .tx:after
.title + div



7. 주석 [Comments]

CSS 주석표현인 /* 주석 */으로 import되는 파일상단에 파일명 표기

  • 개발자도구로 디버깅 시(sass미사용자, 서비스 초기 투입 시) 선언위치 파악에 도움


예시 :

sass
@charset "utf-8";
/* _layout.scss */

...


그 외 주석은 컴파일되지 않도록 //으로 표기

  • 기능(mixin, 변수…​) 대한 설명, UIO 등
  • 이미 기존 CSS에 /* 주석 */ 이 선언되어있던 것을 굳이 //주석으로 수정할 필요는 없음
  • CSS에 반드시 컴파일되어야 하는 주석이 있다면 /* */ 으로 표기 가능


예시 :

sass
@charset "utf-8";
/* _layout.scss */

//Header
...

//Footer
...


주석 컴파일 테스트

_layout.scss

_layout.scss
@charset "utf-8";
/* _layout.scss */

//Header
#header{background:#fff}

//Footer
...


서비스명.scss

서비스명.scss
@charset "utf-8";
@import "common/base";
@import "common/variables";
@import "common/mixins";
@import "common/placeholders";

@import "import/layout";


서비스명.css

서비스명.css
@charset "utf-8";
/* _base.scss */
...

/* _variables.scss */
/* _mixin.scss */
/* _placeholders.scss */
...

/* _layout.scss */
#header{background:#fff}
...



8. 네이밍규칙 [Naming]

8.1. placeholder selector

  • 문자: 소문자
  • 연결자: _ (Underbar)


예시 :

sass
%text_color


중복 class 처럼 활용할 수 있기 때문에 class명 네이밍(컨벤션) 처럼 연결자를 _ (Underbar)로 사용하는 것을 권장


8.2. mixin

  • 문자 및 연결자: Camel Casing Notation

예시 :

sass
@mixin testBox() {
    ...
}

@mixin testBox($test) {
    ...
}


mixin: 선언 시 class명(_ Underbar), css속성명(- Hyphen)과 다르게 눈에 들어올 수 있는 네이밍이 필요하여 Camel Casing Notation으로 사용하는 것을 권장


8.3. 변수

  • 지역변수(로컬 변수): 소문자
  • 전역변수(글로벌 변수): G-소문자
  • 상수: 대문자
    • 상수란? 선언 이후에는 변하지 않는 값 (자세한 개념파악은 생략)
    • 상수는 CSS에서는 활용도가 낮은 편으로.. 굳이 사용한다면 대문자로 표기 권장 함
  • 연결자: - (Hyphen)
  • 네이밍 조합 : ${요소(Element, class) 이름} - {속성 이름} - {용도 및 역할}


네이밍의 조합은 상황에 맞게 재조합 혹은 생략가능

class명에 _ (underbar)가 있는 경우에는 underbar 와 hyphen의 혼용 허용. ex) $btn_more-color 등

'용도 및 역할'은 축약형 지양


네이밍 조합 케이스

예시

$ {요소(E) 이름} - {속성 이름}

$body-color, $body-background-color, $G-body-background-color 등}

$ {요소(E) 이름} - {용도 및 역할}

$body-horizental 등

$ {요소(E) 이름} - {속성 이름} - {용도 및 역할}

$body-color-point, $body-background-color-point 등

$ {요소(class) 이름} - {속성 이름}

$btn-border-color, $btn_more-border-color 등

$ {요소(class) 이름} - {속성 이름} - {용도 및 역할}

$btn-border-color-hover, $btn_more-border-color-hover 등

$ {속성 이름} - {용도 및 역할}

$color-point, $G-color-point, $margin-endpage, $margin-endpage-wide 등

$ {용도 및 역할}

$index, $count, $length, $max-count 등


좋은 예 :

sass
$G-body-color: #fff;
$G-font-family-base: Dotum,'돋움',Helvetica,AppleSDGothicNeo,sans-serif;
$G-font-family-tahoma: tahoma, sans-serif;

.test {
    $color-point: #ff0078;
    $margin-endpage: 15px;
}


나쁜 예 :

sass
//BAD : 전역변수(글로벌 변수)에는 구분을 위해 'G-' 를 prefix로 사용
//(as-is: body-color / to-be: G-body-color)
$body-color: #fff;

.test {
    //BAD: '용도 및 역할'의 변수명은 축약형을 지양하며,
    //fullname 사용(as-is: color-pnt / to-be: color-point)
    $color-pnt: #ff0078;

    //BAD
    //1. '용도 및 역할'의 변수명은 축약형을 지양하며,
    //fullname 사용(as-is: endCtSide / to-be: end-content-side)
    //2. 변수 네이밍은 카멜형식이 아닌 소문자, 연결자는 - (Hyphen)사용(참조: 표 - 네이밍 조합 케이스)
    $endCtSide: 15px;
}


  • 디렉토리 경로에 대한 변수
    • 선택사항으로, 변수 선언시 아래와 같은 규칙으로 선언하도록 권장한다.

종류

변수이름 지정규칙

프로젝트 루트 or 도메인

$G-path

img 디렉토리

$G-path-img

img 디렉토리 이하

$G-path-img-{서브 디렉토리 이름}


  • 아래 예제처럼 배경이미지 경로를 적용할 때 유용하다.

예시 :

sass
$G-path: '../';
$G-path-img: $G-path + 'img/';

.class {
  background-image: url($G-path-img + 'sp_service.png');
}


  1. 변수는 사용성을 위해 요소명, css속성명, 용도 및 역할 등 여러 조합형태로 쓰일 수 있고, mixin이 Camel Casing Notation을 사용하기로 하였으므로 구분을 위해 - (Hyphen)로 사용하는 것을 권장
  2. 로컬변수(지역변수)와 글로별변수(전역변수)를 'G-'와 같은 prefix 를 사용하여 구분한 이유
    • 처음부터 로컬변수(지역변수)와 글로벌변수(전역변수)의 차이를 이해하고, 구분하여 선언해야 유시보수가 용이하기 때문
    • 글로벌변수(전역변수)에 'G-' 를 붙인 이유
    • 로컬변수(지역변수)의 사용양이 많으므로 글로벌변수(전역변수)에 붙임
    • Global 의 약자인 G를 대문자로 사용하여 명확성을 더하고, 변수명의 연결자인 - (Hyphen)을 붙여 위에 약속한 조합의 변수명을 연결하여 사용하는 것을 권장



8.3.1. 지역변수(로컬변수)와 전역변수(글로벌 변수)

  1. 정의
    • 지역변수 : 블록 내에서 선언 된 변수 (범위 : 블록 내에서만)
    • 전역변수 : 블록 밖에서 선언 된 변수 (범위 : 전체)
  2. 사용
    • 특정 요소 / 모듈의 속성 값을 사이트 전체에서 사용하는 경우 속성 값을 전역변수로 사용한다.


예시 :

sass
$G-var: 10px; //전역변수

.foo {
    $var: 5px; //지역변수
    $body-width: 100px; //지역변수
    ...
}

@mixin sample($foo) {
    ...
    //지역변수
}


8.3.2. 선언

  • 1. 변수는 한 줄에 하나만 선언한다.

예시 :

sass
$var1: value;
$var2: value;
  • 2. _variables.scss 파일 내부에 선언한 변수들은 #표 - 네이밍 조합 케이스 에 따라 선언한다.

예시 :

sass
@charset "utf-8";
/* _variables.scss */

//요소(Element, class) 이름 - 속성 이름
$G-header-background-color-point;
...

//속성 - 용도 및 역할 기준
$G-color-point: #ff0078
...

//용도 및 역할 기준
$G-path-img: "../im/";
...

//로컬변수
$btn_area-width: 10px;
...
  • 3. 전역변수는 _variables.scss에 선언하거나, 별도의 import 파일을 사용하지 않는 경우 관련 scss파일의 상단에 정의한다.



9. 믹스인 [Mixin]

  • 인자값 사용유무에 따라 mixin과 extend를 분리하여 사용


mixinextend 을 어떻게 구분하여 사용해야 하는가?' 에 대한 고민

기준차이: 작업자 스타일에 따라 다름

성능차이: 거의 없음

용량차이: 상황에 따라 다름

개인취향에 따라 mixin과 extend의 사용이 혼돈된다.

하지만, mixin은 인자값을 활용할 수 있다는 큰 특징이 있으므로 이를 기준으로 분리하여 사용하는 것을 권장

인자값에 대한 네이밍은 #표 - 네이밍 조합 케이스을 참고한다.


기본 mixin 문법

sass
@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    -ms-border-radius: $radius;
    border-radius: $radius;
}

.box {
    @include border-radius(10px);
}
컴파일된 css
.box {
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    -ms-border-radius: 10px;
    border-radius: 10px;
}




10. @extend [Extend]

  • 선언방법
    • %(place holder) 선택자를 사용


예시 :

sass
%bar {
    border:1px solid red;
}


  • %(place holder)선택자를 사용하는 이유
    1. @extend로 쓰는 것인지 아닌지에 대한 사용 여부를 구분하기 위함
    2. 다른 선택자(class, id 등)와 구분하여 사용하기 때문에 의도하지 않거나 예상하기 힘든 코드를 만들어 내는 일을 최소화
    3. sass-lang.com의 Placeholder Selectors: %foo 상세페이지


좋은예시(% 선택자를 사용)
%foo {
}

.bar {
    @extend %foo;
}


나쁜예시(class 선택자를 사용)
.foo {
}

.bar {
    @extend .foo;
}


기본 extend 문법

sass
%layout {
    border: 1px solid #ccc;
    padding: 10px;
    color: #333;
}

.success {
    @extend %layout;

    border-color: green;
}

.error {
    @extend %layout;

    border-color: red;
}

.warning {
    @extend %layout;

    border-color: yellow;
}
컴파일된 css
.success, .error, .warning {
    border: 1px solid #cccccc;
    padding: 10px;
    color: #333;
}

.success {
    border-color: green;
}

.error {
    border-color: red;
}

.warning {
    border-color: yellow;
}


주의사항

@media 와는 제대로 작동하지 않는다.

Sass 는 미디어 쿼리 안에서 외부의 선택자를 확장할 수 없다.


예시 :

sass
.foo {
  content: 'foo';
}

@media print {
    .bar {
        @extend .foo;
	// !충돌. 컴파일러는 할 수 없는 일이라고 에러메세지를 출력한다.

	// 에러메세지
	// You may not @extend an outer selector from within @media.
	// => @media 안에서 외부의 선택자를 @extend할 수 없다.
	// You may only @extend selectors within the same directive.
	// => 같은 지시어 안에 있는 선택자만 @extend할 수 있다.
    }
}


10.1. %(place holder) 의 확장

  • 규칙 세트 확장 가능
  • 확장 시 고려사항
    • 다른 모듈들에 걸치지 않게, 한 모듈 안에서 확장을 사용
    • 오로지 % 에만 확장을 사용하고, 실제 선택자(class, id??)에는 사용X
    • 확장하는 %가 가능한 한 적게 존재하도록 사용


HTML에 존재하지 않는 불필요한 선택자가 CSS에 출력되지 않도록 주의


예시 :

sass
%foo {
  //@extend안에 @include 가능
  @include  bar;

  .baz {
    width: 100px;
  }
}


10.2. % 선언시, 축약형 지양

좋은 예 :

sass
%sp_enter {
    background-image: url($path-img + "sp_enter_10.png");
    background-repeat: no-repeat;
    background-position: -999px -999px;
}


나쁜 예 :

sass
%sp_enter {
    background: url($path-img + "sp_enter_10.png") no-repeat -999px -999px
}



11. 제어구문 (@if, @each, @for 등) [Control Statements]


11.1. @if

예시 :

sass
@if $foo{
    ...
}


@ else 와 @ else if : 이전 문장의 닫는 괄호와 같은 줄에 기술한다.

sass
$type: monster;

p {
    @if $type == ocean {
        color: blue;
    } @else if $type == matador {
        color: red;
    } @else if $type == monster {
        color: green;
    } @else {
        color: black;
    }
}
컴파일된 css
p {
    color: green;
}


@if 기타 활용예시

sass
@mixin foo($_imgsize, $_position: relative) {
    @if $_position != absolute{
        display: block;
    }

    position: $_position;
    width: $_imgsize;

   ...
}


11.2. @each

  • @each 반복문은 Sass가 제공하는 세 가지 반복문들 중에서 가장 많이 사용될 수 있다.

활용 예1 :

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


활용 예2 :

sass
$map: (
    key: #aaa,
    value: #bbb
)

@each $key, $value in $map {
    .section-#{$key} {
        background-color: $value;
    }
}
컴파일된 Css
section-key {
    background-color: #aaa;
}

.section-value {
    background-color: #bbb;
}

...


활용 예3 :

sass
.foo {
    $_num: 0;
    @each $name , $color in $menu {
        .#{$name} &{
            background-color: #{$color};
        }
        $_num: $_num + 1;
    }

    ...
}


11.3. @for

@for 반복문은 CSS의 :nth-* 가상 클래스와 결합되었을 때 유용할 수 있다.

sass
@for $i from 1 through 10 {
    .foo:nth-of-type(#{$i}) {
        border-color: hsl($i * 36, 50%, 50%);
    }
}
컴파일된 css
.foo:nth-of-type(1) {
  border-color: #bf8c40;
}

.foo:nth-of-type(2) {
  border-color: #a6bf40;
}

.foo:nth-of-type(3) {
  border-color: #59bf40;
}

...


@for 기타 활용예시 :

sass
@for $i from 0 through 3 {
    .no#{$i} {
        background-position: -(15+12*$i)+px -200px
    }
}
컴파일된 css
.no0 {
  background-position: -15px -200px;
}

.no1 {
  background-position: -27px -200px;
}

.no2 {
  background-position: -39px -200px;
}

.no3 {
  background-position: -51px -200px;
}


11.4. @while

@while 반복문은 내부에서 반복문을 중단시킬 방법이 없기 때문에 실제 Sass 프로젝트에서 사용할 일은 거의 없다.



12. 연산자 [Operators]

  • 연산이 필요할 때는 변수를 활용한다.
  • 연산이 필요한 숫자는 단위를 써준다. ex) px, em 등
  • 한글주석을 기제하여 연산식을 알기 쉽게 사용한다.


sass
@mixin halfHeight($height) {
    position: absolute;
    top: 50%;
    height: $height; // 높이값
    margin-top: - $height / 2; // 높이값의 반
}

.tit {
  @include halfHeight(100px);
}
컴파일된 css
.tit {
    position: absolute;
    top: 50%;
    height: 100px;
    margin-top: -50px;
}


연산시 단위가 붙는 경우, 붙지 않는 경우

sass
div {
    // 연산시 1개이상의 값에 단위가 포함되어야 결과값에 단위가 자동으로 붙게 됩니다.
    width: 100px + 10;         // 110px
    width: 100 + 10px;         // 110px
    width: 100px + 10px;       // 110px
    width: (100 + 10) * 1px;   // 110px
    width: 100 + 10;           // 110
}




Jaehee's WebClub