연습장

03. Nesting, import, extend, 조건과 반복, Mixin, Function 본문

Sass

03. Nesting, import, extend, 조건과 반복, Mixin, Function

js0616 2024. 8. 8. 04:47

https://poiemaweb.com/sass-css-extention

 

Sass - CSS Extensions | PoiemaWeb

Sass의 유용한 확장 기능으로 선언을 중첩(nesting)하는 것이다. CSS는 후손 셀렉터(Descendant Combinator)의 경우, 부모요소를 기술하여야 한다.

poiemaweb.com

 

 

1. Nesting
선언을 중첩(nesting)하는 것이다. CSS는 후손 셀렉터(Descendant combinator)의 경우 부모요소를 기술하여야 한다.

 

css

#navbar {
    width: 80%;
    height: 23px;
  }
 
  #navbar ul {
    list-style-type: none;
  }
 
  #navbar li {
    float: left;
  }
 
  #navbar li a {
    font-weight: bold;
  }

 

scss

#navbar {
    width: 80%;
    height: 23px;
 
    ul {
      list-style-type: none;
    }
 
    li {
      float: left;
      a {
        font-weight: bold;
      }
    }
  }

 

후손 셀렉터를 간단히 기술할 수 있다. 또한 HTML의 구조를 반영한 CSS를 기술할 수 있다.

 

기존에는 조상? 요소를 위의 css 처럼 모두 작성해야 하는데, 

Nesting 을 사용하면, 경우 상위 요소의 { } 안에서 작성 할 수 있음. 

단, 너무 깊은 nesting은 가독성을 나쁘게 하고 셀렉터를 복잡하게 만든다.


부모 요소의 참조가 필요한 경우 &를 사용한다. 

ex) :hover 또는 ::before 등의 가상 클래스 선택자 (Pseudo-class selector)를 지정하는 경우 부모 요소의 참조가 필요하다.

 

.myAnchor {
    color: blue;
 
    // .myAnchor:hover
    &:hover {
      text-decoration: underline;
    }
 
    // .myAnchor:visited
    &:visited {
      color: purple;
    }
  }

nesting은 프로퍼티에도 사용할 수 있다.

 

scss

.funky {
    font: {
      family: fantasy;
      size: 30em;
      weight: bold;
    }
  }

 

css

.funky {
    font-family: fantasy;
    font-size: 30em;
    font-weight: bold;
  }

2. @-Rules and Directives


2.1 @import
1개의 CSS 파일에 모든 스타일을 기술하면 유지보수하기 힘들고 가독성이 좋지 않다. 

기능에 따라 CSS 파일을 분리하면 재사용 및 유지보수 측면에서 유리하다. 

따라서 룰을 정하여 파일을 분리하여 개발하는 것은 효과적인 방법이다.

Sass는 @import directive를 사용하여 분리된 stylesheet 파일을 import할 수 있다. 

Sass는 기존의 CSS @import보다 편리한 기능을 제공한다.

@import "foo.scss";

// 확장자는 생략 가능하다
@import "foo";

// 여러 개의 파일을 한번에 임포트할 수 있다.
@import "rounded-corners", "text-shadow";

// 변수를 사용해 문자열을 생성하여 임포트할 수도 있다.
$family: "Open+Sans";
@import url("http://fonts.googleapis.com/css?family=#{$family}");

 

여러 개의 파일로 분할하는 것 또는 분할된 파일을 partial이라 하며, 

partial된 Sass 파일명의 선두에는 underscore(_)를 붙인다. (_reset.scss, _module.scss, _print.scss)

 _의 의미는 import는 수행하되 CSS로의 트랜스파일링은 수행하지 말라는 의미를 갖는다.

 

 

 

예를 들면 다음과 같다.

// partial/_vars.scss
$width: 960px;
// partial/_vars.scss
$width: 960px;
// partial/_sidebar.scss
#sidebar {
    width: $width;
  }
// partial/_footer.scss
#footer {
    width: $width;
  } 
// style.scss
@import "partial/vars";
@import "partial/header";
@import "partial/sidebar";
@import "partial/footer";

 

 

