Что такое CSS-in-JS и как использовать с Angular?angular-93

Что такое CSS-in-JS?

CSS-in-JS — это подход к стилизации, при котором CSS генерируется с помощью JavaScript прямо в компоненте. Вместо отдельных .css/.scss файлов стили определяются как JS-объекты или строки непосредственно в коде компонента.

Основные преимущества:

  1. Локальная область видимости стилей (автоматическая изоляция)
  2. Динамические стили на основе props/state
  3. Исключение конфликтов имен классов
  4. Оптимизация (dead code elimination, автоматическое vendor prefixing)

Популярные библиотеки CSS-in-JS для Angular

1. Styled Components

import { styled } from 'ngx-styled';

const StyledButton = styled.button`
  background: ${props => props.primary ? '#3f51b5' : 'white'};
  color: ${props => props.primary ? 'white' : '#3f51b5'};
  font-size: 1em;
  padding: 0.25em 1em;
  border: 2px solid #3f51b5;
  border-radius: 3px;
`;

@Component({
  template: `
    <StyledButton primary>Primary</StyledButton>
    <StyledButton>Secondary</StyledButton>
  `
})
export class MyComponent {}

2. Emotion

import { css } from '@emotion/css';

const buttonStyles = css({
  backgroundColor: '#3f51b5',
  color: 'white',
  '&:hover': {
    backgroundColor: '#303f9f'
  }
});

@Component({
  template: `<button [class]="buttonStyles">Click</button>`
})
export class MyComponent {
  buttonStyles = buttonStyles;
}

3. JSS

import { createUseStyles } from 'react-jss';

const useStyles = createUseStyles({
  button: {
    padding: '10px 20px',
    background: props => props.color || 'grey'
  }
});

@Component({
  selector: 'app-button',
  template: `<button [class]="classes.button">Submit</button>`
})
export class ButtonComponent {
  color = 'blue';
  classes = useStyles(this);
}

Нативные подходы Angular для CSS-in-JS

1. Использование styles в @Component

@Component({
  styles: [`
    :host {
      display: block;
    }
    .dynamic {
      color: ${this.color};
    }
  `],
  template: `<div class="dynamic">Content</div>`
})
export class MyComponent {
  color = 'red';
}

2. Динамические классы с [ngStyle] и [ngClass]

@Component({
  template: `
    <div [ngStyle]="getStyles()">Styled div</div>
    <div [ngClass]="{ active: isActive }">Class div</div>
  `
})
export class MyComponent {
  isActive = true;

  getStyles() {
    return {
      'color': 'white',
      'background-color': 'blue',
      'font-size.px': 16
    };
  }
}

Сравнение с традиционными подходами

Критерий CSS-in-JS SCSS/CSS
Динамические стили ⭐⭐⭐⭐⭐ ⭐⭐ (через классы)
Изоляция стилей ⭐⭐⭐⭐⭐ ⭐⭐⭐ (Shadow DOM)
Производительность ⭐⭐⭐ (runtime) ⭐⭐⭐⭐ (build-time)
Поддержка тем ⭐⭐⭐⭐⭐ ⭐⭐⭐
DevTools поддержка ⭐⭐⭐ ⭐⭐⭐⭐⭐

Оптимизация производительности

  1. Для production:
import { enableProdMode } from '@angular/core';
enableProdMode(); // Отключает runtime проверки стилей
  1. Используйте статические стилы где возможно:
// Вместо:
styles: [`div { color: ${color}; }`]
// Лучше:
styles: [`:host { --dynamic-color: ${color}; }`]
// И в CSS:
div { color: var(--dynamic-color); }

Резюмируем

CSS-in-JS в Angular предоставляет мощные возможности для динамической стилизации компонентов. Хотя Angular традиционно использует CSS/SCSS, интеграция библиотек вроде Emotion или JSS открывает новые паттерны разработки. Для максимальной производительности рекомендуется комбинировать подходы, используя CSS-in-JS только для действительно динамических стилей.