Урок 7

День 7 | SCSS и современный CSS

70 мин

Что такое SCSS и зачем он нужен?

До сих пор мы писали обычный CSS. Это работает, но когда проект становится большим, CSS становится неудобным. Представьте: у вас 20 файлов CSS, и вы хотите изменить цвет кнопок везде. Придётся искать и менять в каждом файле. А что если цвет хранится в одном месте?

SCSS (Sassy CSS) — это препроцессор CSS, который расширяет возможности обычного CSS. SCSS компилируется (превращается) в обычный CSS, который понимает браузер.

Преимущества SCSS:

  • Переменные — храните цвета, размеры в одном месте
  • Вложенность — пишите стили вложенными, как в HTML
  • Миксины — переиспользуемые блоки кода
  • Импорты — разбивайте стили на модули
  • Математические операции — вычисляйте размеры автоматически
  • Функции — встроенные функции для работы с цветами, строками

Важно понимать: Браузер не понимает SCSS! SCSS нужно скомпилировать (превратить) в обычный CSS. Это делает Vite автоматически.

Установка sass

Для работы с SCSS в Vite нужен только один пакет:

npm install --save-dev sass

Что мы устанавливаем?

  • sass — сам компилятор SCSS (превращает SCSS в CSS)

Почему только sass? Vite поддерживает SCSS из коробки! Не нужны загрузчики, как в Webpack. Vite автоматически обрабатывает SCSS файлы при импорте.

Импорт SCSS в JavaScript

В файле src/js/main.js импортируйте SCSS:

// Импорт главного файла стилей
import "../scss/style.scss";

console.log("Стили загружены!");

Что происходит при импорте?

  1. Vite видит импорт SCSS файла
  2. Автоматически компилирует SCSS в CSS
  3. Добавляет CSS в HTML

Всё! Никакой дополнительной настройки не требуется.

Структура SCSS файлов

Рекомендуемая структура для больших проектов:

scss/
├── _variables.scss    # Переменные (цвета, размеры)
├── _mixins.scss       # Миксины (переиспользуемые блоки)
├── _base.scss         # Базовые стили (сброс, типографика)
├── _layout.scss       # Макет (header, footer, grid)
├── _components.scss   # Компоненты (кнопки, карточки)
└── style.scss         # Главный файл (импортирует все)

Почему подчёркивание в начале имени? Файлы, начинающиеся с _, называются "partials" (частичные файлы). SCSS не компилирует их в отдельные CSS файлы — они импортируются в главный файл.

Главный файл style.scss

Создайте src/scss/style.scss:

// Импорты (порядок важен!)
@import "variables";
@import "mixins";
@import "base";
@import "layout";
@import "components";

Важно: При импорте не нужно указывать расширение .scss и подчёркивание _. SCSS автоматически их найдёт.

Почему порядок важен? Переменные должны быть импортированы до миксинов (потому что миксины могут использовать переменные). Базовые стили должны быть до компонентов (чтобы компоненты могли их переопределять).

SCSS переменные vs CSS Custom Properties

В современной разработке есть два подхода к переменным. Давайте разберём разницу:

SCSS переменные

SCSS переменные работают на этапе компиляции. Создайте src/scss/_variables.scss:

// ============================================
// ЦВЕТА
// ============================================

// Основные цвета
$primary-color: #F36049;
$secondary-color: #667eea;
$accent-color: #764ba2;

// Текст
$text-dark: #323036;
$text-medium: #706D75;
$text-light: #999;

// Фон
$bg-white: #ffffff;
$bg-light: #f5f5f5;
$bg-dark: #1a1a1a;

// ============================================
// ТИПОГРАФИКА
// ============================================

$font-family-base: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
$font-family-heading: "Poppins", $font-family-base;

$font-size-xs: 12px;
$font-size-sm: 14px;
$font-size-base: 16px;
$font-size-lg: 18px;
$font-size-xl: 20px;
$font-size-2xl: 24px;
$font-size-3xl: 30px;
$font-size-4xl: 36px;

$font-weight-normal: 400;
$font-weight-medium: 500;
$font-weight-semibold: 600;
$font-weight-bold: 700;

$line-height-tight: 1.2;
$line-height-normal: 1.5;
$line-height-relaxed: 1.75;

// ============================================
// ОТСТУПЫ
// ============================================

$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 16px;
$spacing-lg: 24px;
$spacing-xl: 32px;
$spacing-2xl: 48px;
$spacing-3xl: 64px;

// ============================================
// BREAKPOINTS (точки перелома для адаптивности)
// ============================================

$breakpoint-mobile: 768px;
$breakpoint-tablet: 1024px;
$breakpoint-desktop: 1280px;