단점

  • pure CSS도 @import를 사용하기 때문에 혼란스러울 수 있다.
  • 같은 파일을 여러번 import 하면 코드 충돌과 중복 코드로 인해 컴파일 속도가 느려질 수 있다.
  • 모든 변수와 함수가 전역으로 관리되기 때문에 같은 이름의 변수나 함수를 사용하면 먼저 선언된 것들이 무시된다.
  • 어디서 가져온 변수 or 함수인지 직관적으로 알 수 없다.

 

https://blog.naver.com/pink_candy02/222347151036

 


@use

  • @import를 사용할 때 발생하는 문제를 해결할 수 있다.
  • 네임스페이스를 자동으로 생성하므로 변수 충돌을 방지
  • alias 사용 가능
  • 필요한 부분만 가져와서 성능이 향상
  • underscore(_)나 hyphen(-)을 이용하면 private member를 만들수 있다.

예시

// _box.scss

$-width : 100px;

@mixin box-size {
    width: $-width;
    height: $-width;
}

 

// main.scss
@use 'box' ; 
// @use 'box' as b; // alias 사용 가능

.div {
    @include box.box-size;
    margin: box.$-width;
}

 

 

private 한 변수 width 에 직접 접근이 불가능한 것을 확인된다. 

 


@forward

@forward는 여러 파일을 하나의 인터페이스로 결합하여 내보내는 특징을 가지고 있다.

 

/* variables.scss */
$primary-color: #333;
$secondary-color: #666;
/* mixins.scss */
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
/* index.scss */
@forward 'variables';
@forward 'mixins';
/* styles.scss */
@use 'index';

body {
  color: index.$primary-color;
  @include index.flex-center;
}

 

하나의 네임스페이스 index를 통해 모든 멤버에 접근할 수 있게 한다.

 

https://mine-it-record.tistory.com/722


prefix

@forward는 접두사를 추가할 수 있다.
이를 활용하면 좀 더 안전하고 직관적이게 어디서 가져오는지 출처를 알 수 있다.
접두사는 <prefix>-* 이런식으로 작성할 수 있다.

/* variables.scss */
$primary-color: #333;
$secondary-color: #666;
/* mixins.scss */
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
/* index.scss */
@forward 'variables' as var-*;
@forward 'mixins' as mix-*;
/* styles.scss */
@use 'index';

body {
  color: index.var-$primary-color;
  @include index.mix-flex-center;
}

Controlling Visibility

  • show : 지정한 멤버만 외부에 노출하고 나머지는 숨긴다.
  • hide : 지정한 멤버만 숨기고 나머지는 외부에 노출한다.
/* variables.scss */
$primary-color: #333;
$secondary-color: #666;
$background-color: #fff;
$text-color: #000;

/* index.scss */
@forward 'variables' show $primary-color, $text-color;

/* styles.scss */
@use 'index';

body {
  color: index.$primary-color;
  background-color: index.$text-color;
}

 

/* variables.scss */
$primary-color: #333;
$secondary-color: #666;
$background-color: #fff;
$text-color: #000;

/* index.scss */
@forward 'variables' hide $secondary-color, $background-color;

/* styles.scss */
@use 'index';

body {
  color: index.$primary-color;
  background-color: index.$text-color;
}

2.2 @extend
기존 스타일을 상속하고자 경우 @extend를 사용한다. 

 

scss

.error {
    border: 1px #f00;
    background-color: blue;
  }
 
  .seriousError {
    @extend .error;
 
    border-width: 3px;
    border-color: darkblue;
  }

 

css

.error, .seriousError {
    border: 1px #f00;
    background-color: blue;
  }
 
  .seriousError {
    border-width: 3px;
    border-color: darkblue;
  }

 

@extend를 사용하면 트랜스파일링 후 자신의 셀렉터가 어디에 첨부될 것인지 예상하기 어렵고, 예상치 못했던 부작용이 발생할 수 있다. @extend의 사용은 가급적 자제하고 Mixin은 사용하는 것을 추천한다.


2.3 Placeholder Selectors
Placeholder Selector는 재사용이 가능한 rule set을 % 키워드로 지정하는 @extend 전용 Selector이다.
Placeholder Selector은 상속만을 위한 rule set으로 자신은 트랜스파일링되지 않는다.

 

scss

%input-style {
    font-size: 14px;
  }
 
  .input-black {
    @extend %input-style;
 
    color: black;
  }
 
  .input-red {
    @extend %input-style;
 
    color: red;
  }

 

