TIL | SCSS(Sass)

noopy·2021년 9월 16일
0

TIL

목록 보기
13/21
post-thumbnail

Week 7. SCSS
내가 좋아하는 SCSS! 기초를 다시한 번 잡고 가즈아~!~!
널 좋아하는데... 좋아하지 않아... 아니 좋아해...아니 좋아하지 않아....

SCSS(Sass)

CSS Preprocessor(전처리 도구)
: 전처리 도구는 웹 브라우저에서 직접 동작하지 않기 때문에
node.js환경을 통해 CSS로 변환작업을 거쳐야 함.

SCSS와 Sass의 차이

Sass:

  • 코드 블록이 없음
    • 블록이 없는 대신 들여쓰기를 통해 구분
  • 문의 종료를 의미하는 세미콜론(;)을 사용하지 않음.

SCSS:

  • CSS와 비슷함

🍡 주석

기본주석: / 내용 /
컴파일되지 않는 주석: // 내용

🍡 중첩

@at-root

유효범위 내에서 중첩을 벗어나야 할 때

.container {
  .item {
    $variable: 100px;
    
    @at-root .box {
      width: $variable;
    }
  }
}

.item 내부에서 선언됐지만 중첩을 벗어나서 컴파일됨.

중복되는 속성 관리

.container {
  flex: {
    grow: 1; /* flex-grow: 1 */
    shrink: 0; /* flex-shrink: 1 */
    basis: auto; /* flex-basis: auto */
  }
}

🍡 다중 선택자

중첩에서 쉼표(,)로 다중선택 하게 되면 다중선택된 개수만큼 선택됨.
🧐 먼말인지 모르겠다면 예시

🍡 변수

변수는 유효범위({})를 갖는다.

유효범위를 바꾸는 !global

.container {
$inner: 200px !global;
width: $inner;
}
.box {
  height: $inner;
}

⚠️ 이미 전역으로 사용하는 변수가 있을 때,
같은 이름의 지역변수가 덮어쓰지 않도록 주의

조건부로 변수 정의 !default

$primary: blue;

.container {
  $primary: orange
}

변수는 재할당되기 때문에 $primary 변수가 orange로 재할당됨.

$primary: blue;

.container {
  $primary: orange !default;
}

유효범위에 변수가 있다면 !default로 무시하고 없을 경우 !default 앞의 값을 할당

🍡 보간 #{}

평가돼야 할 값이 있을 때

🍡 데이터 타입

Lists = ()

$list1: (10px, 20px, 30px);
$list2: 10px, 20px, 30px; /*소괄호 붙이지 않아도 됨*/
$list3: 10px 20px 30px; /*쉼표 안써도 됨*/

Maps = (key, value)

$map1: ( key, value );
$map2: (a: apple, b: banana, c: cherry);
  • map 값을 불러오려면 코드 상단부에서 코드 모듈을 불러와야 함.
    @use 'sass:map';

  • 값 가져오기: map.get(map 이름, 키값)

color도 데이터타입이다 몰랐지 하하하하

🍡 연산자

JS와 연산자가 비슷하지만 몇가지 주의사항이 있음.

$temp = 20px;
top: 20px / 2 👉 연산되지 않음
top: (20px / 2) /* 1. 소괄호로 묶어주기 */
top: $temp / 2 /* 2. 변수에 담아 계산하기 */
background-position: 100px 100px;
background-size: 200px 200px;
background: 100px 100px / 200px 200px; 👉🏻 단축 속성 구분

CSS에서 /로 속성을 구분하는 것과 나머지 연산자(/)와 겹침

논리 연산자

  • and
  • or
  • not
.container {
  $w: 100px;
  $h: 200px;
  $f: false;
  @if (not $f or $h > 100px) {
    width: $w;
    height: $h;
  }
}

삼항 연산자

if (condition, true, false)

font-size: if($size < 30px, 30px, $size)

🍡 @mixin = 재활용

@mixin large-text($size: 30px) { /* 매개변수 기본 값 */
  font-size: $size; /* 40px */
  font-weight: bold;
  font-family: sans-serif;
}

.container {
  @include larget-text(40px);
}

매개변수로 받은 값을 조건문으로 나눌 수 있다.

