Skip to content
On this page

Sass flow control

Title
Sass flow control
Category
CSS
Tags
Aliases
Sass flow control
Created
4 years ago
Updated
last year

Sass(SCSS) Syntax - 9. 흐름 제어(Flow Control)

❗️ 해당 글은 패스트캠퍼스 - 프론트엔드 개발 강의에서 HTML & CSS, SASS(SCSS) Part의 박영웅 강사님의 강의자료(Sass(SCSS) 완전 정복!)를 보며 정리한 것입니다.

흐름 제어(Flow Control)

if (함수)

조건의 값( true , false )에 따라 두 개의 표현식 중 하나만 반환한다.

JS의 조건부 삼항 연산자(conditional ternary operator)와 비슷한 개념

조건의 값이 true 이면 표현식1 을,

조건의 값이 false 이면 표현식2 를 실행한다.

if(조건, 표현식1, 표현식2)
if(조건, 표현식1, 표현식2)
$width: 555px;
div {
  width: if($width > 300px, $width, null);
}
$width: 555px;
div {
  width: if($width > 300px, $width, null);
}

컴파일하면

div {width: 555px;}
div {width: 555px;}

@if

@if 는 조건이 따른 분기 처리가 가능하다.

같이 사용할 수 있는 지시어로는 @else , @else if 가 있다.

// @if
@if (조건) {
  /* 조건이 참일 때 구문 */
}

// @if @else
@if (조건) {
  /* 조건이 참일 때 구문 */
} @else {
  /* 조건이 거짓일 때 구문 */
}

// @if @else if
@if (조건1) {
  /* 조건1이 참일 때 구문 */
} @else if (조건2) {
  /* 조건 1이 거짓이고, 조건2가 참일 때 구문 */
} @else {
  /* 모두 거짓일 때 구문 */
}
// @if
@if (조건) {
  /* 조건이 참일 때 구문 */
}

// @if @else
@if (조건) {
  /* 조건이 참일 때 구문 */
} @else {
  /* 조건이 거짓일 때 구문 */
}

