CSS 전처리기 SASS SCSS
2022. 1. 24. 12:56ㆍStudy/Publishing
Sass는 CSS전처리기(Preprocessor)라고도 합니다.
CSS 전처리기란?
CSS 전(예비)처리기 입니다.
보통 언급되는 전치리기 3대장으로 Less, Sass(SCSS), Styleus가 있습니다.
그 중 Sass는 2006년부터 시작하여 가장 오래된 CSS 확장 언어이며, 그만큼 높은 성숙도와 많은 커뮤니티를 가지고 있고 기능도 훌륭합니다.
Sass와 SCSS의 차이점?
Sass (Syntactically Awesome Style Sheets)의 3버전에서 새롭게 등장한 SCSS는 CSS 구문과 완전히 호환되도록 새로운 구문을 도입해 만든 Sass의 모든 기능을 지원하는 CSS의 상위집합(Superset) 입니다.
즉, SCSS는 CSS와 거의 같은 문법으로 Sass 기능을 지원합니다.
Sass와 SCSS는 문법에 약간의 차이가 있습니다.
간단하게 설명해서
Sass | SCSS |
들여쓰기로 구분 | { } 중괄호, ; 세미콜론 사용 |
=와 + 기호로 Mixins 기능 사용 | @Mixin과 @include로 Mixins 기능 사용 |
Sass
.list
width: 100px
float: left
li
color: red
background:url('./image.jpg')
$:last-child
margin-right:-10px
=border-radius($radius)
border-radius: $radius
.box
+border-radius(10px)
SCSS
.list {
width: 100px;
float:left;
li{
color: red;
background:url('./images.jpg');
&:last-child{
margin-right:-10px;
}
}
}
@mixin border-radius($radius){
border-radius: $radius;
}
.box{ @include border-radius(10px); }
Syntax
주석 Comment
Javascript처럼 두 가지 스타일의 주석을 사용합니다.
// 컴파일되지 않는 주석
/* 컴파일되는 주석 */
데이터 종류 Data Types
데이터 | 설명 | 예시 |
Numbers | 숫자 | 1, 82, 20px, 2em ... |
Strings | 문자 | bold, relative, "/images/a.png", "dotum" |
Colors | 색상 표현 | red, blue, #FFFF00, rgba(255,0,0,.5) |
Booleans | 논리 | true, false |
Nulls | 아무것도 없음 | null |
Lists | 공백이나 , 로 구분된 값의 목록 | (apple, orange, banana), apple orange |
Maps | Lists와 유사하나 값이 key: value 형태 | (apple: a, orange: o, banana: b) |
중첩 Nesting
Sass는 중첩 기능을 사용할 수 있습니다.
SCSS
.section{
width:100%;
.list{
padding:20px;
li{
float:left;
}
}
}
Compiled to
.section{width:100%;}
.section .list{padding: 20px;}
.section .list li{float:left;}
Ampersand (상위 선택자 참조)
중첩 안에서 & 키워드는 상위(부모) 선택자를 참조하여 치환합니다.
SCSS
.btn{
position: absolute;
&.active{
color: red;
}
}
.list{
li{
&:last-child{
margin-right:0;
}
}
}
/* &키워드가 참조한 상위 선택자로 치환되는 것이기 때문에 다음과 같이 응용할 수도 있습니다.*/
.fs{
&-small {font-size: 12px;}
&-medium {font-size: 14px;}
&-large {font-size:16px;}
}
Compiled to
.btn{position:absolute;}
.btn.active{color: red;}
.list li:last-child{margin-right:0;}
.fs-small{font-size: 12px;}
.fs-medium{font-size: 14px;}
.fs-large{font-size: 16px;}
@at-root (중첩 벗어나기)
중첩에서 벗어나고 싶을 때 @at-root 키워드를 사용합니다.
중첩 안에서 생성하되 중첩 밖에서 사용해야 경우에 유용합니다.
SCSS
.list{
$w: 100px;
$h: 50px;
li{
width:$w;
height:$h;
}
@at-root .box{
width: &w;
height: &h;
}
}
/* 잘못된 예제 */
.box{
width:$w;
height:$h;
}
잘못된 예제처럼 .list 안에 있는 특정 변수를 범위 밖에서 사용할 수 없기 때문에, 위 예제처럼 @at-root 키워드를 사용해야 합니다.
Compiled to
.list li{width:100px; height:50px;}
.box{width:100px; height:50px;}
중첩된 속성
font-, margin- 등과 같이 동일한 네임 스페이스를 가지는 속성들을 다음과 같이 사용할 수 있습니다.
SCSS
.box{
font: {
weight: bold;
size: 10px;
family: sans-serif;
};
margin: {
top: 10px;
left:20px;
};
padding: {
bottom:40px;
right:30px;
};
}
Compiled to
.box{
font-weight:bold;
font-wize: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");
}
Compiled to
.box {
width: 200px;
margin-left: 200px;
background: #e96900 url("/assets/images/bg.jpg");
}
변수 유효범위 (Variable Scope)
변수는 사용 가능한 유효범위가 있습니다.
선언된 블록{ } 내에서만 유효범위를 가집니다.
변수 $color는 .box1의 블록 안에서 설정되었기 때문에 블록 밖의 .box2 에서는 사용할 수 없습니다.
.box1 {
$color: #111;
background: $color;
}
// Error
.box2 {
background: $color;
}
변수 재 할당 (Variable Reassignment)
다음과 같이 변수에 변수를 할당할 수 있습니다.
SCSS
$red: #FF0000;
$blue: #0000FF;
$color-primary: $blue;
$color-danger: $red;
.box{
color: $color-primary;
background: $color-danger;
}
Compiled to
.box {
color: #0000FF;
background: #FF0000;
}
!global (전역 설정)
!global 플래그를 사용하면 변수 유효범위를 전역 (Global)로 설정할 수 있습니다.
대신 기존에 사용하던 같은 이름의 변수가 있을 경우 값이 덮어져 사용될 수 있습니다.
SCSS
.box1 {
$color: #111 !global;
background: $color;
}
.box2 {
background: $color;
}
Compiled to
.box1 {background: #111;}
.box2 {background: #111;}
!default (초기값 설정)
!default 플래그는 할당되지 않은 변수의 초기값을 설정합니다.
즉, 할당되어있는 변수가 있다면 변수가 기존 할당 값을 사용합니다.
SCSS
$color-primary: red;
.box {
$color-primary: blue !default;
background: $color-primary;
}
Compiled to
.box {background: red;}
좀 더 유용하게, '변수와 값을 설정하겠지만, 혹시 기존 변수가 있을 경우는 현재 설정하는 변수의 값은 사용하지 않겠다'는 의미로 슬 수 있습니다.
예를 들어, Bootstrap 같은 외부 Sass(SCSS) 라이브러리를 연결했더니 변수 이름이 같아 내가 작성한 코드의 변수들이 Overwrite (덮어쓰기) 된다면 문제가 있겠죠.
반대로 내가 만든 Sass(SCSS) 라이브러리가 다른 사용자 코드의 변수들을 Overwrite 한다면, 사용자들은 그 라이브러리를 더 이상 사용하지 않을 것입니다.
이럴 때 Sass(SCSS) 라이브러리 (혹은 새롭게 만든 모듈)에서 사용하는 변수에 !default 플래그가 있다면 기존 코드(원본)를 Overwrite 하지 않고도 사용할 수 있습니다.
// _config.scss
$color-active: red;
// main.scss
@import 'config';
$color-active: blue !default;
.box{
background: $color-active; // red
}
다음은 Bootstrap 코드 (_variables.scss)의 일부입니다.
// stylelint-disable
$white: #fff !default;
$gray-100: #f8f9fa !default;
$gray-200: #e9ecef !default;
$gray-300: #dee2e6 !default;
$gray-400: #ced4da !default;
$gray-500: #adb5bd !default;
$gray-600: #6c757d !default;
$gray-700: #495057 !default;
$gray-800: #343a40 !default;
$gray-900: #212529 !default;
$black: #000 !default;
#{ } (문자 보간)
#{ } 를 이용해서 코드의 어디든지 변수 값을 넣을 수 있습니다.
$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=#{$family}");
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
Sass의 내장 함수 unquote()는 문자에서 따옴표를 제거합니다.
가져오기 (Import)
@import 로 외부에서 가져온 Sass 파일은 모두 단일 CSS 출력 파일로 병합됩니다.
또한, 가져온 파일에 정의된 모든 변수 또는 Mixins 등을 주 파일에서 사용할 수 있습니다.
Sass @import는 기본으로 Sass 파일을 가져오는데, CSS @import 규칙으로 컴파일되는 몇 가지 상황이 있습니다.
- 파일 확장자가 .css 일 때
- 파일 이름이 http:// 로 시작하는 경우
- url() 이 붙었을 경우
- 미디어쿼리가 있는 경우
위의 경우 CSS @import 규칙대로 컴파일 됩니다.
@import "hello.css";
@import "http://hello.com/hello";
@import url(hello);
@import "hello" screen;
여러 파일 가져오기
하나의 @import로 여러 파일을 가져올 수도 있습니다.
파일 이름은 , 로 구분합니다.
@import "header", "footer";
파일 분할 (Partials)
프로젝트 규모가 커지면 파일들을 header나 side-menu 같이 각 기능과 부분으로 나눠 유지보수가 쉽도록 관리하게 됩니다.
이 경우 파일이 점점 많아지는데, 모든 파일이 컴파일 시 각각의 ~.css 파일로 나눠서 저장된다면 관리나 성능 차원에서 문제가 될 수 있겠죠.
그래서 Sass는 Partials 기능을 지원합니다.
파일 이름 앞에 _를 붙여 (_header.scss와 같이) @import로 가져오면 컴파일 시 ~.css 파일로 컴파일하지 않습니다.
예를 들어보겠습니다.
다음과 같이 scss/ 안에 3개의 Sass 파일이 있습니다.
Sass-App
# ...
├ scss
│ ├ header.scss
│ ├ side-menu.scss
│ └ main.scss
# ...
main.scss로 나머지 ~.scss 파일을 가져옵니다.
// main.scss
@import "header", "side-menu";
그리고 이 파일들을 css/ 디렉토리로 컴파일 합니다.
(컴파일은 위에서 설명한 node-sass 로 진행합니다.)
# `scss`디렉토리에 있는 파일들을 `css`디렉토리로 컴파일
$ node-sass scss --output css
컴파일 후 확인하면 아래와 같이 scss/ 에 있던 파일들이 css/ 안에 각각 하나씩 파일로 컴파일됩니다.
Sass-App
# ...
├─css
│ ├─header.css
│ ├─side-menu.css
│ └─main.css
├─scss
│ ├─header.scss
│ ├─side-menu.scss
│ └─main.scss
# ...
자, 이번에는 가져올 파일 이름이 _를 붙이겠습니다.
메인 파일은 main.css 에서는 _를 사용하지 않습니다.
Sass-App
# ...
├─scss
│ ├─_header.scss
│ ├─_side-menu.scss
│ └─main.scss
# ...
// main.scss
@import "header", "side-menu";
같은 방법으로 컴파일 하면
$ node-sass scss --output css
아래처럼 별도의 파일로 컴파일되지 않고 사용됩니다.
Sass-App
# ...
├─css
│ └─main.css # main + header + side-menu
├─scss
│ ├─header.scss
│ ├─side-menu.scss
│ └─main.scss
# ...
Webpack 이나 Parcel, Gulp 같은 일반적인 빌드툴에서는 Partials 기능을 사용할 필요 없이, 설정된 값에 따라 빌드됩니다. 하지만 되도록 _를 사용할 것을 권장합니다.
연산 (Operations)
Sass는 기본적인 연산 기능을 지원합니다.
레이아웃 작업 시 상황에 맞게 크기를 계산하거나 정해진 값을 나눠서 작성할 경우 유용합니다.
다음은 Sass에서 사용 가능한 연산자 종류 입니다.
산술연산자
종류 | 설명 | 주의사항 |
+ | 더하기 | |
- | 빼기 | |
* | 곱하기 | 하나 이상의 값이 반드시 숫자(Number) |
/ | 나누기 | 오른쪽 값이 반드시 숫자 (Number) |
% | 나머지 |
비교연산자
종류 | 설명 |
== | 동등 |
!= | 부등 |
< | 대소 / 보다 작은 |
> | 대소 / 보다 큰 |
<= | 대소 및 동등 / 보다 작거나 같은 |
>= | 대소 및 동등 / 보다 크거나 같은 |
논리 (불린, Boolea) 연산자
종류 | 설명 |
and | 그리고 |
or | 또는 |
not | 부정 |
숫자 (Numbers)
일반적으론 절대값을 나타내는 px 단위로 연산을 합니다만, 상대적 단위 (%, em, vw 등)의 연산의 경우 CSS calc()로 연산해야 합니다.
width: 50% - 20px; // 단위 모순 에러(Incompatible units error)
width: calc(50% - 20px); // 연산 가능
나누기 연산의 주의사항
CSS는 속성 값의 숫자를 분리하는 방법으로 / 를 허용하기 때문에 / 가 나누기 연산으로 사용되지 않을 수 있습니다.
예를 들어, font: 16px / 22px serif; 같은 경우 font-size 16px와 line-height 22px 의 속성값 분리를 위해서 /를 사용합니다.
아래 예제를 보면 나누기 연산자만 연산 되지 않고 그대로 컴파일됩니다.
SCSS
div {
width: 20px + 20px; // 더하기
height: 40px - 10px; // 빼기
font-size: 10px * 2; // 곱하기
margin: 30px / 2; // 나누기
}
Compiled to
div {
width: 40px; /* OK */
height: 30px; /* OK */
font-size: 20px; /* OK */
margin: 30px / 2; /* ?? */
}
따라서 / 를 나누기 연산 기능으로 사용하려면 다음과 같은 조건을 충족해야 합니다.
- 값 또는 그 일부가 변수에 저자오디거나 함수에 의해 반환되는 경우
- 값이 ()로 묶여있는 경우
- 값이 다른 산술 표현식의 일부로 사용되는 경우
SCSS
div {
$x: 100px;
width: $x / 2; // 변수에 저장된 값을 나누기
height: (100px / 2); // 괄호로 묶어서 나누기
font-size: 10px + 12px / 3; // 더하기 연산과 같이 사용
}
Compiled to
div {
width: 50px;
height: 50px;
font-size: 14px;
}
문자 (String)
참고 :)
'Study > Publishing' 카테고리의 다른 글
input 태그의 pattern 속성과 정규표현식 (0) | 2022.05.02 |
---|---|
세로쓰기 모드 writing-mode, 글자 타이핑 효과 (0) | 2022.03.18 |
단위 em, rem, vw, vh, vmin, vmax (0) | 2022.01.12 |
CSS3 grid (0) | 2022.01.11 |
CSS3 filter (0) | 2022.01.07 |