(๋ฒˆ์—ญ) ์ž˜ ๊ฐ€ SASS ๐Ÿ‘‹, ๋‹ค์‹œ ๋งŒ๋‚˜ ๋ฐ˜๊ฐ€์›Œ ๋„ค์ดํ‹ฐ๋ธŒ CSS

์›๋ฌธ : Goodbye SASS ๐Ÿ‘‹, welcome back native CSS

thumbnail

Sass๋Š” ๋กœ์ปฌ์— ์„ค์น˜๋˜๋Š” ๊ฐ•๋ ฅํ•œ ์ „์ฒ˜๋ฆฌ๊ธฐ๋กœ ์ž๋ฆฌ ์žก์œผ๋ฉฐ ์ง€๋‚œ 10๋…„ ๋™์•ˆ ์ œ ํ”„๋กœ์ ํŠธ์˜ ํ•ต์‹ฌ์„ ์ด๋ฃจ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๊ณ  ์•ˆ์ •์ ์ธ CSS ํŒจํ‚ค์ง€๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๋„ Sass๋Š” ๊ต‰์žฅํžˆ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ 2024๋…„์— ์ ‘์–ด๋“ค๋ฉด์„œ CSS๊ฐ€ ๊ธ‰์†๋„๋กœ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ๋ถ€์ธํ•  ์ˆ˜ ์—†๋Š” ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ํ•œ๋•Œ Sass์—๋งŒ ์กด์žฌํ•˜๋˜ ๊ธฐ๋Šฅ๋“ค์ด ์ด์ œ๋Š” CSS์— ๊ธฐ๋ณธ์ ์œผ๋กœ ํ†ตํ•ฉ๋˜์—ˆ์œผ๋ฉฐ, ๋ณ€์ˆ˜ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํŠนํžˆ ์ฃผ๋ชฉํ•  ์ตœ์‹  ๊ธฐ๋Šฅ์ธ CSS ์ค‘์ฒฉ์ด ๊ทธ ์˜ˆ์ž…๋‹ˆ๋‹ค.

๋ณ€์ˆ˜(Variables)

:root {
  --button-padding: 10px 20px;
  --button-bg-color: #007bff;
  --button-text-color: #ffffff;
  --button-border-radius: 8px;
}

.button {
  padding: var(--button-padding);
  background-color: var(--button-bg-color);
  color: var(--button-text-color);
  border-radius: var(--button-border-radius);
  border: none;
  cursor: pointer;
  transition: background-color 0.3s;
}

๋ณ€์ˆ˜ ์ •์˜๋Š” ์˜ค๋žซ๋™์•ˆ SCSS์˜ ๋…ํŠนํ•œ ๊ฐ•์ ์œผ๋กœ ์—ฌ๊ฒจ์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋งŽ์€ ์†์„ฑ์„ ์ค‘์•™์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์œผ๋กœ, CSS์—์„œ๋Š” ์˜ค๋žœ ์‹œ๊ฐ„ ์•„์‰ฌ์šด ๋ถ€๋ถ„์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ๋Š” CSS์—์„œ๋„ Sass์™€ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ค‘์š”ํ•œ ์ฐจ์ด์ ์€ Sass ๋ณ€์ˆ˜๋Š” ์ „์ฒ˜๋ฆฌ๊ธฐ ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ๋งŒ ์กด์žฌํ•˜์ง€๋งŒ, CSS ๋ณ€์ˆ˜๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ๋™์ ์œผ๋กœ ๋ฎ์–ด์“ธ ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

CSS ์ค‘์ฒฉ(Nesting)

.blog {
  position: relative;
  padding: 1rem;
  background: var(--neutral-100);

  .blog-item {
    border: 1px solid var(--neutral-200);

    & span {
      font-size: 1rem;
    }
  }
}

