데브코스

[Day 32] SCSS (2)

라다디 2022. 11. 30. 16:04

@mixin

@mixin은 여러번 재활용 할 스타일들을 정의해서 필요한 곳에서 사용하는 개념이다. 

만들어 둘 스타일을 @mixin 규칙으로 정의하고 필요한 곳에서 @include 규칙을 통해 사용할 수 있다. 

 

@mixin은 특정한 값을 인수로 보내고 매개변수로 받아서 사용할 수 있다. 

이 매개변수에는 기본값을 지정해줄 수 있다. 

 

조건문을 통해서 조건을 줄 수 있다.

조건문은 삼항 연산자를 사용해서 작성할 수도 있다. if(condtion, true, false)

참고로 if 뒤에 괄호를 쓸 때 띄어쓰기를 하면 expected "(" 라는 에러가 난다. 

 

@mixin은 단순히 css의 속성과 값만 적는 것이 아니라 Sass에서 정의할 수 있는 다양한 내용을 @mixin 내부에서 활용할 수 있다. 

@mixin을 통해서 중첩된 하위 선택자를 작성할 수도 있다.

@mixin 내부에서 또 다른 @mixin을 @include로 가져와서 활용할 수 있다.

 

가변 인수

매개변수로 들어올 값의 개수를 예측하지 못할 때 가변 인수를 사용할 수 있다.

@mixin bg($w, $h, $rest...) {
    width: $w;
    height: $h;
    background: $rest;
}

.box {
    @include bg(100px, 
        200px, 
        url("/images/a.png") no-repeat center, 
        url("/images/b.png") repeat-x, 
        url("/images/c.png") repeat-y center / contain
    );
}

... 연산자를 사용하여 리스트 데이터를 전개시켜 순서대로 매개변수에 들어가게 할 수도 있다.

보간 기능을 통해 속성의 이름을 받아서 다음과 같이 작성할 수도 있다. 

 

키워드 인수

일부 속성에만 값을 주고 싶을 경우 특정 속성값에 null을 지정해서 컴파일 되지 않도록 해준다. 

하지만 이렇게 하면 매개변수의 순서를 정확하게 알고 있어야 한다는 단점이 존재한다. 

이럴 때 사용할 수 있는 것이 키워드 인수이다. 

매개변수의 이름을 전달하는 인수의 키워드로 사용한다고 해서 키워드 인수라고 한다. 

 

 

@content

@include의 중괄호 사이(= 스타일 블럭)에 있는 내용은 @mixin의 @content 규칙으로 들어가게 된다.

 

아래의 예제는 미디어 규칙의 브레이크 포인트가 달라질 때마다 동일한 값을 사용하는 모든 부분을 직접적으로 수정해줘야 한다. 

이러한 점을 보완해서 @mixin 규칙을 새로 만들어 줄 수 있다. 

Sass에서 map 데이터를 조회할 때 사용하는 내장 모듈을 @use "sass:map";로 가져온다.

위처럼 작성하면 브레이크 포인트에 해당하는 값이 변할 때 맵 데이터에 있는 해당 값만 변경해주면 된다.

 

@content는 단일로만 사용될 수 있는 것 뿐만이 아니라 함수처럼 소괄호를 통해 스타일 블록으로 데이터를 전달해줄 수 있다.

 

@extend

@extend를 통해 이미 작성해둔 선택자의 이름을 명시하면 그 선택자가 가진 스타일을 다른 요소에 적용시킬 수 있다.

주의해야할 점은 @extend는 선택자 폭발이라는 부작용이 있을 수 있다.

/* SCSS */
.container {
    .item {
        color: red;
        .box {
            @extend .item;
            &::after {
                content: "";
                @extend .item;
            }
        }
    }
}

/* CSS */
.container .item, 
.container .item .box::after, 
.container .item .box::after .box, 
.container .item .box {
  color: red;
}
.container .item .box::after {
  content: "";
}

.container .item .box::after .box

box에서 @extend .item을 사용할 때는  자신이 포함되지 않은 아이템 부분의 선택자만 상속이 되어서 사용이 되는 반면,  box의 의 중첩된 부분에서 @extend .item을 사용하게 되면 item뿐만이 아닌 box부분도 상속이 되어서 문제점이 발생한다. 

따라서 @extend는 중첩이 되었을 때 사용하지 않는 것이 좋다.

 

또한 @extend를 사용하는 것은 @mixin 을 통해 스타일 그룹을 만드는 방법으로 완전히 대체하는 것이 가능하다.

그렇기 때문에 전역화된 스타일이 있는 경우에 이 스타일을 @mixin으로 대체하는 것이 번거롭거나 문제가 있는 경우에만 쓰는 것이 좋다.

 

@extend에는 placeholder 선택자 %가 존재한다. 

@extend 규칙을 통해 확장해서 사용하는 용도로만 쓸 수 있는 선택자이다.

주의사항은 placeholder 선택자는 범위를 신경써야 하기 때문에 media 규칙 내에서 사용할 placeholder 선택자는 그 안에서 정의되어 있어야 한다는 것이다.

 

위 코드를 @mixin을 대체한 코드는 다음과 같다. 

컴파일 된 결과를 보면 반복되는 코드가 많다.

