이 글은 패스트캠퍼스 오늘 복습으로 [프론트엔드 개발 올인원 패키지 with React Online] 강의와 HEROPY 블로그의 Sass(SCSS)완전 정복!을 보고 정리한 글입니다.
함수와 Mixins은 거의 유사하지만 반환되는 내용이 다르다.
// Mixins
@mixin 믹스인이름($매개변수) {
스타일;
}
// Functions
@function 함수이름($매개변수) {
@return 값
}
Mixin은 스타일을 반환하지만 함수는 연산된 특정 값을
@return
지시어를 통해 반환한다.
// Mixin
@include 믹스인이름(인수);
// Functions
함수이름(인수)
사용 방법도 mixin은 @include로 가져와서 사용하고, 인수가 없는 경우에 괄호를 생략할 수 있지만, 함수는 그냥 이름만 가져와서 사용하고, 인수가 없는 경우에도 괄호를 붙여서 사용해야한다.
@function columns($number: 1, $columns: 12, $width: 1200px) {
@return $width * ($number/$columns);
}
.container {
$width: 1200px;
width: $width;
.item:nth-child(1) {
width: columns();
}
.item:nth-child(2) {
width: columns(8);
}
.item:nth-child(3) {
width: columns(3, $width: $width);
}
}
.container {
width: 1200px;
}
.container .item:nth-child(1) {
width: 100px;
}
.container .item:nth-child(2) {
width: 800px;
}
.container .item:nth-child(3) {
width: 300px;
}
mixin과 마찬가지로 매개변수의 기본값을 설정할 수 있고, 인자에 키워드 인수를 사용하여 원하는 매개변수의 값을 넣어줄 수 있다.
함수는 @include
와 같은 별도의 지시어 없이 사용하기 때문에 지정한 함수와 내장함수의 이름이 충돌 할 수 있다. 따라서 별도의 접두어를 붙여주는 것이 좋다.
// 내가 정의한 함수
@function extract-red($color) {
// 내장 함수
@return rgb(red($color), 0, 0);
}
div {
color: extract-red(#D55A93);
}
red() 가 내장함수이기 때문에 별도의 접두어를 붙여서 사용! 또는 특별한 이름을 접두어로 사용할 수도 있다.
EX)my-custom-func-red()
조건의 값에 따라 두 개의 표현식 중 하나만 반환 함.(조건부 삼항 연산자와 비슷)
조건 값이 true이면 표현식 1을,
조건 값이 false이면 표현식 2를 실행한다.
if(조건, 표현식1, 표현식2)
$width: 100px;
div {
width: if($width > 300px, $width, null);
height: 100px;
}
div {
height: 100px;
}
@if
지시어는 조건에 따른 분기 처리가 가능하고 if문과 유사하다.
// @if
@if (조건) {
/* 조건이 참일 때 구문 */
}
// @if @else
@if (조건) {
/* 조건이 참일 때 구문 */
} @else {
/* 조건이 거짓일 때 구문 */
}
// @if @else if
@if (조건1) {
/* 조건1이 참일 때 구문 */
} @else if (조건2) {
/* 조건2가 참일 때 구문 */
} @else {
/* 모두 거짓일 때 구문 */
}
$color: orange;
div {
@if $color == strawberry {
color: #FE2E2E;
} @else if $color == orange {
color: #FE9A2E;
} @else if $color == banana {
color: #FFFF00;
} @else {
color: #2A1B0A;
}
}
css 결과
div {
color: #FE9A2E;
}
조건에
()
는 생략이 가능하기 때문에,()
없이 작성하는 방법이 좀 더 편리할 수 있다.
@function limitSize($size) {
@if ($size >= 0 and $size <= 200px) {
@return 200px;
} @else {
@return 800px;
}
}
div {
width: limitSize(180px);
height: limitSize(340px);
}
css 컴파일
div {
width: 200px;
height: 800px;
}
@mixin positionCenter($w, $h, $p: absolute) {
@if ($p == absolute or $p == fixed or not $p == relative or not $p == static) {
width: if(unitless($w), #{$w}px, $w);
height: if(unitless($h), #{$h}px, $h);
position: $p;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
}
.box1 {
@include positionCenter(10px, 20px);
}
.box2 {
@include positionCenter(50, 50, fixed);
}
.box3 {
@include positionCenter(100, 200, relative);
}
css 결과
.box1 {
width: 10px;
height: 20px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.box2 {
width: 50px;
height: 50px;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
다음과 같이 조건에는 논리 연산자를 사용할 수 있고
unitless
함수는 단위가 붙어 있지 않으면 true를, 붙어 있으면 false를 반환하여 문자보간을 같이 사용해 붙어있지 않은 경우 px를 붙여주었다.
box3의 css의 경우 position 속성에서 걸려 css결과가 나오지 않았다.
@for
는 스타일을 반복적으로 출력한다.
through
를 사용하는 형식과 to
를 사용하는 형식으로 나뉜다.
둘의 차이는 종료 조건이 해석되는 방식
// through
// 종료 만큼 반복
@for $변수 from 시작 through 종료 {
// 반복 내용
}
// to
// 종료 직전까지 반복
@for $변수 from 시작 to 종료 {
// 반복 내용
}
through는 종료 까지!, to는 종료 직전까지!
@for $index from 1 through 3 {
.through:nth-child(#{$index}) {
width: 20px * $index;
}
}
@for $index from 1 to 3 {
.to:nth-child(#{$index}) {
width: 20px * $index;
}
}
css결과
.through:nth-child(1) {
width: 20px;
}
.through:nth-child(2) {
width: 40px;
}
.through:nth-child(3) {
width: 60px;
}
.to:nth-child(1) {
width: 20px;
}
.to:nth-child(2) {
width: 40px;
}
@each
는 List와 Map 데이터를 반복할 때 사용한다.
@each $변수 in 데이터 {
// 반복 내용
}
// List Data
$fruits: (apple, orange, banana, mango);
.fruits {
@each $fruit in $fruits {
li.#{$fruit} {
background: url("/images/#{$fruit}.png");
}
}
}
css결과
.fruits li.apple {
background: url("/images/apple.png");
}
.fruits li.orange {
background: url("/images/orange.png");
}
.fruits li.banana {
background: url("/images/banana.png");
}
.fruits li.mango {
background: url("/images/mango.png");
}
반복되는 리스트의 index값이 필요하다면
index()
내장함수 사용도 가능
아래에 그 예제가 있음.
$fruits: apple, orange, banana, mango;
.fruits {
@each $fruit in $fruits {
$index: index($fruits, $fruit);
li:nth-child(#{$index}) {
left: 50px * $index;
background: url("/images/#{$fruit}.png");
}
}
}
css로 컴파일한 결과
.fruits li:nth-child(1) {
left: 50px;
background: url("/images/apple.png");
}
.fruits li:nth-child(2) {
left: 100px;
background: url("/images/orange.png");
}
.fruits li:nth-child(3) {
left: 150px;
background: url("/images/banana.png");
}
.fruits li:nth-child(4) {
left: 200px;
background: url("/images/mango.png");
}
index함수를 사용하여 index를 가져와 nth-child와 같은 필요한 부분에 사용할 수 있다.
$fruits-data: (
apple: korea,
orange: china,
banana: japan
);
@each $fruit, $country in $fruits-data {
// map-keys($fruits-data) => (apple, orange, banana)
// map-values($fruits-data) => (korea, china, japan)
$fruits-data--key-list: map-keys($fruits-data);
$index: index($fruits-data--key-list, $fruit);
.box-#{$fruit} {
width: 100px * $index;
background: url("/iamges/#{$country}.png");
}
}
css로 컴파일한 결과
.box-apple {
width: 100px;
background: url("/iamges/korea.png");
}
.box-orange {
width: 200px;
background: url("/iamges/china.png");
}
.box-banana {
width: 300px;
background: url("/iamges/japan.png");
}
index가 필요한 경우에 map같은 자료구조에 데이터가 존재하면
map-keys
또는map-values
라는 내장함수를 이용하여 리스트 데이터로 변환한 후, 인덱스 값을 추출해 내야한다.
index 값이 필요 없다면 굳이 이렇게 안해도 됨
@while
은 조건이 false
로 평가될 때까지 내용을 반복한다.
그러나 컴파일 중 무한 루프에 빠질 수 있어서 사용을 권하지 않는다.
@while 조건 {
// 반복 내용
}
$i: 6;
@while $i > 0 {
.item-#{$i} {
width: 2px * $i;
}
$i: $i - 2;
}
css 결과
.item-6 { width: 12px; }
.item-4 { width: 8px; }
.item-2 { width: 4px; }
Sass Built-in Functions에서 모든 내장 함수를 확인할 수 있다.