SCSS/SASS 기초와 활용


SCSS(Sassy CSS)는 CSS를 더 효율적으로 작성할 수 있게 해주는 전처리기입니다. 변수, 중첩, 믹스인, 함수 등을 제공하여 유지보수가 쉬운 스타일시트를 만들 수 있습니다.



언제 사용하나요?



  • 대규모 프로젝트의 CSS 관리

  • 반복되는 스타일 패턴 재사용

  • 테마 시스템 구축

  • 컴포넌트 기반 스타일링



설치 및 컴파일


# 설치
npm install sass --save-dev

# 컴파일
npx sass src/styles:dist/css --watch

# package.json 스크립트
"scripts": {
"sass": "sass src/scss:dist/css --watch"
}


변수


// _variables.scss
$primary-color: #3498db;
$secondary-color: #2ecc71;
$font-stack: "Noto Sans KR", sans-serif;
$spacing-unit: 8px;

// 사용
.button {
background: $primary-color;
font-family: $font-stack;
padding: $spacing-unit * 2;
}


중첩 (Nesting)


.card {
padding: 20px;

&__header {
font-size: 18px;

&--highlight {
color: $primary-color;
}
}

&__body {
margin-top: 10px;
}

// 가상 선택자
&:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

// 미디어 쿼리 중첩
@media (max-width: 768px) {
padding: 10px;
}
}

// 컴파일 결과
// .card { ... }
// .card__header { ... }
// .card__header--highlight { ... }
// .card:hover { ... }


믹스인 (Mixin)


// 정의
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}

@mixin button($bg-color, $text-color: white) {
background: $bg-color;
color: $text-color;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;

&:hover {
background: darken($bg-color, 10%);
}
}

// 사용
.container {
@include flex-center;
}

.btn-primary {
@include button($primary-color);
}

.btn-secondary {
@include button($secondary-color, black);
}


반복문과 조건문


// @each
$sizes: (sm: 12px, md: 16px, lg: 20px, xl: 24px);

@each $name, $size in $sizes {
.text-#{$name} {
font-size: $size;
}
}

// @for
@for $i from 1 through 5 {
.col-#{$i} {
width: 20% * $i;
}
}

// @if
@mixin theme($mode) {
@if $mode == dark {
background: #333;
color: #fff;
} @else {
background: #fff;
color: #333;
}
}


함수


// 내장 함수
$color: #3498db;
lighten($color, 20%); // 밝게
darken($color, 20%); // 어둡게
saturate($color, 20%); // 채도 높게
rgba($color, 0.5); // 투명도

// 커스텀 함수
@function rem($px) {
@return #{$px / 16}rem;
}

.text {
font-size: rem(14); // 0.875rem
padding: rem(16); // 1rem
}


파일 분리와 Import


// 파일 구조
styles/
├── main.scss
├── _variables.scss
├── _mixins.scss
├── _reset.scss
├── components/
│ ├── _button.scss
│ └── _card.scss
└── pages/
└── _home.scss

// main.scss
@use "variables";
@use "mixins";
@use "reset";
@use "components/button";
@use "components/card";
@use "pages/home";

// 네임스페이스로 접근
.element {
color: variables.$primary-color;
@include mixins.flex-center;
}


확장 (@extend)


%button-base {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}

.btn-primary {
@extend %button-base;
background: $primary-color;
}

.btn-secondary {
@extend %button-base;
background: $secondary-color;
}


유용한 믹스인 모음


// 반응형 브레이크포인트
@mixin mobile {
@media (max-width: 767px) { @content; }
}

@mixin tablet {
@media (max-width: 1023px) { @content; }
}

// 사용
.container {
width: 1200px;
@include tablet { width: 100%; }
@include mobile { padding: 10px; }
}

// 텍스트 말줄임
@mixin ellipsis($lines: 1) {
@if $lines == 1 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} @else {
display: -webkit-box;
-webkit-line-clamp: $lines;
-webkit-box-orient: vertical;
overflow: hidden;
}
}