본문 바로가기

CSS

입문 Sass(SCSS), 그리고 작성 방법론 BEM

Sass(SCSS)

Sass

 

Sass를 알아가기 전에 잡썰 잠깐 풀어 보겠습니다.

마이크로 프로젝트에 CSS를 작성하는 건 그리 어려운 일도 아닐뿐더러
딱히 Less, Sass 등의 전처리기를 고려할 필요도 없을 것입니다.

하지만 추후 서비스가 확장되거나 규모가 큰 협업 프로젝트에서 CSS 코드가 기하급수적으로 늘어나는 상황이라면..
변경/추가 사항이 생기거나 디자인이 바뀔 경우, 상당한 단순노동의 수고를 해야 하거나
디버깅이 어려운 CSS의 늪에 빠지게 되고 결국 중복된 오버라이딩과 !important를 남발하게 됩니다.

Sass는 이러한 문제를 해결해 줄까요?
두말 하면 잔소리, 충분히 가려운 부분을 긁어줄 수 있을 뿐만 아니라 더 재미있는 코딩생활 가능!

 

장점

  • CSS의 재활용성을 높여줍니다.
  • 코드의 계층과 관계 가독성이 좋습니다.
  • 변수, 함수, 연산의 기능이 있습니다. (개발 개념 향상을 위한 동기부여)


단점(?)

  • 컴파일 과정과 개발언어의 개념이 필요합니다. (if, for, function 등)  "단점일까요?"

 


아닥하고 예제를 보죠.

JS 구문과 같은 코드안에 CSS 속성이 보입니다.
개발언어에 대한 지식이 없는 분이라면 당황하실 수 있겠지만 천천히 설명 들어갑니다.

아래 코드는 공통으로 쓰일 기능들을 모아 놨기에 global.scss 란 파일명으로 저장해 봅니다.
.scss란 파일명이지만 이것만으로는 어디에도 css 속성이 적용되지 않습니다.

/* global.scss */

/* global values*/
$base-font-size: 16px;
$base-bg-color: #f2f2f2;


/* fontSet Usage: size, color */
@mixin fontSet($size, $color) {
  font-size: $size;
  color: $color;
}


/* textBoxXet Usage: type-a, type-b */
@mixin textBoxSet($type) {
  @if($type == type-a) {
    padding: 16px;
    border: 1px solid #e1e1e1;
    background-color: #fff;
  }
  @if($type == type-b) {
    padding: 14px;
    color: #fff;
    background-color: #333;
  }
}

아래 코드는 메인페이지 스타일 작업을 위해 main.scss 란 파일명으로 저장하고
상단에는 공통 기능 사용을 위해 global.scss 를 import 합니다.

/* main.scss */

/* 공통기능 import */
@import "global.scss";

/* 위에서 정의한 변수와 기능을 써먹기 */
body {
  font-size: $base-font-size;
  background-color: $base-bg-color;
}
  