css

.input-black, .input-red {
    font-size: 14px;
  }
 
  .input-black {
    color: black;
  }
 
  .input-red {
    color: red;
  }

 


3. 조건과 반복
Sass는 프로그래밍 언어와 유사하게 제어문을 사용할 수 있는 기능을 제공한다.

3.1 if()
built-in if() 함수는 주어진 조건을 판단하여 결과를 리턴한다. Javascript의 삼항연산자와 유사하게 동작한다.

if(condition, if_true, if_false)
$type: ocean;

p {
  color: if($type == ocean, blue, black); // color: blue;
}

 


3.2 @if…@else
@if…@else를 사용하면 조건 분기가 가능하다.

 

$type: monster;

p {
  @if $type == ocean {
    color: blue;
  } @else if $type == matador {
    color: red;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}

 


3.3 @for
@for으로 반복문을 사용할 수 있다.

 

@for $i from 1 through 3 {
    .item-#{$i} { width: 2em * $i; }
  }

3.4 @each
@each와 list 또는 map의 요소에 대해 반복을 실시한다.

 

scss

// List
@each $animal in puma, sea-slug, egret, salamander {

    .#{$animal}-icon {
      background-image: url('/images/#{$animal}.png');
    }
  }
 
  // Map
  // $header: h1, $size: 2em
  // $header: h2, $size: 1.5em
  // $header: h3, $size: 1.2em
  @each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
    #{$header} {
      font-size: $size;
    }
  }

 

css

.puma-icon {
    background-image: url("/images/puma.png");
  }
 
  .sea-slug-icon {
    background-image: url("/images/sea-slug.png");
  }
 
  .egret-icon {
    background-image: url("/images/egret.png");
  }
 
  .salamander-icon {
    background-image: url("/images/salamander.png");
  }
 
  h1 {
    font-size: 2em;
  }
 
  h2 {
    font-size: 1.5em;
  }
 
  h3 {
    font-size: 1.2em;
  }

3.5 @while
@while으로 반복문을 사용할 수 있다.

 

scss

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

 

css

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

 


4. Mixin
Mixin은 Sass의 매우 유용한 기능으로 중복 기술을 방지하기 위해 사용 빈도가 높은 마크업을 사전에 정의하여 필요할 때에 불러 사용하는 방법이다.

@mixin 선언하고 @include로 불러들인다.

@extend와 유사하나, @Mixin은 함수와 같이 매개 변수를 사용할 수 있다.

 

 

scss

@mixin circle($size) {
    width: $size;
    height: $size * 2;
    border-radius: 50%;
  }
 
  .box {
    @include circle(100px);
 
    background: #f00;
  }

100px을 인수로 하여 circle 코드를 불러오며, box 안에서 background 색을 추가로 지정한다.

 

 

css

.box {
    width: 100px;
    height: 200px;
    border-radius: 50%;
    background: #f00;
  }

 

5. Function
Function은 mixin과 유사하나 반환값에 차이가 있다.

  • mixin : style markup을 반환
  • function : @return directive를 통하여 값을 반환
$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar { width: grid-width(5); }  // width: 240px;

 


 

6. Comment
CSS는 멀티 라인 주석 /* */만을 지원하지만 Sass는 /* */와 // 모두 사용할 수 있다.
한 줄 주석 //은 트랜스파일링 후 CSS에서 사라지고, 멀티 라인 주석은 CSS에 나타난다.

 

scss

// 한줄 주석
/* 여러줄 주석*/


@use 'box';

.div {
    @include box.box-size;
}

 

css

@charset "UTF-8";
/* 여러줄 주석*/
.div {
  width: 100px;
  height: 100px;
}

/*# sourceMappingURL=main.css.map */

 

css (compressed)

.div{width:100px;height:100px}/*# sourceMappingURL=main.css.map */

 

 

 

 

 

'Sass' 카테고리의 다른 글

요약  (0) 2024.08.08
05. Webpack 개발 환경에서 Sass 사용하기  (0) 2024.08.08
04. 기본 내장 함수  (0) 2024.08.08
02. SassScript  (0) 2024.08.08
01. Sass의 소개, 설치와 간단한 명령어 사용법  (0) 2024.08.07