@mixin large-text($size: 30px) { /* 매개변수 기본 값 */
  @if ($size < 30px) { 
    font-size: 30px; /* 매개변수가 30px보다 작으므로 30px로 들어감 */
  } @else {
    font-size: $size
  }
  font-weight: bold;
  font-family: sans-serif;
}

.container {
  @include larget-text(10px);
}

🍡 인수

가변 인수 (...)

JS의 나머지 매개변수(rest parameter)와 유사함.

입력한 인수의 개수가 불확실할 때.

@mixin bg($w, $h, $url...) {
  width: $w;
  height: $h;
  background: $url;
}

/* $url은 인수의 개수 상관없이 받음 */

.container {
  @include bg(
    100px,
    200px,
    url('/images/a.png') no-repeat center, /*z-index 가장 높음*/
    url('/images/b.png') repeat-x, /* z-index 그 다음으로 높음 */
    url('/images/c.png') repeat-y center / contain, /* z-index 가장 낮음 */
  )
}

Lists + 가변 인수

@mixin spread($top, $right, $bottom, $left) {
  margin: {
    top: $top;
    right: $right;
    bottom: $bottom;
    left: $left;
  }
}

.container {
  $margin: 10px 20px 30px 40px;  /* List 데이터 */
  @include spread($margin...);
}

가변 인수를 사용하지 않을 경우,
첫번째 파라미터에만 list 데이터가 들어가게 됨.

키워드 인수

인수를 순서에 상관없이 넣고 싶을 때


@mixin pos ($position, $top: null, $bottom: null, $left: null, $right: null) {
  position: $position;
  top: $top;
  bottom: $bottom;
  left: $left;
  right: $right;
}

.container {
  @include pos(absolute, $top: 100px, $left: 200px)
}

🍡 @content

@include 호출 후 {} 안의 내용은 @content에 추가된다.

@mixin icon($url) {
  &::after {
    content: url($url);
    @content; // 여기추가됨
  }
} 

.container {
  @include icon('/images/icon.png') {
    position: absolute;
    top: 0;
    left: 50px;
  }
}

@content의 인수에 넣은 데이터는 mixin에 전달되어 using으로 받을 수 있다.
@content(밖으로 꺼낼 데이터)
@include 믹스인이름 using(받은 데이터)

👉 디버그 할 때 값 체크 용도로 쓸 수 있을 듯

🍡 @extend (확장)

@extend 선택자

  • 선택자의 선언들을 가져올 수 있음.
.btn {
  display: inline-block;
  padding: 10px 20px;
  background-color: blue;
}

.btn-primary {
  @extend .btn;
  font-weight: 700;
}

⚠️ @extend를 중첩 코드 내부에서 연속으로 사용하는 것을 지양해야 한다.

선택자 폭발

  • 상위 선택자도 딸려서 extend 될 수 있기 때문.
    👉🏻 꼭 필요한 경우가 아니라면 mixin을 사용하고,
    전역 변수를 단순히 extend하는 식으로 활용하는 것은 ok

% (placeholder 선택자)

extend 전용 선택자

%btn { 
  display: inline-block;
  padding: 10px 20px;
  font-weight: 700;
}

.btn-primary {
  @extend %btn;
  background-color: blue;
}

.btn-red {
  @extend %btn;
  background-color: red;
}

.btn-green {
  @extend %btn;
  background-color: green;
}

미디어쿼리와 placeholder

미디어 쿼리 내부에 placeholder가 선언이 되어있어야만,
해당 placeholder를 사용할 수 있음.

@media (max-width: 1400px) {
  %btn {
    color: red;
  }
  .box {
    @extend %btn;
  }
}

⚠️ extend는 이러한 제한 규칙이 많기 때문에, mixin으로 대체하는 것을 권장.
👉🏻 다만 mixin을 남용하면 용량 최적화 문제가 있으므로 Gzip 압축방식을 같이 사용.

🍡 @function

형태: @function 이름 () {}
호출: 이름()

@function으로 grid system 만들어보기

$columns-width: 1400px;
@function grid($col: 1, $total: 12) {
  @if ($col > $total) {
    @error '$col must be less than $total.';
  }
  @return $columns-width * $col / $total;
}

.container {
  width: grid(); // 116.6666666667px
}

.container {
  width: grid(13); // error
}

⚠️ 함수 이름의 중복을 피하기 위해 두 단어 이상으로 이름 조합하기

🍡 조건과 반복

@each

List와 Map 데이터를 반복할 때 사용

