- CSS 주석은 /* ... */ 입니다.
- SCSS는 JavaScript처럼 두 가지 스타일의 주석을 사용합니다.
- Numbers : 숫자에 단위가 있거나 없습니다.
- Strings : 문자에 따옴표가 있거나 없습니다.
- Nulls : 속성값으로 null 이 사용되면 컴파일하지 않습니다.
- Lists : () 를 붙이거나 붙이지 않습니다.
- Maps : () 를 꼭 붙여야 합니다.
| 데이터 | 설명 | 예시 |
|---|---|---|
| Numbers | 숫자 | 1, .82, 20px, 2em... |
| Strings | 문자 | bold, relative, "/images/a.png", "dotum" |
| Colors | 색상 표현 | red, blue, #FFF00, 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) |
- Scss는 중첩 기능을 사용할 수 있습니다.
- 상위 선택자의 반복을 피하고 좀 더 편리하게 복잡한 구조를 작성할 수 있습니다.
.section {
width: 100%;
.list {
padding: 20px;
li {
float: left;
}
}
}
.section {
width: 100%;
}
.section .list {
padding: 20px;
}
.section .list li {
float: left;
}
- 중첩 안에서 & 키워드는 상위(부모) 선택자를 참조하여 치환합니다.
.btn {
position: absolute;
&.active {
color: red;
}
}
.list {
li {
&:last-child {
margin-right: 0;
}
}
}
.btn {
position: absolute;
}
.btn.active {
color: red;
}
.list li:last-child {
margin-right: 0;
}
- & 키워드가 참조한 상위 선택자로 치환되는 것이기 때문에 다음과 같이 응용할 수도 있습니다.
.fs {
&-small { font-size: 12px; }
&-medium { font-size: 14px; }
&-large { font-size: 16px; }
}
.fs-small { font-size: 12px; }
.fs-medium { font-size: 14px; }
.fs-large { font-size: 16px; }
- 중첩에서 벗어나고 싶을 때 @at-root 키워드를 사용합니다.
- 중첩 안에서 생성하되 중첩 밖에서 사용해야 할 경우에 유용합니다.
.list {
$w: 100px;
$h: 50px;
li {
width: $w;
height: $h;
}
@at-root .box {
width: $w;
height: $h;
}
}
.list li {
width: 100px;
height: 50px;
}
.box {
width: 100px;
height: 50px;
}
- font- , margin- 등과 같이 동일한 네임 스페이스를 가지는 속성들을 다음과 같이 사용할 수 있습니다.
.box {
font: {
weight: bold;
size: 10px;
family: sans-serif;
};
margin: {
top: 10px;
left: 20px;
};
padding: {
bottom: 40px;
right: 30px;
};
}
.box {
font-weight: bold;
font-size: 10px;
font-family: sans-serif;
margin-top: 10px;
margin-left: 20px;
padding-bottom: 40px;
padding-right: 30px;
}
- 반복적으로 사용되는 값을 변수로 지정할 수 있습니다.
- 변수 이름 앞에는 항상 $ 를 붙입니다. ($변수이름: 속성값;)
$color-primary: #e96900;
$url-images: "/assets/images/";
$w: 200px;
.box {
width: $w;
margin-left: $w;
background: $color-primary url($url-images + "bg.jpg");
}
.box {
width: 200px;
margin-left: 200px;
background: #e96900 url("/assets/images/bg.jpg");
}
- 변수는 사용 가능한 유효범위가 있습니다.
- 선언된 블록( {} ) 내에서만 유효범위를 가집니다.
- 변수 $color 는 .box1 의 블록 안에서 설정되었기 때문에, 블록 밖의 .box2에서는 사용할 수 없습니다.
.box1 {
$color: #111;
background: $color;
}
// Error
.box2 {
background: $color;
}
- 다음과 같이 변수에 변수를 할당할 수 있습니다.
$red: #FF0000;
$blue: #0000FF;
$color-primary: $blue;
$color-danger: $red;
.box {
color: $color-primary;
background: $color-danger;
}
.box {
color: #0000FF;
background: #FF0000;
}
- !global 플래그를 사용하면 변수의 유효범위를 전역(Global)로 설정할 수 있습니다.
.box1 {
$color: #111 !global;
background: $color;
}
.box2 {
background: $color;
}
.box1 {
background: #111;
}
.box2 {
background: #111;
}
- 대신 기존에 사용하던 같은 이름의 변수가 있을 경우 값이 덮어져 사용될 수 있습니다.
$color: #000;
.box1 {
$color: #111 !global;
background: $color;
}
.box2 {
background: $color;
}
.box3 {
$color: #222;
background: $color;
}
.box1 {
background: #111;
}
.box2 {
background: #111;
}
.box3 {
background: #222;
}
- !default 플래그는 할당되지 않은 변수의 초깃값을 설정합니다.
즉, 할당되어있는 변수가
있다면 변수가 기존 할당 값을 사용합니다.
$color-primary: red;
.box {
$color-primary: blue !default;
background: $color-primary;
}
.box {
background: red;
}
- #{} 를 이용해서 코드의 어디든지 변수 값을 넣을 수 있습니다.
$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=#{$family}");
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
- Sass는 기본적인 연산 기능을 지원합니다.
- 레이아웃 작업 시 상황에 맞게 크기를 계산을 하거나 정해진 값을 나눠서 작성할 경우 유용합니다.
| 종류 | 설명 | 주의사항 |
|---|---|---|
| + | 더하기 | |
| - | 빼기 | |
| * | 곱하기 | 하나 이상의 값이 반드시 숫자(Number) |
| / | 나누기 | 오른쪽 값이 반드시 숫자(Number) |
| % | 나머지 |
| 종류 | 설명 |
|---|---|
| == | 동등 |
| != | 부등 |
| < | 대소/보다 작은 |
| > | 대소/보다 큰 |
| <= | 대소 및 동등/보다 작거나 같은 |
| >= | 대소 및 동등/보다 크거나 같은 |
| 종류 | 설명 |
|---|---|
| and | 그리고 |
| or | 또는 |
| not | 부정 |
- 일반적으론 절댓값을 나타내는 px 단위로 연산을 합니다만, 상대적 단위(%, em, vw 등)의 연산의 경우 CSS calc()로 연산을 해야합니다.
width: 50% - 20px; // 단위 모순 에러(Incompatible units error) width: calc(50% - 20px); // 연산 가능
- / 를 나누기 연산 기능으로 사용하려면 다음과 같은 조건을 충족해야 합니다.
- 값 또는 그 일부가 변수에 저장되거나 함수에 의해 반환되는 경우
- 값이 () 로 묶여있는 경우
- 값이 다른 산술 표현식의 일부로 사용되는 경우
div {
$x: 100px;
width: $x / 2; // 변수에 저장된 값을 나누기
height: (100px / 2); // 괄호로 묶어서 나누기
font-size: 10px + 12px / 3; // 더하기 연산과 같이 사용
}
div {
width: 50px;
height: 50px;
font-size: 14px;
}
- 문자 연산에는 + 가 사용됩니다.
- 문자 연산의 결과는 첫 번째 피연사자를 기준으로 합니다.
- 첫 번째 피연산자에 따옴표가 붙어있다면 연산 결과를 따옴표로 묶습니다.
- 반대로 첫 번째 피연산자에 따옴표가 붙어있지 않다면 연산 결과도 따옴표를 처리하지 않습니다.
div::after {
content: "Hello " + World;
flex-flow: row + "-reverse" + " " + wrap
}
div::after {
content: "Hello World";
flex-flow: row-reverse wrap;
}
- @import 로 외부에서 가져온 Sass 파일은 모두 단일 CSS 출력 파일로 병합됩니다.
- 또한, 가져온 파일에 정의된 모든 변수 또는 Mixins 등을 주 파일에서 사용할 수 있습니다.
- @import 로 외부에서 가져온 Sass 파일에서 다른 Sass 파일을 @import 할 수 있으며 모두 단일 CSS로 병합됩니다.
- Sass @import 는 기본적으로 Sass 파일을 가져오는데, CSS @import 규칙으로 컴파일되는 몇 가지 상황이 있습니다.
- 위의 경우 CSS @import 규칙대로 컴파일 됩니다.
@import "hello.css"; @import "http://hello.com/hello"; @import url(hello); @import "hello" screen;
- 하나의 @import 로 여러 파일을 가져 올 수도 있습니다.
- 파일 이름은 , 로 구분합니다.
@import "header", "footer";
- 프로젝트 규모가 커지면 파일들을 header 나 side-menu 같이 각 기능과 부분으로 나워 유지보수가 쉽도록 관리하게 됩니다.
- 이 경우 파일이 점점 많아지는데, 모든 파일이 컴파일 시 각각의 .css 파일로 나눠서 저장된다면
관리나 성능 차원에서 문제가 될수 있습니다.
그래서 Sass는 Partials 기능을 지원합니다.
- 파일 이름 앞에 _ 를 붙여 (_header.css 와 같이) @import 로 가져오면 컴파일 시 ~.css 파일로 컴파일하지 않습니다.
- 다음과 같이 Sass/ 안에 3개의 Sass 파일이 있습니다. 메인 파일인 main.scss 에는 _ 를 사용하지 않겠습니다.
Sass-App # ... ├─scss │ ├─header.scss │ ├─side-menu.scss │ └─main.scss # ...
- 다음과 같이 Sass/ 안에 3개의 Sass 파일이 있습니다.
메인 파일인 main.scss 에는 _ 를 사용하지 않겠습니다.
Sass-App # ... ├─scss │ ├─header.scss │ ├─side-menu.scss │ └─main.scss # ...
- main.scss 로 나머지 ~.scss 파일을 가져옵니다.
// main.scss @import "header", "side-menu";
- 그리고 이 파일들을 css/디렉토리로 컴파일합니다. (컴파일은 예시로 node-sass로 진행)
$ node-sass scss --output css
- 아래처럼 별도의 파일로 컴파일되지 않고 사용됩니다.
Sass-App # ... ├─css │ ├─header.css │ ├─side-menu.css │ └─main.css ├─scss │ ├─header.scss │ ├─side-menu.scss │ └─main.scss # ...
- Webpack 이나 Parcel, Gulp 같은 일반적인 빌드툴에서는 Partials 기능을 사용할 필요 없이, 설정된 값에 따라 빌드됩니다. 하지만 되도록 _ 를 사용할 것을 권장합니다.
- CSS의 @media와 같은 개념입니다. SASS에서는 아래 방법처럼 CSS 다르게 작성할 수도 있습니다. 당연히 CSS @media 문법대로 작성도 가능합니다.
@media (min-width:768px) {
@media (max-width:1280px) {
.box1 {width:768px; margin:0 auto;}
}
}
@media (min-width:768px) and (max-width:1280px) {
.box1 {width:768px; margin:0 auto;}
}
- 확장은 의미하는 @extend는 기존에 설정되어 있는 CSS의 선택자의 속성을 재사용하면서 다른 선택자의 기능을 확장해 주는 문법입니다. (@extend 선택자;)
.btn {
display:block;
padding: 10px;
background: blue;
}
.btn-red {
@extend .btn;
background: red;
}
.btn-green {
@extend .btn;
background: green;
}
.btn,
.btn-red,
.btn-green {
display: block;
padding: 10px;
background: blue;
}
.btn-red {
background: red;
}
.btn-green {
background: green;
}
- 다만 @extend 를 잘못 사용하면 연관성 없는 값들이 한 장소에 묶이게 되어 소스 순서가 어그러져서 혼란을 주며, 심각한 경우 특정도(적용 우선순위 점수, specificity)가 엉망이 되면서 코드가 뜻대로 제어되지 않는 결과를 낳을 수도 있습니다.
.btn_wrap {
.btn {
display:block;
padding: 10px;
background: blue;
}
}
.btn_cont {
.btn-red {
@extend .btn;
background: red;
}
}
.btn_box {
.btn-green {
@extend .btn;
background: green;
}
}
.btn_wrap .btn,
.btn_wrap .btn_cont .btn-red,
.btn_cont .btn_wrap .btn-red,
.btn_wrap .btn_box .btn-green,
.btn_box .btn_wrap .btn-green {
display: block;
padding: 10px;
background: blue;
}
.btn_cont .btn-red {
background: red;
}
.btn_box .btn-green {
background: green;
}
- SASS의 문법을 설명할 때 @extend는 일반적으로 ‘사용을 권장하지 않는다’ 라고들 추천합니다.
- 정확한 기준으로 연관성이 있게 사용해야 한다면 괜찮은 사용법인 것 같습니다. 다만 매우 주의해서 사용해야 할 것 같습니다.
- mixin은 재사용할 그룹 선언으로 반복적인 작업을 획기적으로 줄여 줄 수 있어서 Sass에서 가장 쓰임새가 많습니다.
- @mixin을 정의하며, CSS 선택자 내부에 @include를 이용하며 호출됩니다.
- 정의된 @mixin에서 @include로 또 다른 @mixin 도 재사용이 가능합니다.
- SASS와 SCSS 문법이 다릅니다.
- @mixin은 함수(Functions)처럼 $매개변수를 가질 수 있습니다.
- @mixin에서 $매개변수가 없다면 ($매개변수:기본값) 삭제 가능합니다.
- @mixin의 매개변수에 기본값을 추가할 수 있으며 기본값은 초기화 값입니다.
- @include 전달 할 인수 값이 없다면 (인수) 삭제 가능합니다.
- @include 의 인수 값이 @mixin의 기본값과 같다면 삭제 가능합니다.
- @include 의 인수값에 @mixin의 매개변수 순서대로 전달됩니다.
- @mixin의 매개변수 순서와 상관 없이 전달하려면 @include의 인수값을 $매개변수: 기본값 으로 기입한다.
@mixin 믹스인이름($매개변수:기본값) {
// 매개변수 없다면 ($매개변수:기본값) 삭제 가능
// 매개변수와 기본값은 추가할 수 있으며 기본값은 초기화값
스타일;
}
.box1 {
@include 믹스인이름($매개변수:인수);
// 인수의 값이 기본값과 같다면 (인수) 삭제 가능
// 인수 적용은 @mixin의 매개변수 순서대로 전달
// 순서와 상관없이 전달하려면 $매개변수:인수 로 기입
}
// 믹스인 정의 =믹스인이름($매개변수: 기본값) 스타일 // 믹스인 사용 +믹스인이름($매개변수:인수)
- Scss에서 사용자 정의 함수를 정의할 수 있습니다.
- CSS 및 Mixin 에서 호출할 수 있습니다.
@function 함수이름($매개변수) {
// 매개변수가 없어도 함수이름()으로 기입 () 필수
@return 값
}
.box1 {
함수이름(인수);
}
@mixin 믹스인이름 {
함수이름(인수);
}
- SASS에서는 프로그래밍 언너와 같이 제어문을 이용하여 조건문 또는 변수 결합하여 아주 편리하게 값이 다른 여러 스타일들을 만들어 낼 수 있습니다.
- 조건의 값(true, false)에 따라 두 개의 표현식 중 하나만 반환합니다.
- Javascript 의 삼항연산자와 비슷합니다.
- 조건의 값이 true이면 표현식1을, 조건의 값이 false이면 표현식2를 실행합니다.
if(true, 1px, 2px); => 1px if(false, 1px, 2px); => 2px
- @if은 지시어의 따른 분기 처리가 가능하며, @else if(지시어), @else 로 복잡한 조건문을 작성할 수 있습니다.
- Javascript 의 if문과 비슷합니다.
@if (조건1) { //지시어를 감싸는 () 는 삭제 가능
/* 조건1이 참일 때 구문 */
} @else if (조건2) {
/* 조건2가 참일 때 구문 */
} @else {
/* 모두 거짓일 때 구문 */
}
@function limitSize($size) {
@if $size >= 0 and $size <= 200px {
@return 200px;
} @else {
@return 800px;
}
}
div {
width: limitSize(180px); // => 200px
height: limitSize(340px); // => 800px
}
- 반복문입니다.
- @for는 through를 사용하는 형식과 to를 사용하는 형식으로 나뉩니다.
- through는 종료만큼 반복하나 from은 종료 전까지만 반복합니다.
- Javascript 의 for문과 비슷합니다.
// through : 종료 만큼 반복
@for $변수 from 시작 through 종료 {
// 반복 내용
}
// to : 종료 직전까지 반복
@for $변수 from 시작 to 종료 {
// 반복 내용
}
@for $i from 1 through 3 { // 1부터 3번 반복
.li:nth-child(#{$i}) {
width : 20px * $i
}
}
@for $i from 1 to 3 { // 1부터 3 직전까지만 반복(2번 반복)
.li:nth-child(#{$i}) {
width : 20px * $i
}
}
- @each는 List와 Map 데이터를 반복할 때 사용합니다.
- Javascript 의 for in 문과 비슷합니다.
@Each - List Data
@each $변수 in 데이터 {
// 반복 내용
}
예1)
// List Data
$fruits: (apple, orange, banana);
.fruits {
@each $fruit in $fruits {
li.#{$fruit} {
background: url("/images/img_#{$fruit}.png");
}
}
}
.fruits li.apple {
background: url("/images/img_apple.png");
}
.fruits li.orange {
background: url("/images/img_orange.png");
}
.fruits li.banana {
background: url("/images/img_banana.png");
}
예2)
// List Data
$apple: (apple, korea, 1);
$orange: (orange, china, 2);
$banana: (banana, japan, 3);
@each $fruit, $country, $number in $apple, $orange, $banana {
.box-#{$fruit} {
background: url("/images/#{$number}/img_#{$country}.png");
}
}
.box-apple {
background: url("/images/1/img_korea.png");
}
.box-orange {
background: url("/images/2/img_china.png");
}
.box-banana {
background: url("/images/3/img_japan.png");
}
@Each - Map Data
@each $key변수, $value변수 in 데이터 {
// 반복 내용
}
예)
// Map Data
$fruits-data: (
apple: korea, // key : value
orange: china,
banana: japan
);
@each $fruit, $country in $fruits-data {
.box-#{$fruit} {
background: url("/images/img_#{$country}.png");
}
}
.box-apple {
background: url("/images/img_korea.png");
}
.box-orange {
background: url("/images/img_china.png");
}
.box-banana {
background: url("/images/img_japan.png");
}
- 내장함수는 다양하며 [Sass Built-in Functions] 에서 확인할 수 있습니다.
- 내장함수는 Color, List, Map, Math, Meta, Selector, String의 Type으로 구분됩니다.
- (tip) numbering이 Zero-based numbering 이 아닌 1부터 시작합니다.
| Type | Function | 설명 |
|---|---|---|
| Color | grayscale($color) | 색상을 회색으로 변환 |
|
opacify($color, $amount) fade-in($color, $amount) |
색상을 더 불투명하게 변환 | |
|
transparentize($color, $amount) fade-out($color, $amount) |
색상을 더 투명하게 변환 | |
| Strings | unquote($string) | 문자에서 따옴표를 제거 |
| quote($string) | 문자에 따옴표를 추가 | |
| to-upper-case($string) | 문자를 대문자를 변환 | |
| to-lower-case($string) | 문자를 소문자로 변환 | |
| Math | unit($number) | unit 반환 ex) unit(100px) => "px" unit(10px * 5em) => "em*px" |
| unitless($number) | 단위가 있는지 true/false 반환 ex) unitless(100) => true unitless(100px) => false |
|
| type-of($number) | Data type 반환 | |
| round($number) | 소숫점 이하 반올림 | |
| ceil($number) | 소숫점 이하 올림 | |
| floor($number) | 소숫점 이하 제거 | |
| percentage($number) | 숫자(단위 무시)를 백분율로 변환 | |
| min($numbers…) | 숫자 중 최소 값 찾음 | |
| max($numbers…) | 숫자 중 최대 값 찾음 | |
| List | length($list) | List의 개수를 반환 |
| nth($list, $n) | List에서 n번째 값을 반환 | |
| set-nth($list, $n, $value) | List에서 n번째 값을 다른 값으로 변경 | |
| append($list, $val, $separator: auto) | 리스트의 마지막에 단일 요소 추가 ex) append(10px 20px, 30px) |
|
| index($list, $value) | List에서 특정 값의 index를 반환 | |
| Map | map-get($map, $key) | Map에서 특정 key의 value를 반환 |
| map-keys($map) | Map에서 모든 key를 List로 반환 | |
| map-values($map) | Map에서 모든 value를 List로 반환 |