Как использовать SCSS переменные?

// Вместо этого:
.button {
  background: #F36049;
  color: #323036;
}

// Пишем так:
.button {
  background: $primary-color;
  color: $text-dark;
}

Особенности SCSS переменных:

  • ✅ Работают на этапе компиляции
  • ✅ Можно использовать в миксинах и функциях
  • ✅ Можно использовать в медиа-запросах
  • ❌ Нельзя изменить через JavaScript
  • ❌ Не работают в runtime (после компиляции)

CSS Custom Properties (CSS переменные)

CSS Custom Properties — это нативные переменные CSS, которые работают в браузере. Они поддерживаются во всех современных браузерах с 2017 года!

// В _variables.scss или отдельном файле
:root {
  // CSS Custom Properties (начинаются с --)
  --primary-color: #F36049;
  --secondary-color: #667eea;
  --text-dark: #323036;
  --spacing-md: 16px;
  --font-size-base: 16px;
}

Как использовать CSS Custom Properties?

.button {
  background: var(--primary-color);
  color: var(--text-dark);
  padding: var(--spacing-md);
  font-size: var(--font-size-base);
}

Особенности CSS Custom Properties:

  • ✅ Работают в runtime (в браузере)
  • ✅ Можно изменить через JavaScript
  • ✅ Поддерживают каскадность (можно переопределять)
  • ✅ Работают в медиа-запросах (с 2023 года)
  • ✅ Не требуют компиляции
  • ❌ Нельзя использовать в миксинах SCSS
  • ❌ Нельзя использовать в функциях SCSS

Гибридный подход (рекомендуется)

Лучший подход — использовать оба варианта вместе! SCSS переменные для компиляции, CSS Custom Properties для runtime.

// _variables.scss

// SCSS переменные (для компиляции, миксинов, функций)
$primary-color: #F36049;
$secondary-color: #667eea;
$text-dark: #323036;
$spacing-md: 16px;
$font-size-base: 16px;

// CSS Custom Properties (для runtime, JavaScript, тем)
:root {
  --primary-color: #{$primary-color}; // Интерполяция SCSS в CSS
  --secondary-color: #{$secondary-color};
  --text-dark: #{$text-dark};
  --spacing-md: #{$spacing-md};
  --font-size-base: #{$font-size-base};
}

Что такое интерполяция? #{$variable} — это способ вставить значение SCSS переменной в CSS. Это нужно, чтобы передать SCSS переменную в CSS Custom Property.

Как использовать гибридный подход?

// В SCSS используем SCSS переменные для миксинов
@mixin button($bg-color: $primary-color) {
  background: var(--primary-color); // В CSS используем CSS Custom Properties
  color: var(--text-dark);
  padding: var(--spacing-md);
}

.button {
  @include button(); // Миксин использует SCSS переменную
  
  // Но в CSS применяется CSS Custom Property
  // Это позволяет менять цвет через JavaScript!
}

Преимущества гибридного подхода:

  • ✅ SCSS переменные для миксинов и функций
  • ✅ CSS Custom Properties для динамических значений
  • ✅ Можно менять темы через JavaScript
  • ✅ Можно переопределять в разных контекстах
  • ✅ Лучшее из обоих миров!

Пример: Темная тема через CSS Custom Properties

// _variables.scss
:root {
  --primary-color: #F36049;
  --bg-color: #ffffff;
  --text-color: #323036;
}

// Темная тема
[data-theme="dark"] {
  --primary-color: #ff7a5c;
  --bg-color: #1a1a1a;
  --text-color: #ffffff;
}

// Использование
body {
  background: var(--bg-color);
  color: var(--text-color);
}

// Переключение темы через JavaScript
document.documentElement.setAttribute("data-theme", "dark");

Это невозможно с SCSS переменными! Они компилируются один раз и не меняются.

Миксины (_mixins.scss)

Миксин (mixin) — это переиспользуемый блок кода. Это как функция в программировании. Создайте src/scss/_mixins.scss:

// Миксин для flexbox центрирования
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// Миксин для кнопки
@mixin button($bg-color: $primary-color, $text-color: white) {
  background: var(--primary-color); // Используем CSS Custom Property
  color: $text-color; // Или SCSS переменную, если не нужно менять через JS
  padding: var(--spacing-md);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.3s;
  
  &:hover {
    opacity: 0.9;
  }
}

// Миксин для медиа-запросов
@mixin mobile {
  @media (max-width: $breakpoint-mobile) {
    @content;
  }
}

@mixin tablet {
  @media (max-width: $breakpoint-tablet) {
    @content;
  }
}