@use 'sass:list';

$sizes: 20px, 40px, 80px;
$fruits: (apple: 'A', banana: 'B', cherry: 'C');

// List
@each $size in $sizes {
  $index: list.index($sizes, $size);
  .icon-#{$index} {
    width: $size;
    height: $size;
  }
}

// Map
@each $key, $value in $fruits {
  .fruit-#{$key}::after {
    content: $value;
  }
}

@for

@for $i from 1 through 3 { // 1 <= 3
  .item {
    width: 100px * $i;
  }
}

@for $i from 1 to 3 { // 1 < 3
  .item {
    width: 100px * $i;
  }
}

@while

.box {
  $i: 1;
  $n: 8;
  @while ($n > 0) {
    내용
  }
  $i: $i + 1;
  $n: $n - 2; // 종료조건
}

🍡 모듈 가져오기

@use

@use 'sass:'

  • 은닉화
@use './variables';

.container {
  color: variables.$primary;
}

@import로 불러오지 않고, @use로 불러오게 되면 모듈로 불러오게 됨.
모듈.변수 등으로 이름 충돌없이 명확히 사용할 수 있음.

@forward

어떤 특정한 영역에서 사용하는 모듈을
해당 파일 밖으로 전달

@forward 모듈 as 이름-*
👉🏻 *에 모듈 내부의 변수들을 넣을 수 있음.

🍡 내장모듈

sass 공식문서 - 내장모듈

형태: @use sass:

sass: math

@use 'sass:math'

math.ceil() /*올림*/
math.floor() /*내림*/
math.round() /*반올림*/
math.max() /*최대값*/
math.min() /*최소값*/
math.abs() /*절대값*/

math.is-unitless(20px) /*결과: false, 단위가 없는지 확인*/
math.is-unitless(20) /*결과: true, 단위가 없는지 확인*/

math.compatible(비교값1, 비교값2) /*연산이 가능한지 확인 = 단위가 같음?*/

sass: string

@use 'sass:string';

string.quote(); /*따옴표 추가*/
string.unquote(); /*따옴표 제거*/

string.index(문자열, 찾을 문자열);
string.insert(문자열, 넣을 문자열, index);
string.length(문자열);

string.slice(문자열, 자를 인덱스); /*잘라진 문자열이 반환됨*/

string.to-upper-case(문자열);
string.to-lower-case(문자열);

string.unique-id(); /*유니크한 문자 데이터를 만들어줌*/

sass: color

  • 밝기 바꾸기
/*전역 함수*/
darken($color, $amount);
lighten($color, $amount);

/*모듈*/
@use 'sass:color';

선택자: {속성: color.adjust($color, $lightness: $amount)}
  • 채도 바꾸기
/*전역 함수*/
saturate($color, $amount)
desaturate($color, $amount)

/*모듈*/
@use 'sass:color';

선택자: {속성: color.adjust($color, $saturation: $amount)}
  • 흑백화
/*전역 함수*/
grayscale($color)

/*모듈*/
@use 'sass:color';

선택자: {속성: color.grayscale($color)}

sass: list

⚠️ list의 index는 1부터 시작

@use 'sass:list';

list.append(list, element) /* append된 list 반환 */
list.index(list, element) /*element의 index 반환*/
list.index(list, element) /*element의 index 반환*/
list.join(list, list2) /*요소들이 합쳐진 list 반환*/
list.length(list) /*list의 length 반환*/
list.nth(list, index) /*list[index] 반환*/

sass: map

@use 'sass:map';

map 이름: (:, :)

map.get(map 이름,);
map.has-key(map 이름,);
map.keys(map 이름); /*키를 list로 반환*/
map.values(map 이름); /*키 값을 list로 반환*/
map.merge(map 이름, map2 이름) /*map 합치고 반환  👉🏻 키 중복 안됨*/
map.remove(map 이름,) /*복사된 새 map의 프로퍼티 삭제 후 반환*/

sass: selector

sass: meta

@use 'sass:meta';

meta.call($callback, 인수); /*콜백함수에 인수를 넣어 실행*/
meta.type-of() /*타입 체크*/

🍡 디버그

@debug /*console.log*/
@warn /*console.warn*/
@error /*throw error*/

느낀점

와... 죽겠다............

profile
💪🏻 아는 걸 설명할 줄 아는 개발자 되기

0개의 댓글