ํ•˜๋‚˜์˜ ์š”์†Œ ์•ˆ์—์„œ ๋‹ค๋ฅธ ์š”์†Œ์˜ ์Šคํƒ€์ผ ๊ทœ์น™์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์€ CSS ์ž‘์„ฑ์„ ํฌ๊ฒŒ ๋‹จ์ˆœํ™”ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์œ„ ์š”์†Œ๋‚˜ ๊ฐ€์ƒ ์„ ํƒ์ž๋ฅผ ์œ„ํ•ด ๋™์ผํ•œ ์„ ํƒ์ž๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹ , ์ค‘์ฒฉ์„ ํ†ตํ•ด ์ด๋ฅผ ์ƒ์œ„ ์„ ํƒ์ž ๋‚ด์—์„œ ๊ทธ๋ฃนํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๋ช…ํ™•ํ•˜๊ณ  ๊ณ„์ธต์ ์œผ๋กœ ๊ตฌ์กฐํ™”ํ•˜๋ฉฐ, ๋” ํšจ์œจ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

CSS ์ค‘์ฒฉ๊ณผ ์ค‘์ฒฉ ์„ ํƒ์ž๋Š” ๊ฐ๊ฐ 84%, 86% ์ด์ƒ์˜ ๋ธŒ๋ผ์šฐ์ € ์ง€์›์„ ๋ฐ›๊ณ  ์žˆ์–ด ์ ์  ๋” ์ ‘๊ทผ์„ฑ์ด ๋†’์•„์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

:is() ์˜์‚ฌ ํด๋ž˜์Šค

:is(selector1, selector2, selector3) {
  /* styles */
}

:is ์˜์‚ฌ ํด๋ž˜์Šค๋Š” ์„ ํƒ์ž ๊ฐœ๋…์„ ํ˜์‹ ์ ์œผ๋กœ ๋ฐ”๊พธ๋ฉฐ, ์—ฌ๋Ÿฌ ์„ ํƒ์ž ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ›์•„ ์ด๋“ค ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ๋ฅผ ์Šคํƒ€์ผ๋ง ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” DOM์—์„œ ์š”์†Œ๋ฅผ ์„ ํƒํ•˜๊ณ  ์Šคํƒ€์ผ๋ง ํ•˜๋Š” ๊ณผ์ •์„ ํฌ๊ฒŒ ๋‹จ์ˆœํ™”ํ•ฉ๋‹ˆ๋‹ค.

๊ธด ์„ ํƒ์ž ๋ฆฌ์ŠคํŠธ ๋Œ€์‹  :is()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋…์„ฑ์„ ๋†’์ด๋ฉด์„œ ๊ธด ์„ ํƒ์ž ์ž‘์„ฑ๋„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

:has() ์˜์‚ฌ ํด๋ž˜์Šค

.hero:has(.hero-button) {
  background-color: var(--accent-50);
}

CSS ์˜์‚ฌ ํด๋ž˜์Šค :has()๋Š” ํ•˜์œ„ ์š”์†Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์š”์†Œ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ ์ ์šฉ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ

.component {
  --theme: dark;
  container-name: fancy;
}

@container fancy style(--theme: dark) {
  .fancy {
    /* dark styles. */
  }
}
.parent-container {
  container-type: inline-size;

  .headline {
    font-size: 2rem;
  }

  @container (width >= 720px) {
    .headline {
      font-size: 2.5rem;
    }
  }
}

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ๋Š” CSS3 ์ดํ›„ ์›น ๋””์ž์ธ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํ˜์‹ ์œผ๋กœ ํ‰๊ฐ€๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์˜ ๊ฐœ๋…์„ ํ™•์žฅํ•˜์—ฌ ์š”์†Œ๊ฐ€ ์ปจํ…Œ์ด๋„ˆ์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์กฐ์ •๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์€ ์š”์†Œ์˜ ๋””์ž์ธ์ด ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์—ฌ ๋”์šฑ ์œ ์—ฐํ•˜๊ณ  ์ ์‘๋ ฅ ์žˆ๋Š” ๋””์ž์ธ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ fancy๊ฐ€ ๋ณ€์ˆ˜ โ€”theme: dark๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ์œ„์˜ CSS๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์บ์Šค์ผ€์ด๋“œ ๋ ˆ์ด์–ด(Cascade layers)

@layer utilities {
  b .button {
    padding: 0.5rem;
  }

  .button--lg {
    padding: 0.8rem;
  }
}