Разберём миксины подробно:

  • @mixin flex-center — простой миксин без параметров. Используется так: @include flex-center;
  • @mixin button($bg-color: $primary-color, $text-color: white) — миксин с параметрами:
    • $bg-color — обязательный параметр (цвет фона)
    • $text-color: white — необязательный параметр (если не указан, будет white)
  • &:hover — это вложенный селектор. & означает "родительский селектор"
  • @content — позволяет передавать блок кода в миксин (используется в медиа-запросах)

Как использовать миксины?

// В _components.scss
.button {
  @include button($primary-color);
  
  &.secondary {
    @include button($secondary-color);
  }
}

.container {
  @include flex-center;
  padding: var(--spacing-md);
  
  @include mobile {
    padding: var(--spacing-sm);
  }
}

Вложенность селекторов

SCSS позволяет вкладывать селекторы, как в HTML. Это делает код более читаемым:

// Вместо этого в CSS:
.nav {
  background: #333;
}
.nav ul {
  list-style: none;
}
.nav ul li {
  display: inline-block;
}
.nav ul li a {
  color: white;
}

// В SCSS можно писать так:
.nav {
  background: #333;
  
  ul {
    list-style: none;
    
    li {
      display: inline-block;
      
      a {
        color: white;
      }
    }
  }
}

Важно: Не злоупотребляйте вложенностью! Глубокая вложенность (больше 3-4 уровней) делает код сложным для чтения.

CSS Nesting (нативная вложенность в CSS)

Важно знать: В современных браузерах (Chrome 112+, Firefox 117+, Safari 16.5+) появилась нативная вложенность CSS! Теперь можно писать вложенность прямо в CSS без препроцессора.

/* Нативный CSS Nesting (2023+) */
.nav {
  background: #333;
  
  ul {
    list-style: none;
    
    li {
      display: inline-block;
      
      a {
        color: white;
      }
    }
  }
}

Когда использовать SCSS, когда нативный CSS?

  • SCSS — если нужны миксины, функции, переменные для компиляции, поддержка старых браузеров
  • Нативный CSS Nesting — для простой вложенности в современных проектах (2024+)

Рекомендация: Используйте SCSS для сложных проектов с миксинами и функциями. Для простой вложенности можно использовать нативный CSS, если поддерживаете только современные браузеры.

Когда что использовать?

Используйте SCSS переменные для:

  • ✅ Значений в миксинах и функциях
  • ✅ Значений в медиа-запросах (breakpoints)
  • ✅ Статических значений, которые не меняются
  • ✅ Математических операций на этапе компиляции

Используйте CSS Custom Properties для:

  • ✅ Значений, которые нужно менять через JavaScript
  • ✅ Тем (светлая/темная)
  • ✅ Динамических значений (например, размеры, которые меняются при взаимодействии)
  • ✅ Значений, которые нужно переопределять в разных контекстах

Практическое задание

  1. Установите sass: npm install --save-dev sass
  2. Создайте структуру папок для SCSS (scss/ с подпапками если нужно)
  3. Создайте файл _variables.scss с SCSS переменными
  4. Добавьте CSS Custom Properties в :root с интерполяцией SCSS переменных
  5. Создайте файл _mixins.scss с несколькими миксинами (flex-center, button, mobile)
  6. Создайте главный файл style.scss и импортируйте все части
  7. Импортируйте style.scss в main.js
  8. Запустите dev server: npm run dev
  9. Проверьте результат — стили должны примениться к странице
  10. Попробуйте использовать и SCSS переменные, и CSS Custom Properties
  11. Создайте простую темную тему через CSS Custom Properties
  12. Попробуйте изменить CSS Custom Property через JavaScript

Частые ошибки

Ошибка: "Cannot find module 'sass'"

  • Установите sass: npm install --save-dev sass

Ошибка: "File to import not found"

  • Проверьте пути к файлам при импорте
  • Убедитесь, что файлы существуют
  • Помните: при импорте не нужно указывать _ и .scss

CSS Custom Properties не работают

  • Проверьте синтаксис: должно быть --variable-name: value;
  • Убедитесь, что они объявлены в :root или в нужном селекторе
  • Используйте var(--variable-name) для применения

Что дальше?

Отлично! Теперь вы умеете работать с SCSS и CSS Custom Properties. В следующем уроке мы настроим Vite Dev Server для удобной разработки с автоматической перезагрузкой страницы.

Мы используем файлы cookie для улучшения работы сайта и персонализации контента. Продолжая использовать сайт, вы соглашаетесь с использованием cookies в соответствии с нашей Политикой конфиденциальности.