// @if @else if
@if (조건1) {
  /* 조건1이 참일 때 구문 */
} @else if (조건2) {
  /* 조건 1이 거짓이고, 조건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;
  }
}
$color: orange;
div {
  @if $color == strawberry {
    color: #FE2E2E;
  } @else if $color == orange {
    color: #FE9A2E;
  } @else if $color == banana {
    color: #FFFF00;
  } @else {
    color: #2A1B0A;
  }
}

컴파일하면

div {color: #FE9A2E;}
div {color: #FE9A2E;}

논리 연산자 and , or , not 을 사용할 수 있다.

@function limitSize($size) {
  @if $size >= 0 and $size <= 200px {
    @return 200px;
  } @else {
    @return 800px;
  }
}

div {
  width: limitSize(180px);
  height: limitSize(340px);
}
@function limitSize($size) {
  @if $size >= 0 and $size <= 200px {
    @return 200px;
  } @else {
    @return 800px;
  }
}

div {
  width: limitSize(180px);
  height: limitSize(340px);
}

컴파일하면

div {width: 200px;height: 800px;}
div {width: 200px;height: 800px;}

내장 함수 unitless() (숫자에 단위가 있는지 여부를 반환하는 함수)를 사용하는 예제

@mixin pCenter($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 pCenter(10px, 20px);
}
.box2 {
  @include pCenter(50, 50, fixed);
}
.box3 {
  @include pCenter(100, 200, relative);
}
@mixin pCenter($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 pCenter(10px, 20px);
}
.box2 {
  @include pCenter(50, 50, fixed);
}
.box3 {
  @include pCenter(100, 200, relative);
}

컴파일하면

.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;}
.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;}

@for

@for 는 스타일을 반복적으로 출력한다.

@forthrough 를 사용하는 형식과 to 를 사용하는 형식으로 나뉜다.

두 형식은 종료 조건이 해석되는 방식이 다르다.

// through
// 종료 만큼 반복
@for $변수 from 시작 through 종료 {
  // 반복 내용
}

// to
// 종료 직전까지 반복
@for $변수 from 시작 to 종료 {
  // 반복 내용
}
// through
// 종료 만큼 반복
@for $변수 from 시작 through 종료 {
  // 반복 내용
}

// to
// 종료 직전까지 반복
@for $변수 from 시작 to 종료 {
  // 반복 내용
}

차이점을 이해하기 위한 다음 예제

변수는 관례상 $i 를 사용한다.

// 1부터 3번 반복
@for $i from 1 through 3 {
  .through:nth-child(#{$i}) {
    width : 20px * $i
  }
}

// 1부터 3 직전까지만 반복(2번 반복)
@for $i from 1 to 3 {
  .to:nth-child(#{$i}) {
    width : 20px * $i
  }
}
// 1부터 3번 반복
@for $i from 1 through 3 {
  .through:nth-child(#{$i}) {
    width : 20px * $i
  }
}

// 1부터 3 직전까지만 반복(2번 반복)
@for $i from 1 to 3 {
  .to:nth-child(#{$i}) {
    width : 20px * $i
  }
}

컴파일하면

.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; }
.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; }

to 는 주어진 값 직전까지만 반복해야할 경우 사용.

하지만 :nth-child() 에서 특히 유용하게 사용되는 @for 는 일반적으로 through 를 사용한다.

@each

@each 는 List와 Map 데이터를 반복할 때 사용.

for in 문과 유사하다.

@each $변수 in 데이터 {
  // 반복 내용
}
@each $변수 in 데이터 {
  // 반복 내용
}

List 데이터를 반복하는 예제.

// List Data
$fruits: (apple, orange, banana, mango);

.fruits {
  @each $fruit in $fruits {
    li.#{$fruit} {
      background: url("/images/#{$fruit}.png");
    }
  }
}
// List Data
$fruits: (apple, orange, banana, mango);

.fruits {
  @each $fruit in $fruits {
    li.#{$fruit} {
      background: url("/images/#{$fruit}.png");
    }
  }
}

컴파일하면

.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");}
.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 {
    $i: index($fruits, $fruit);
    li:nth-child(#{$i}) {
      left: 50px * $i;
    }
  }
}
$fruits: (apple, orange, banana, mango);

.fruits {
  @each $fruit in $fruits {
    $i: index($fruits, $fruit);
    li:nth-child(#{$i}) {
      left: 50px * $i;
    }
  }
}

컴파일하면

.fruits li:nth-child(1) {left: 50px;}.fruits li:nth-child(2) {left: 100px;}.fruits li:nth-child(3) {left: 150px;}.fruits li:nth-child(4) {left: 200px;}
.fruits li:nth-child(1) {left: 50px;}.fruits li:nth-child(2) {left: 100px;}.fruits li:nth-child(3) {left: 150px;}.fruits li:nth-child(4) {left: 200px;}

동시에 여러 개의 List 데이터를 반복 처리할 수도 있다.

$apple: (apple, korea);
$orange: (orange, china);
$banana: (banana, japan);

@each $fruit, $country in $apple, $orange, $banana {
  .box-#{$fruit} {
    background: url("/images/#{$country}.png");
  }
}
$apple: (apple, korea);
$orange: (orange, china);
$banana: (banana, japan);

@each $fruit, $country in $apple, $orange, $banana {
  .box-#{$fruit} {
    background: url("/images/#{$country}.png");
  }
}

컴파일하면

.box-apple {background: url("/images/korea.png");}.box-orange {background: url("/images/china.png");}.box-banana {background: url("/images/japan.png");}
.box-apple {background: url("/images/korea.png");}.box-orange {background: url("/images/china.png");}.box-banana {background: url("/images/japan.png");}

Map 데이터를 반복할 경우에는 하나의 데이터에 두 개의 변수가 필요하다.

@each $key변수, $value변수 in 데이터 {
  // 반복 내용
}
@each $key변수, $value변수 in 데이터 {
  // 반복 내용
}
$fruits-data: (
  apple: korea,
  orange: china,
  banana: japan
);

@each $fruit, $country in $fruits-data {
  .box-#{$fruit} {
    background: url("/images/#{$country}.png");
  }
}
$fruits-data: (
  apple: korea,
  orange: china,
  banana: japan
);

@each $fruit, $country in $fruits-data {
  .box-#{$fruit} {
    background: url("/images/#{$country}.png");
  }
}

컴파일하면

.box-apple {background: url("/images/korea.png");}.box-orange {background: url("/images/china.png");}.box-banana {background: url("/images/japan.png");}
.box-apple {background: url("/images/korea.png");}.box-orange {background: url("/images/china.png");}.box-banana {background: url("/images/japan.png");}

@while

@while 은 조건이 false 로 평가될 때까지 내용을 반복한다. while 문과 유사하게 잘못된 조건으로 인해 컴파일 중 무한 루프에 빠질 수 있다.

@while 조건 {
  // 반복 내용
}
@while 조건 {
  // 반복 내용
}
$i: 6;

@while $i > 0 {
  .item-#{$i} {
    width: 2px * $i;
  }
  $i: $i - 2;
}
$i: 6;

@while $i > 0 {
  .item-#{$i} {
    width: 2px * $i;
  }
  $i: $i - 2;
}

컴파일하면

.item-6 { width: 12px; }.item-4 { width: 8px; }.item-2 { width: 4px; }
.item-6 { width: 12px; }.item-4 { width: 8px; }.item-2 { width: 4px; }

Reference

패스트캠퍼스 - 프론트엔드 개발 강의 - HTML & CSS, SASS(SCSS) Part by ParkYoungWoong

Sass(SCSS) 완전 정복!

Released under the MIT License.