์บ์Šค์ผ€์ด๋“œ ๋ ˆ์ด์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค๋‚˜ ID ๋“ฑ์„ ์ค‘์ฒฉํ•  ํ•„์š” ์—†์ด ์ž์ฒด ๊ณ„์ธต(๋ ˆ์ด์–ด)์„ ํ• ๋‹นํ•ด ๋” ๋†’์€ ์šฐ์„ ์ˆœ์œ„(specificity)๋ฅผ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @layer ๊ทœ์น™๊ณผ ๊ณ„์ธตํ™”๋œ @import๋ฅผ ์‚ฌ์šฉํ•ด ๋ฆฌ์…‹ ๋ฐ ๊ธฐ๋ณธ๊ฐ’๊ณผ ๊ฐ™์€ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ์Šคํƒ€์ผ์—์„œ ํ…Œ๋งˆ, ํ”„๋ ˆ์ž„์›Œํฌ, ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ๊ฑฐ์ณ ์ปดํฌ๋„ŒํŠธ, ์œ ํ‹ธ๋ฆฌํ‹ฐ, ์˜ค๋ฒ„๋ผ์ด๋“œ์™€ ๊ฐ™์€ ๋†’์€ ์šฐ์„ ์ˆœ์œ„ ์Šคํƒ€์ผ๊นŒ์ง€ ์ž์ฒด ์บ์Šค์ผ€์ด๋“œ ๋ ˆ์ด์–ด๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋” ๋‚˜์€ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Sass์˜ ๋ฏธ๋ž˜

๊ทธ๋ ‡๋‹ค๋ฉด Sass๋Š” ์ด์ œ ํ•„์š” ์—†์–ด์กŒ์„๊นŒ์š”? ์ „ํ˜€ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ”ฝ์…€์„ rem์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์™€ ๋ฏน์Šค์ธ(Mixins)์€ Sass์˜ ๋Œ€์ฒด ๋ถˆ๊ฐ€๋Šฅํ•œ ์žฅ์ ์œผ๋กœ ๋‚จ์•„์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ €๋Š” ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ์ ํŠธ์—์„œ Sass๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  Sublime Editor์—์„œ ๋ฏธ๋ฆฌ ์ •์˜๋œ ์ฝ”๋“œ ๋ธ”๋ก๊ณผ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•ด ์›Œํฌํ”Œ๋กœ๋ฅผ ํฌ๊ฒŒ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

Sass ์ž˜ ๊ฐ€?

2024๋…„ ์‹œ์ ์—์„œ ๋ณด๋ฉด, Sass๋ฅผ ์„ค์น˜ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ณ  ์ปดํŒŒ์ผํ•˜๋Š” ๊ณผ์ •์˜ ๋ฒˆ๊ฑฐ๋กœ์›€์„ ๊ฐ์ˆ˜ํ•  ๋งŒํ•œ ์ด์ ์ด ๋” ์ด์ƒ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  CSS์˜ ํ™•์žฅ์„ฑ๊ณผ ์‚ฌ์šฉ ์นœํ™”์„ฑ์€ ์ถ”๊ฐ€ ๋„๊ตฌ ์—†์ด๋„ ์ถฉ๋ถ„ํžˆ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

์ €์˜ Themex ํ”„๋กœ์ ํŠธ๋Š” ์ƒˆ๋กœ์šด CSS ๊ธฐ๋Šฅ์˜ ์กฐํ•ฉ์ด ์–ผ๋งˆ๋‚˜ ๊ฐ•๋ ฅํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

CSS์˜ ๋ฐœ์ „๊ณผ ํ•จ๊ป˜ ํฌ๊ณ  ์ž‘์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง์ ‘์ ์ด๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

Sass, ์•ˆ๋…•ํžˆ ๊ฐ€์„ธ์š”. ๊ณ ๋งˆ์› ์Šต๋‹ˆ๋‹ค!

goodbye sass, and thank you!


๐Ÿš€ ํ•œ๊ตญ์–ด๋กœ ๋œ ํ”„๋ŸฐํŠธ์—”๋“œ ์•„ํ‹ฐํด์„ ๋น ๋ฅด๊ฒŒ ๋ฐ›์•„๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด Korean FE Article(https://kofearticle.substack.com/)์„ ๊ตฌ๋…ํ•ด์ฃผ์„ธ์š”!


Written by@[Ykss]
๊ณ ์ด๊ฒŒ ๋‘์ง€ ์•Š๊ณ  ํ˜๋ ค๋ณด๋‚ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์ž.

GitHubInstagramLinkedIn