이러한 경우에 css의 용량 최적화를 위해 GZip 압축 방식을 자주 사용한다. 

 

@function

@function을 이용해서 함수를 작성할 수 있다.

@error을 사용하여 자바스크립트 throw와 같이 예외 처리를 할 수 있다. 

함수를 작성할 때 SCSS에 내장되어 있는 다양한 전역 함수와 이름을 겹치게 하지 않기 위해 두 개의 단어를 조합해서 이름을 작성하는 것이 좋다.

참고로 Sass는 소수점 자리 10자리까지만 계산한다.

 

조건과 반복

Sass에서의 조건문은 @if, @else if, @else를 통해 작성할 수 있다.

@if는 조건 부분에 소괄호를 생략할 수 있다.

 

List와 Map은 @each 통해서 반복할 수 있다.

 

@for를 통해서 반복할 때는 다음과 같이 작성한다. 

for 변수 from 시작 through 끝 (through은 <=의 의미)

for 변수 from 시작 to 끝 (to는 <의 의미)

참고로 선택자 부분에 변수를 사용하려면 보간 기능을 사용한다. 

 

@while도 마찬가지로 반복문을 작성할 때 사용하고 소괄호를 생략할 수 있다. 

 

가져오기, 모듈

@import

@import를 통해 외부에 있는 파일을 가져올 수 있다. 

 

다음 명령어를 통해 터미널에서 SCSS를 컴파일 시켜줄 수 있는 패키지를 설치한다.

npm install -g sass

전역으로 Sass라는 패키지를 설치해서 sass 명령으로 Sass, SCSS파일들을 css로 컴파일 할 수 있다.

 

sass scss:css

scss 폴더를 css 폴더로 컴파일하라는 의미이다. 

 

variables.scss라는 파일이 있다고 할 때 main.scss에서 import를 하고 싶다면 다음과 같이 작성한다.

확장자는 생략할 수 있다.

@import "./variables"

만일 _variables.scss 처럼 파일 이름 앞에 _가 있다면 컴파일이 되지 않고, import를 할 때도 파일 이름에 _를 작성하지 않아도 된다. 

 

주의할 점은 다음과 같이 css에서 사용하는 url 함수를 사용하거나, css 확장자를 사용하거나, http로 시작되는 url을 가져올 때는 컴파일 결과로 포함이 되어 출력된다.

@import url("./variables.scss");
@import "./variables.css";
@import "http://google.com/variables.scss";

전부 다 컴파일 결과로 포함이 되어 출력 된다.

 

@use

@use를 통해 파일을 가져올 경우 모듈화 해서 사용이 가능하고 네임스페이스를 사용할 수 있다.

@use "./variables" as var

.main {
  background-color: var.$primary;
}

 

@forward

@forward특정 파일에서 모듈로 사용하고 있는 내용을 다른 파일에서도 사용 가능하게 만들어 준다.

 

예를들어 main.scss에서 @use를 사용하여 variables.scss의 변수들을 가져와서 사용하고 있을 때 해당 파일의 범위에서 사용하는 것이기 때문에 다른 파일에서 main.scss파일을 import를 할 경우 main.scss에서 사용하고 있는 variables를 사용할 수 없다.

 

이럴 때 사용할 수 있는 것이 @forward이다.

 

@use "./variables" as var;
@forward "./variables";

.main {
  background-color: var.$primary;
}

@use로 불러온 variables를 @forward를 통해 다시 전달을 해주는 개념이다.

 

// other.scss
@use "../scss/main.scss"

.box {
  color: main.$primary;
}

 

@forward도 @use와 마찬가지로 네임스페이를 사용할 수 있는데 방식이 다르다. 

@forward "./variables" as var-*;

*를 사용하면 *의 위치에 변수명이 들어가고 *의 앞을 prefix라고 말한다. 

// main.scss
@use "./variables" as var;
@forward "./variables" as var-*;

.main {
  background-color: var.$primary;
}
// other.scss
@use "../sess/main.scss"

.box{
  color: main.$var-primary;
}

 

내장 모듈

이미 만들어져 내장되어 있는 기능들을 모듈로 이용할 수 있다.

  • sass:color - 색상 관련
  • sass:list - 리스트 타입
  • sass:map - 객체 타입
  • sass:math - 계산
  • sass:meta - 콜백, 타입 체크 등
  • sass:selector
  • sass:string - 문자열 관련
 

Sass: Built-In Modules

Compatibility: Dart Sass since 1.23.0 LibSass ✗ Ruby Sass ✗ Only Dart Sass currently supports loading built-in modules with @use. Users of other implementations must call functions using their global names instead. Sass provides many built-in modules w

sass-lang.com

 

디버그

@debug

console.log()의 역할로 @debug를 사용해서 디버그 메세지를 남길 수 있다.

@debug "debuging";

 

@warn

console.warn()의 역할로 @warn을 사용해서 경고 메세지를 남길 수 있다.

@warn "Warning";

 

@error

throw와 유사하게 @error를 사용해서 에러 메세지를 남길 수 있으며 컴파일이 일어나지 않게 해준다.

@error "Error";

 


출처: 프로그래머스 프론트엔드 데브코스 

[Day 32] CSS 심화 (4)