CSS Modules, styled-components, Tailwind... Svelte에서는 이 중 어떤 것도 없어도 충분히 강력한 스타일링이 가능합니다.

개념 정의

Svelte의 스타일 시스템은 컴포넌트 스코프 CSS를 기본 제공 합니다. 추가 라이브러리 없이 스코프 격리, 동적 스타일, CSS 변수 기반 테마까지 처리할 수 있습니다.

스코프 CSS의 동작 원리

SVELTE
<p>이 텍스트만 빨간색</p>

<style>
  /* 컴파일러가 .svelte-xyz123 같은 고유 클래스를 자동 추가 */
  /* 실제 출력: p.svelte-xyz123 { color: red; } */
  p { color: red; }
</style>

:global — 스코프 탈출

SVELTE
<style>
  /* 전체 앱에 적용 */
  :global(body) {
    margin: 0;
    font-family: system-ui;
  }

  /* 이 컴포넌트 안의 .content 하위 전역 스타일 */
  .content :global(h1) {
    font-size: 2rem;
  }

  /* :global 블록 — 여러 규칙을 한번에 */
  :global {
    .markdown h2 { margin-top: 2rem; }
    .markdown p { line-height: 1.8; }
    .markdown code { background: #f0f0f0; padding: 2px 4px; }
  }
</style>

<div class="content">
  {@html markdownContent}
</div>

고급 선택자

SVELTE
<style>
  /* 중첩 (Svelte가 지원) */
  .card {
    padding: 1rem;

    h2 {
      font-size: 1.5rem;
    }

    &:hover {
      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    }

    &.active {
      border-color: #ff3e00;
    }
  }

  /* 미사용 CSS 경고 */
  /* Svelte는 사용되지 않는 CSS 선택자를 경고합니다 */
  /* 이는 CSS 정리에 매우 유용합니다 */
</style>

CSS 변수를 활용한 테마

SVELTE
<script>
  let themes = {
    light: { bg: '#fff', text: '#333', primary: '#ff3e00', card: '#f5f5f5' },
    dark: { bg: '#1a1a2e', text: '#eee', primary: '#e94560', card: '#16213e' },
    ocean: { bg: '#0a1628', text: '#e0e0e0', primary: '#00d4ff', card: '#1a2744' },
  };

  let currentTheme = $state('light');
  let theme = $derived(themes[currentTheme]);
</script>

<div
  class="app"
  style:--bg={theme.bg}
  style:--text={theme.text}
  style:--primary={theme.primary}
  style:--card={theme.card}
>
  <select bind:value={currentTheme}>
    <option value="light">라이트</option>
    <option value="dark">다크</option>
    <option value="ocean">오션</option>
  </select>

  <div class="card">
    <h2>테마 카드</h2>
    <p>CSS 변수로 테마 전환</p>
    <button>액션 버튼</button>
  </div>
</div>

<style>
  .app {
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    padding: 2rem;
    transition: all 0.3s ease;
  }
  .card {
    background: var(--card);
    padding: 1.5rem;
    border-radius: 8px;
  }
  button {
    background: var(--primary);
    color: white;
    border: none;
    padding: 0.5rem 1rem;
    border-radius: 4px;
  }
</style>

컴포넌트에 CSS 변수 전달

SVELTE
<!-- Box.svelte -->
<div class="box"><slot /></div>

<style>
  .box {
    background: var(--box-bg, #f0f0f0);
    padding: var(--box-padding, 1rem);
    border-radius: var(--box-radius, 8px);
    border: 1px solid var(--box-border, transparent);
  }
</style>
SVELTE
<!-- 사용 측에서 CSS 변수로 스타일 커스터마이징 -->
<Box --box-bg="#e8f5e9" --box-border="#4caf50" --box-padding="2rem">
  <p>커스텀 스타일 박스</p>
</Box>

@media와 반응형

SVELTE
<style>
  .grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
  }

  @media (min-width: 768px) {
    .grid { grid-template-columns: repeat(2, 1fr); }
  }

  @media (min-width: 1024px) {
    .grid { grid-template-columns: repeat(3, 1fr); }
  }

  /* 다크 모드 선호 감지 */
  @media (prefers-color-scheme: dark) {
    .card { background: #2a2a2a; color: #eee; }
  }

  /* 모션 감소 선호 */
  @media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
  }
</style>

Tailwind CSS 통합

BASH
npx sv add tailwindcss
SVELTE
<!-- Tailwind도 함께 사용 가능 -->
<div class="flex items-center gap-4 p-4 bg-white rounded-lg shadow-md">
  <img class="w-12 h-12 rounded-full" src={avatar} alt={name} />
  <div>
    <h3 class="font-bold text-gray-900">{name}</h3>
    <p class="text-sm text-gray-500">{email}</p>
  </div>
</div>

<style>
  /* Svelte 스코프 CSS와 Tailwind를 혼용할 수 있습니다 */
  /* 복잡한 애니메이션은 Svelte CSS에서, 유틸리티는 Tailwind에서 */
</style>

면접 포인트

  • "Svelte 스코프 CSS의 원리는?": 컴파일러가 컴포넌트별 고유 클래스(해시)를 생성하여 모든 셀렉터와 요소에 추가합니다. 런타임 비용 없이 CSS 격리를 달성합니다.
  • "미사용 CSS 감지는 어떻게 동작하나요?": 컴파일러가 마크업을 분석하여 어떤 CSS 선택자가 실제로 매칭되는 요소가 없는지 확인하고 경고합니다. 빌드 시 dead CSS를 제거하는 데 도움됩니다.

정리

Svelte의 CSS 시스템은 "기본이 충분히 강력한" 접근입니다. 스코프 격리, 동적 스타일, CSS 변수 기반 테마, 미사용 CSS 경고 — 이 모든 것이 추가 의존성 없이 제공됩니다. 필요하다면 Tailwind 같은 도구도 자연스럽게 통합할 수 있습니다.

댓글 로딩 중...