- 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로 반환 |