.heading {
  @include fontSet(40px, #33aaaa);
}
  
.text-box {
  @include textBoxSet(type-a);
  
  &__title {
    @include fontSet(18px, #666666);
  }
}


간단히 설명하면

body 내 속성은 공통에 정의된 폰트사이즈 '16px'와 배경색 '#f2f2f2' 변수를 가져왔고,
body에 속한 h1 제목은 fontSet 에 폰트사이즈 '40px' 값과 색상값 '#33aaaa'를 넣어 주고 @include로 호출,
역시 body에 속한 .text-box란 클래스에는 textBoxSet에 type-a 란 값을 넣어 주고 @include로 호출합니다.

SCSS 컴파일 과정을 거치고서야 아래 처럼 css 파일이 생성되는데
global.scss에 정의한 변수와 기능을 사용해 최종 css로 어떻게 작성되어 나오는지 알수 있습니다.

body {
  font-size: 16px;
  background-color: #f2f2f2;
}

h1 {
  font-size: 40px;
  color: #33aaaa;
}

.text-box {
  padding: 16px;
  border: 1px solid #e1e1e1;
  background-color: #fff;
}
.text-box__title {
  font-size: 16px;
  color: #666;
}

 

바로 이 css 파일이 실제 서비스에 적용되게 됩니다.

Online Tool

sassmeisterjsfiddle, codepen 처럼 설치,환경구성 없이 Sass(SCSS) 코딩 테스트가 가능한 도구입니다.
 

SassMeister | The Sass Playground!

SassMeister: The sassiest way to play with Sass, Compass, & LibSass!Loading...

www.sassmeister.com


사스장인?을 이용해 직접 코딩해 보면서 감을 찾아보세요.

예제를 통해 살펴 본 Sass(SCSS)를 간단히 정의해보면
최종 css 파일 생성 전 처리(SCSS코딩+컴파일)기로 효율적인 코딩과 재사용성이 좋은 유용한 도구 정도겠군요.


제목은 입문인데 별 내용은 없는 것이...
개발 언어와 거리감이 있는 분들의 이해에 촛점을 두고 설명하다 뒷산으로 올라간 듯 싶습니다.
궁금한 부분은 댓글에 남겨주시면 가능한 열심히 답변드리겠습니다.

 

 

 


 

BEM

Block > Element > Modifier

 

BEM은 css를 효율적으로 관리하는 여러가지 방법론 중 하나입니다.

CSS class 명을 아래와 같은 구조로 작성해 종속적 관계가 아닌 독립적(개별 Block)으로 구성합니다.

블럭요소(그룹 컨테이너)  +  __하위 엘리먼트(그룹내 기능)  +  --엘리먼트 상태

 

BEM 방법론에 따른 class 명 작성 예시를 볼까요?  (이미 위의 sass 예시에 적용된 것은 안비밀)

우선 HTML 마크업 코드입니다.

이미지, 목록, 버튼을 포함하고 있는 카드 그룹의 클래스 이름과 그 하위 클래스명을 잘 살펴 보세요.

<article class="card">
  <div class="card__image">
    <img src="https://media.giphy.com/media/2zoCrihrueMUVOZlTx/giphy.gif">
  </div>
  <ul class="card__list">
    <li class="card__list__item">List 1</li>
    <li class="card__list__item">List 2</li>
    <li class="card__list__item card__list__item--active">List 3 - active</li>
  </ul>
  <button class="card__button">Go button</button>
</article>

그룹 컨테이너(B) 'card' 가 있고 자식요소(E)는 'card__image, card_list, card_button' 으로 card 그룹에 속하지만
독립적인 class명으로 정의되어 있습니다.
(중첩이 많으면 class명이 길어지는 문제가 있지만 명확한 구분과 부모,자식 그룹의 관계를 이해하기 수월합니다.)
목록 중 세번째 li 에는 상태(M)를 정의한 card__list__item--active 클래스가 정의되어 있습니다.

이제 SCSS를 작성해보죠.

card 클래스에 BEM 으로 하위 그룹을 작성한 예 입니다.

그룹의 컨테이너(B)
__그룹에 속한 엘리먼트(E)
--엘리먼트의 상태(M)

/* BEM 구조로 카드 그룹 SCSS 작성 예시 */

.card {
  display: inline-flex;
  flex-flow: column nowrap;
  padding: 14px;
  background: #999;
  &__image {
    
    img {
      width: 300px;
    }
  }
  &__list {
    list-style: none;
    margin: 16px 0;
    padding: 0;
    &__item {
      margin: 2px 0;
      padding: 6px;
      line-height: 1.6em;
      color: #fff;
      background-color: #335;
      &--active {
        color: #a9ff00;
        background-color: #115;
      }
    }
  }
  &__button {
    padding: 6px;
    border: 0;
    font-size: 16px;
    background-color: yellow;
    &:hover {
      position: relative;
      background-color: white;
      &:before {
        position: absolute;
        content: '';
        width: 20px;
        height: 20px;
        margin-left: -25px;
        border-radius: 10px;
        background: red;
      }
    }
  }
}


SCSS는 중첩 깊이가 4단계 이상 들어가지 않도록 권고하고 있습니다.
하지만 BEM으로 작성할 경우에는 몇 단계라도 독립적인 클래스로 구조화 되므로 코딩시 여유롭습니다.

컴파일 후 CSS 결과물을 보면 알수 있습니다.

.card {
  display: inline-flex;
  flex-flow: column nowrap;
  padding: 14px;
  background: #999;
}
.card__image img {
  width: 300px;
}
.card__list {
  list-style: none;
  margin: 16px 0;
  padding: 0;
}
.card__list__item {
  margin: 2px 0;
  padding: 6px;
  line-height: 1.6em;
  color: #fff;
  background-color: #335;
}
.card__list__item--active {
  color: #a9ff00;
  background-color: #115;
}
.card__button {
  padding: 6px;
  border: 0;
  font-size: 16px;
  background-color: yellow;
}
.card__button:hover {
  position: relative;
  background-color: white;
}
.card__button:hover:before {
  position: absolute;
  content: "";
  width: 20px;
  height: 20px;
  margin-left: -25px;
  border-radius: 10px;
  background: red;
}

 

BEM의 기본 방법론은 이렇습니다.

관계를 유추할 수 있는 명확한 클래스명과 독립성이 BEM의 핵심이라고 생각됩니다.
언더바'__'나 하이픈'--'이 아니라도 될것 같지만.. 가만히 생각해보면 가독성과 구분을 위한 최선인 듯 싶네요.

기타 SMACSS, OOCSS 등의 방법론이 있고 또 여기서 확장된 OOSASS 같은 개발색(?)이 짙은 보완된 방법론도 있습니다.

 

오늘은 여기까지..

'CSS' 카테고리의 다른 글

단거 - content: attr(data-xxx)  (0) 2023.01.12
placeholder 색상 변경 스타일  (0) 2016.09.07