ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Sass/SCSS
    Note 2021. 4. 19. 02:18

     

    HTML, CSS를 다루다 여러 번 들어본 Sass, SCSS에 대해 알아보려고 한다.

     

    이것들은 CSS Preprocessor(CSS 전처리기)라고 불리는데, CSS가 동작하기 전에 사용하고 CSS의 불편함을 줄여주는데 도움이 된다고 한다. 전처리기는 CSS 문법과 굉장히 유사하지만 선택자의 중첩이나 조건문, 반복문 등 표준 CSS 보다 훨씬 많은 기능을 사용해서 편리하게 작성할 수 있다.

     

    위에서 언급한 CSS 전처리기만으로는 웹에서 CSS가 동작하지 않는다. 웹에서 직접 동작하지 않으니 작성한 전처리기를 웹에서 동작 가능하도록 표준 CSS로 컴파일 해야 한다.

     

    Sass와 SCSS는 차이점

    Sass(Syntactically Awesome Style Sheets)의 3버전에서 새롭게 등장한 SCSS는 CSS 구문과 완전히 호환되도록 새로운 구문을 도입해 만든 Sass의 모든 기능을 지원하는 CSS의 상위집합이다.


    즉, SCSS는 CSS와 거의 같은 문법으로 Sass 기능을 지원한다.

     

    더 쉽고 간단한 차이는 {}(중괄호)와 ;(세미콜론)의 유무이다.

     

    Sass

    .list
      width: 100px
      float: left
      li
        color: red
        background: url("./image.jpg")
        &:last-child
          margin-right: -10px

     

    SCSS

    .list {
      width: 100px;
      float: left;
      li {
        color: red;
        background: url("./image.jpg");
        &:last-child {
          margin-right: -10px;
        }
      }
    }

    Sass는 선택자의 유효범위를 ‘들여쓰기’로 구분하고, SCSS는 {}로 범위를 구분한다.

     

    Sass는 좀 더 간결하고 작성하기 편리하며, {} ;를 사용하지 않아도 되니 코드가 훨씬 깔끔
    SCSS는 인라인 코드(한 줄 작성)를 작성할 수 있고, CSS와 유사한 문법을 가지기 때문에 코드 통합이 훨씬 쉬움

     

    컴파일

    Sass(SCSS)는 웹에서 직접 동작할 수 없다. 어디까지나 최종에는 표준 CSS로 동작해야 하며, 전처리기로 작성 후 CSS로 컴파일해야 한다.

     

    SassMeister

    간단한 Sass 코드는 컴파일러를 설치하는게 부담될 수 있다. 페이지 접속 후 바로 Sass나 SCSS 문법으로 코딩하면 CSS로 실시간 변환이 된다.

     

    node-sass

    node-sass는 Node.js를 컴파일러인 LibSass에 바인딩한 라이브러리

    $ npm install -g node-sass

     

    컴파일하려는 파일의 경로와 컴파일된 파일이 저장될 경로를 설정([]는 선택사항)

    $ node-sass [옵션] <입력파일경로> [출력파일경로]

     

    옵션으로 --watch 혹은 -w를 입력하면, 런타임 중 파일을 감시하여 저장 시 자동으로 변경 사항을 컴파일

    $ node-sass --watch scss/main.scss public/main.css

     

    문법

    주석(Comment)

    /* SCSS */
    
    /*
    컴파일되는
    여러 줄
    주석
    */

     

    중첩(Nesting)

    /* SCSS */
    
    .section {
      width: 100%;
      .list {
        padding: 20px;
        li {
          float: left;
        }
      }
    }
    /* compile */
    
    .section {
      width: 100%;
    }
    .section .list {
      padding: 20px;
    }
    .section .list li {
      float: left;
    }

     

    상위 선택자 참조(Ampersand)

    /* SCSS */
    
    .fs {
      &-small { font-size: 12px; }
      &-medium { font-size: 14px; }
      &-large { font-size: 16px; }
    }
    /* compile */
    
    .fs-small {
      font-size: 12px;
    }
    .fs-medium {
      font-size: 14px;
    }
    .fs-large {
      font-size: 16px;
    }

     

    @at-root (중첩 벗어나기)

    /* SCSS */
    
    .list {
      $w: 100px;
      $h: 50px;
      li {
        width: $w;
        height: $h;
      }
      @at-root .box {
        width: $w;
        height: $h;
      }
    }
    /* compile */ 
    
    .list li {
      width: 100px;
      height: 50px;
    }
    .box {
      width: 100px;
      height: 50px;
    }

     

    중첩된 속성

    /* SCSS */
    
    .box {
      font: {
        weight: bold;
        size: 10px;
        family: sans-serif;
      };
      margin: {
        top: 10px;
        left: 20px;
      };
      padding: {
        bottom: 40px;
        right: 30px;
      };
    }
    /* compile */
    
    .box {
      font-weight: bold;
      font-size: 10px;
      font-family: sans-serif;
      margin-top: 10px;
      margin-left: 20px;
      padding-bottom: 40px;
      padding-right: 30px;
    }

     

    변수(Variables)

    반복적으로 사용되는 값을 변수로 지정할 수 있다. 변수 이름 앞에는 항상 $를 붙인다.

    변수는 선언된 블록({}) 내에서만 유효범위를 가진다.

    /* SCSS */
    
    $color-primary: #e96900;
    $url-images: "/assets/images/";
    $w: 200px;
    
    .box {
      width: $w;
      margin-left: $w;
      background: $color-primary url($url-images + "bg.jpg");
    }
    /* compile */
    
    .box {
      width: 200px;
      margin-left: 200px;
      background: #e96900 url("/assets/images/bg.jpg");
    }

     

    !global 플래그를 사용하면 변수의 유효범위를 전역(Global)로 설정할 수 있다.

    /* SCSS */
    
    .box1 {
      $color: #111 !global;
      background: $color;
    }
    .box2 {
      background: $color;
    }
    /* compile */
    
    .box1 {
      background: #111;
    }
    .box2 {
      background: #111;
    }

     

    연산(Operations)

    Sass는 기본적인 연산 기능을 지원한다. 레이아웃 작업시 상황에 맞게 크기를 계산을 하거나 정해진 값을 나눠서 작성할 경우 유용하다.

     

    산술 연산자

    종류 설명 주의사항
    + 더하기  
    - 빼기  
    * 곱하기 하나 이상의 값이 반드시 숫자
    / 나누기 오른쪽 값이 반드시 숫자
    & 나머지  

     

     

    비교 연산자

    종류 설명
    == 동등
    != 부등
    < 대소 / 보다 작은
    > 대소 / 보다 큰
    <= 대소 및 동등 / 보다 작거나 같은
    >= 대소 및 동등 / 보다 크거나 같은

     

    논리(Boolean)

    Sass의 @if 조건문에서 사용되는 논리(Boolean) 연산에는 ‘그리고’,’ 또는’, ‘부정’이 있다.

    종류 설명
    and 그리고
    or 또는
    not 부정
    /* SCSS */
    
    $width: 90px;
    div {
      @if not ($width > 100px) {
        height: 300px;
      }
    }
    /* compile */
    
    div {
      height: 300px;
    }

     

    재활용(Mixins)

    Sass Mixins는 스타일 시트 전체에서 재사용 할 CSS 선언 그룹 을 정의하는 아주 훌륭한 기능

     

    선언하기(@mixin)와 포함하기(@include), 만들어서(선언), 사용(포함)

     

    @mixin

    /* SCSS */
    @mixin 믹스인이름 {
      스타일;
    }
    
    @mixin large-text {
      font-size: 22px;
      font-weight: bold;
      font-family: sans-serif;
      color: orange;
    }

     

    @include

    /* SCSS */
    
    @include 믹스인이름;
    
    h1 {
      @include large-text;
    }
    div {
      @include large-text;
    }
    /* compile */
    
    h1 {
      font-size: 22px;
      font-weight: bold;
      font-family: sans-serif;
      color: orange;
    }
    
    div {
      font-size: 22px;
      font-weight: bold;
      font-family: sans-serif;
      color: orange;
    }

     

    조건과 반복(Control Directives / Expressions)

    조건의 값(true, false)에 따라 두 개의 표현식 중 하나만 반환

     

    조건의 값이 true이면 표현식1, 조건의 값이 false이면 표현식2 실행

    if(조건, 표현식1, 표현식2)
    /* SCSS */
    
    $width: 555px;
    div {
      width: if($width > 300px, $width, null);
    }
    /* compile */
    
    div {
      width: 555px;
    }

     

    @for

    @for는 스타일을 반복적으로 출력

     

    @for through를 사용하는 형식과 to를 사용하는 형식으로 나뉜다. 두 형식은 종료 조건이 해석되는 방식이 다르다.

    /* through 종료 만큼 반복 */
    @for $변수 from 시작 through 종료 {
      // 반복 내용
    }
    
    /* to 종료 직전까지 반복*/ 
    @for $변수 from 시작 to 종료 {
      // 반복 내용
    }

     

    /* SCSS */
    
    /* through 1부터 3번 반복 */
    @for $i from 1 through 3 {
      .through:nth-child(#{$i}) {
        width : 20px * $i
      }
    }
    
    /* to 1부터 3 직전까지만 반복(2번 반복) */
    @for $i from 1 to 3 {
      .to:nth-child(#{$i}) {
        width : 20px * $i
      }
    }
    /* compile */
    
    .through:nth-child(1) { width: 20px; }
    .through:nth-child(2) { width: 40px; }
    .through:nth-child(3) { width: 60px; }
    
    .to:nth-child(1) { width: 20px; }
    .to:nth-child(2) { width: 40px; }

    to는 주어진 값 직전까지만 반복해야할 경우 유용
    그러나 :nth-child()에서 특히 유용하게 사용되는 @for는 일반적으로 through를 사용하길 권장

     

    @each

    @each는 List와 Map 데이터를 반복할 때 사용

    @each $변수 in 데이터 {
      // 반복 내용
    }

     

    /* SCSS */
    
    $fruits: (apple, orange, banana, mango);
    
    .fruits {
      @each $fruit in $fruits {
        li.#{$fruit} {
          background: url("/images/#{$fruit}.png");
        }
      }
    }
    /* compile */
    
    .fruits li.apple {
      background: url("/images/apple.png");
    }
    .fruits li.orange {
      background: url("/images/orange.png");
    }
    .fruits li.banana {
      background: url("/images/banana.png");
    }
    .fruits li.mango {
      background: url("/images/mango.png");
    }

     

    매번 반복마다 Index 값이 필요하다면 다음과 같이 index() 내장 함수를 사용

    /* SCSS */
    
    $fruits: (apple, orange, banana, mango);
    
    .fruits {
      @each $fruit in $fruits {
        $i: index($fruits, $fruit);
        li:nth-child(#{$i}) {
          left: 50px * $i;
        }
      }
    }
    /* CSS */
    
    .fruits li:nth-child(1) {
      left: 50px;
    }
    .fruits li:nth-child(2) {
      left: 100px;
    }
    .fruits li:nth-child(3) {
      left: 150px;
    }
    .fruits li:nth-child(4) {
      left: 200px;
    }
    

     

     

     

    출처: Sass(SCSS) 완전 정복! / HEROPY Tech

    'Note' 카테고리의 다른 글

    Reflow, Repaint  (0) 2021.04.23
    유닛 테스트(Unit Test), 테스트 주도 개발(Test-driven development)  (0) 2021.04.22
    프론트엔드 개발자가 신경 써야 할 보안  (0) 2021.04.18
    CI/CD  (0) 2021.04.17
    Forward proxy, Reverse proxy  (0) 2021.04.15

    댓글