1. 주석
CSS 주석은 /* ... */ 이다.
Sass(SCSS)는 JavaScript처럼 두 가지 스타일의 주석을 사용한다.
// 컴파일되지 않는 주석
/* 컴파일되는 주석 */
- Sass :
/* 컴파일되는
* 여러 줄
* 주석 */
// Error
/* 컴파일되는
* 여러 줄
* 주석 */
SCSS는 각 줄에 *이 없어도 문제되지 않습니다. 따라서 기존 CSS와 호환이 쉽다.
- SCSS :
/*
컴파일되는
여러 줄
주석
*/
2. 데이터 종류
데이터 | 설명 | 예시 |
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) |
특이사항
- Numbers: 숫자에 단위가 있거나 없다.
- Strings: 문자에 따옴표가 있거나 없다.
- Nulls: 속성값으로 null이 사용되면 컴파일하지 않는다.
- Lists: ()를 붙이거나 붙이지 않는다.
- Maps: ()를 꼭 붙여야 한다.
3. 중첩
- 원래 작성 하던 CSS 중첩
.section {
width: 100%;
}
.section .list {
padding: 20px;
}
.section .list li {
float: left;
}
- SCSS 중첩 : 선택자의 반복을 피할 수 있음
.section {
width: 100%;
.list {
padding: 20px;
li {
float: left;
}
}
}
-1) 상위 선택자 참조
: 중첩 안에서 & 키워드는 상위(부모) 선택자를 참조하여 치환
- 원래 CSS
.btn {
position: absolute;
}
.btn.active { /*일치 선택자 : btn클래스 이면서, active 선택자 인것*/
color: red;
}
.list li:last-child {
margin-right: 0;
}
- SCSS
.btn {
position: absolute;
&.active {
color: red;
}
}
.list {
li {
&:last-child {
margin-right: 0;
}
}
}
<&사용 응용>
- 원래 CSS
.fs-small {
font-size: 12px;
}
.fs-medium {
font-size: 14px;
}
.fs-large {
font-size: 16px;
}
- SCSS
.fs {
&-small { font-size: 12px; }
&-medium { font-size: 14px; }
&-large { font-size: 16px; }
}
-2) 중첩 벗어나기
: 중첩에서 벗어나고 싶을 때 @at-root 키워드를 사용
- 원래 CSS
.list li {
width: 100px;
height: 50px;
}
.box {
width: 100px;
height: 50px;
}
- SCSS
.list {
$w: 100px;
$h: 50px;
li {
width: $w;
height: $h;
}
@at-root .box {
width: $w;
height: $h;
}
}
4. 중첩된 속성 정의
: font-, margin- 등과 같이 동일한 네임 스페이스를 가지는 속성들을 다음과 같이 사용할 수 있다.
- 원래 CSS
.box {
font-weight: bold;
font-size: 10px;
font-family: sans-serif;
margin-top: 10px;
margin-left: 20px;
padding-bottom: 40px;
padding-right: 30px;
}
- SCSS
.box {
font: {
weight: bold;
size: 10px;
family: sans-serif;
};
margin: {
top: 10px;
left: 20px;
};
padding: {
bottom: 40px;
right: 30px;
};
}
5. 변수
0) 변수
: 변수 이름 앞에는 항상 $를 붙인다.
- 원래 CSS
.box {
width: 200px;
margin-left: 200px;
background: #e96900 url("/assets/images/bg.jpg");
}
- SCSS
$color-primary: #e96900;
$url-images: "/assets/images/";
$w: 200px;
.box {
width: $w;
margin-left: $w;
background: $color-primary url($url-images + "bg.jpg");
}
-1) 유효범위
: 변수는 선언된 블록({}) 내에서만 유효범위를 가진다.
- 변수 $color는 .box1의 블록 안에서 설정되었기 때문에, 블록 밖의 .box2에서는 사용할 수 없다.
.box1 {
$color: #111;
background: $color;
}
// Error
.box2 {
background: $color;
}
<변수 재할당>
- 원래 CSS
.box {
color: #0000FF;
background: #FF0000;
}
- SCSS
$red: #FF0000;
$blue: #0000FF;
$color-primary: $blue;
$color-danger: $red;
.box {
color: $color-primary;
background: $color-danger;
}
-2) 전역 설정
: !global 플래그를 사용하면 변수의 유효범위를 전역(Global)로 설정할 수 있다.
- 원래 CSS
.box1 {
background: #111;
}
.box2 {
background: #111;
}
-SCSS
.box1 {
$color: #111 !global;
background: $color;
}
.box2 {
background: $color;
}
<응용,활용>
- CSS
.box1 {
background: #111;
}
.box2 {
background: #111;
}
.box3 {
background: #222;
}
- SCSS
$color: #000;
.box1 {
$color: #111 !global;
background: $color;
}
.box2 {
background: $color;
}
.box3 {
$color: #222;
background: $color;
}
-3) 초깃값 설정, 문자 보간
!default (초깃값 설정)
: !default 플래그는 할당되지 않은 변수의 초깃값을 설정 (즉, 할당되어있는 변수가 있다면 변수가 기존 할당 값을 사용)
$color-primary: red;
.box {
$color-primary: blue !default; /* red가 나옴*/
background: $color-primary;
}
좀 더 유용하게, ‘변수와 값을 설정하겠지만, 혹시 기존 변수가 있을 경우는 현재 설정하는 변수의 값은 사용하지 않겠다’는 의미로 쓸 수 있다.
예를 들어, Bootstrap 같은 외부 Sass(SCSS) 라이브러리를 연결했더니 변수 이름이 같아 내가 작성한 코드의 변수들이 Overwrite(덮어쓰기) 된다면 문제가 있을 거다.
반대로 내가 만든 Sass(SCSS) 라이브러리가 다른 사용자 코드의 변수들을 Overwrite 한다면, 사용자들은 그 라이브러리를 더 이상 사용하지 않을 것이다.
이럴 때 Sass(SCSS) 라이브러리(혹은 새롭게 만든 모듈)에서 사용하는 변수에 !default 플래그가 있다면 기존 코드(원본)를 Overwrite 하지 않고도 사용할 수 있다.
#{} (문자 보간)
: #{}를 이용해서 코드의 어디든지 변수 값을 넣을 수 있다.
$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=#{$family}");
/*#{$family} 는 family에 해당 변수가 들어가겠다는 의미!*/
Sass의 내장 함수 unquote()는 문자에서 따옴표를 제거한다.(CSS에는 없음)
6. 가져오기
0) 가져오기
원래 기존의 @import 사용법은 : @import url("경로");
SCSS에서의 사용법은 : @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;
-1) 여러 파일 가져오기, 파일 분할
여러파일 가져오기
하나의 @import로 여러 파일을 가져올 수도 있습니다.
파일 이름은 ,로 구분한다.
@import "header", "footer";
파일 분할
프로젝트 규모가 커지면 파일들을 header나 side-menu 같이 각 기능과 부분으로 나눠 유지보수가 쉽도록 관리하게 된다.
이 경우 파일이 점점 많아지는데, 모든 파일이 컴파일 시 각각의 ~.css 파일로 나눠서 저장된다면 관리나 성능 차원에서 문제가 될 수 있는데, 그래서 Sass는 Partials 기능을 지원한다.
파일 이름 앞에 _를 붙여(_header.scss와 같이) @import로 가져오면 컴파일 시 ~.css 파일로 컴파일하지 않는다.
scss안의 header.scss, side-menu.scss, main.scss가 있다.
Sass-App
# ...
├─scss
│ ├─header.scss
│ ├─side-menu.scss
│ └─main.scss
# ...
1. 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
# ...
2. 가져올 파일 이름에 _를 붙여보자 (main.scss에서는 _사용 X)
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 기능을 사용할 필요 없이, 설정된 값에 따라 빌드됩니다. 하지만 되도록 _를 사용할 것을 권장한다.
7. 연산
0) 연산
산술 연산자 :
종류 | 연산 | 주의사항 |
+ | 더하기 | |
- | 빼기 | |
* | 곱하기 | 하나 이상의 값이 반드시 숫자(Number) |
/ | 나누기 | 오른쪽 값이 반드시 숫자(Number) |
% | 나머지 |
비교 연산자 :
종류 | 설명 |
== | 동등 |
!= | 부등 |
< | 대소 / 보다 작은 |
> | 대소 / 보다 큰 |
<= | 대소 및 동등 / 보다 작거나 같은 |
>= | 대소 및 동등 / 보다 크거나 같은 |
논리(불린, Boolean) 연산자:
종류 | 설명 |
and | 그리고 |
or | 또는 |
not | 부정 |
-1) 숫자
- 상대적 단위 연산
: 일반적으론 절댓값을 나타내는 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의 속성값 분리를 위해서 /를 사용한다.
따라서 /를 나누기 연산 기능으로 사용하려면 다음과 같은 조건을 충족해야 한다.
- 값 또는 그 일부가 변수에 저장되거나 함수에 의해 반환되는 경우
- 값이 ()로 묶여있는 경우
- 값이 다른 산술 표현식의 일부로 사용되는 경우
div {
$x: 100px;
width: $x / 2; // 변수에 저장된 값을 나누기
height: (100px / 2); // 괄호로 묶어서 나누기
font-size: 10px + 12px / 3; // 더하기 연산과 같이 사용
}
/*아래와 같이 연산된다.*/
div {
width: 50px;
height: 50px;
font-size: 14px;
}
-2) 문자
문자 연산에는 +가 사용된다.
문자 연산의 결과는 첫 번째 피연산자를 기준으로 한다.
첫 번째 피연산자에 따옴표가 붙어있다면 연산 결과를 따옴표로 묶는다.
반대로 첫 번째 피연산자에 따옴표가 붙어있지 않다면 연산 결과도 따옴표를 처리하지 않는다.
div::after {
content: "Hello " + World;
flex-flow: row + "-reverse" + " " + wrap
}
/*아래와 같이 컴파일 된다.*/
div::after {
content: "Hello World";
flex-flow: row-reverse wrap;
}
-3) 색상
색상도 연산할 수 있다
div {
color: #123456 + #345678;
// R: 12 + 34 = 46
// G: 34 + 56 = 8a
// B: 56 + 78 = ce
background: rgba(50, 100, 150, .5) + rgba(10, 20, 30, .5);
// R: 50 + 10 = 60
// G: 100 + 20 = 120
// B: 150 + 30 = 180
// A: Alpha channels must be equal
}
/*아래와 같이 연산된다.*/
div {
color: #468ace;
background: rgba(60, 120, 180, 0.5);
}
RGBA에서 Alpha 값은 연산되지 않으며 서로 동일해야 다른 값의 연산이 가능하다.
Alpha 값을 연산하기 위한 다음과 같은 색상 함수(Color Functions)를 사용할 수 있다.
$color: rgba(10, 20, 30, .5);
div {
color: opacify($color, .3); // 30% 더 불투명하게 / 0.5 + 0.3
background-color: transparentize($color, .2); // 20% 더 투명하게 / 0.5 - 0.2
}
/*아래와 같이 연산된다.*/
div {
color: rgba(10, 20, 30, 0.8);
background-color: rgba(10, 20, 30, 0.3);
}
-4) 논리
Sass의 @if 조건문에서 사용되는 논리(Boolean) 연산에는 ‘그리고’,’ 또는’, ‘부정’이 있다.
자바스크립트 문법에 익숙하다면 &&, ||, !와 같은 기능으로 생각하면 된다.
$width: 90px;
div {
@if not ($width > 100px) {
height: 300px;
}
}
/*연산결과는 아래와 같다.*/
div {
height: 300px;
}
8. 재활용
-1) Mixin
: Sass Mixins는 스타일 시트 전체에서 재사용 할 CSS 선언 그룹 을 정의하는 아주 훌륭한 기능이다.
우선, Mixin은 두 가지만 기억하면 된다.
선언하기(@mixin)와 포함하기(@include) 이고, 만들어서(선언), 사용(포함)하는 거다!
-@mixin
:@mixin 지시어를 이용하여 스타일을 정의한다.
// SCSS
@mixin 믹스인이름 {
스타일;
}
// Sass
=믹스인이름
스타일
// SCSS
@mixin large-text {
font-size: 22px;
font-weight: bold;
font-family: sans-serif;
color: orange;
}
// Sass
=large-text
font-size: 22px
font-weight: bold
font-family: sans-serif
color: orange
Mixin은 선택자를 포함 가능하고 상위(부모) 요소 참조(& 같은)도 할 수 있다.
@mixin large-text {
font: {
size: 22px;
weight: bold;
family: sans-serif;
}
color: orange;
&::after {
content: "!!";
}
span.icon {
background: url("/images/icon.png");
}
}
-2) 재활용 - Include
-@include
: 선언된 Mixin을 사용(포함)하기 위해서는 @include가 필요하다.
// SCSS
@include 믹스인이름;
// Sass
+믹스인이름
SCSS:
// SCSS
h1 {
@include large-text;
}
div {
@include large-text;
}
// Sass
h1
+large-text
div
+large-tex
CSS:
h1 {
font-size: 22px;
font-weight: bold;
font-family: sans-serif;
color: orange;
}
h1::after {
content: "!!";
}
h1 span.icon {
background: url("/images/icon.png");
}
div {
font-size: 22px;
font-weight: bold;
font-family: sans-serif;
color: orange;
}
div::after {
content: "!!";
}
div span.icon {
background: url("/images/icon.png");
}
-3) 인수
Mixin은 함수(Functions)처럼 인수(Arguments)를 가질 수 있다.
// SCSS
@mixin 믹스인이름($매개변수) {
스타일;
}
@include 믹스인이름(인수);
// Sass
=믹스인이름($매개변수)
스타일
+믹스인이름(인수)
매개변수(Parameters)란 변수의 한 종류로, 제공되는 여러 데이터 중 하나를 가리키기 위해 사용된다.
제공되는 여러 데이터들을 전달인수(Arguments) 라고 부른다.
SCSS:
@mixin dash-line($width, $color) {
border: $width dashed $color;
}
.box1 { @include dash-line(1px, red); }
.box2 { @include dash-line(4px, blue); }
컴파일 :
.box1 {
border: 1px dashed red;
}
.box2 {
border: 4px dashed blue;
}
-4) 인수 - 기본값설정
인수(argument)는 기본값(default value)을 가질 수 있다.
@include 포함 단계에서 별도의 인수가 전달되지 않으면 기본값이 사용된다.
@mixin 믹스인이름($매개변수: 기본값) {
스타일;
}
SCSS:
@mixin dash-line($width: 1px, $color: black) {
border: $width dashed $color;
}
.box1 { @include dash-line; }
.box2 { @include dash-line(4px); }
컴파일 :
.box1 {
border: 1px dashed black;
}
.box2 {
border: 4px dashed black;
}
-5) 인수 - 키워드 인수
@mixin 믹스인이름($매개변수A: 기본값, $매개변수B: 기본값) {
스타일;
}
@include 믹스인이름($매개변수B: 인수);
Mixin에 전달할 인수를 입력할 때 명시적으로 키워드(변수)를 입력하여 작성할 수 있다.
별도의 인수 입력 순서를 필요로 하지 않아 편리하게 작성할 수 있다.
단, 작성하지 않은 인수가 적용될 수 있도록 기본값을 설정해 주는 것이 좋다.
SCSS:
@mixin position(
$p: absolute,
$t: null,
$b: null,
$l: null,
$r: null
) {
position: $p;
top: $t;
bottom: $b;
left: $l;
right: $r;
}
.absolute {
// 키워드 인수로 설정할 값만 전달
@include position($b: 10px, $r: 20px);
}
.fixed {
// 인수가 많아짐에 따라 가독성을 확보하기 위해 줄바꿈
@include position(
fixed,
$t: 30px,
$r: 40px
);
}
CSS:
.absolute {
position: absolute;
bottom: 10px;
right: 20px;
}
.fixed {
position: fixed;
top: 30px;
right: 40px;
}
-6) 인수 - 가변 인수
때때로 입력할 인수의 개수가 불확실한 경우가 있다.
그럴 경우 가변 인수를 사용할 수 있고,가변 인수는 매개변수 뒤에 ...을 붙여준다.
@mixin 믹스인이름($매개변수...) {
스타일;
}
@include 믹스인이름(인수A, 인수B, 인수C);
SCSS:
// 인수를 순서대로 하나씩 전달 받다가, 3번째 매개변수($bg-values)는 인수의 개수에 상관없이 받음
@mixin bg($width, $height, $bg-values...) {
width: $width;
height: $height;
background: $bg-values;
}
div {
// 위의 Mixin(bg) 설정에 맞게 인수를 순서대로 전달하다가 3번째 이후부터는 개수에 상관없이 전달
@include bg(
100px,
200px,
url("/images/a.png") no-repeat 10px 20px,
url("/images/b.png") no-repeat,
url("/images/c.png")
);
}
CSS:
div {
width: 100px;
height: 200px;
background: url("/images/a.png") no-repeat 10px 20px,
url("/images/b.png") no-repeat,
url("/images/c.png");
}
위에선 인수를 받는 매개변수에 ...을 사용하여 가변 인수를 활용했다.
이번엔 반대로 가변 인수를 전달할 값으로 사용해 보자.
SCSS:
@mixin font(
$style: normal,
$weight: normal,
$size: 16px,
$family: sans-serif
) {
font: {
style: $style;
weight: $weight;
size: $size;
family: $family;
}
}
div {
// 매개변수 순서와 개수에 맞게 전달
$font-values: italic, bold, 16px, sans-serif;
@include font($font-values...);
}
span {
// 필요한 값만 키워드 인수로 변수에 담아 전달
$font-values: (style: italic, size: 22px);
@include font($font-values...);
}
a {
// 필요한 값만 키워드 인수로 전달
@include font((weight: 900, family: monospace)...);
}
CSS:
div {
font-style: italic;
font-weight: bold;
font-size: 16px;
font-family: sans-serif;
}
span {
font-style: italic;
font-weight: normal;
font-size: 22px;
font-family: sans-serif;
}
a {
font-style: normal;
font-weight: 900;
font-size: 16px;
font-family: monospace;
-7) Content
선언된 Mixin에 @content이 포함되어 있다면 해당 부분에 원하는 스타일 블록 을 전달할 수 있다.
이 방식을 사용하여 기존 Mixin이 가지고 있는 기능에 선택자나 속성 등을 추가할 수 있다.
@mixin 믹스인이름() {
스타일;
@content;
}
@include 믹스인이름() {
// 스타일 블록
스타일;
}
SCSS:
@mixin icon($url) {
&::after {
content: $url;
@content;
}
}
.icon1 {
// icon Mixin의 기존 기능만 사용
@include icon("/images/icon.png");
}
.icon2 {
// icon Mixin에 스타일 블록을 추가하여 사용
@include icon("/images/icon.png") {
position: absolute;
};
}
컴파일:
.icon1::after {
content: "/images/icon.png";
}
.icon2::after {
content: "/images/icon.png";
position: absolute;
}
Mixin에게 전달된 스타일 블록은 Mixin의 범위가 아니라 스타일 블록이 정의된 범위에서 평가된다.
즉, Mixin의 매개변수는 전달된 스타일 블록 안에서 사용되지 않고 전역 값으로 해석된다.
전역 변수(Global variables)와 지역 변수(Local variables)를 생각하면 좀 더 쉽다.
SCSS:
$color: red;
@mixin colors($color: blue) {
// Mixin의 범위
@content;
background-color: $color;
border-color: $color;
}
div {
@include colors() {
// 스타일 블록이 정의된 범위
color: $color;
}
}
컴파일 :
div {
color: red;
background-color: blue;
border-color: blue;
}
Thanks to heropy.blog/2018/01/31/sass/
'Front-end > Web' 카테고리의 다른 글
부트스트랩 (0) | 2021.02.22 |
---|---|
SCSS 문법 - 확장, 함수, 조건문, 반복문, 내장함수 (0) | 2021.02.13 |
Sass(SCSS) 개요 (0) | 2021.02.13 |
CSS속성 - Grid (0) | 2021.02.12 |
CSS 속성 - 플렉스 (0) | 2021.02.12 |
댓글