Что нужно знать о CSS в языке JS: плюсы и минусы

Что-то слышали о CSS в языке JS, но так и не разобрались? Возможно, зря. Мы подготовили статью про работу с этой технологией. Читайте.

Вероятно, вы слышали такие термины, как CSS в языке JS, Styled Components, Radium, Aphrodite, и, скорее всего, решили, что это всё ненужные штуки. В этой статье я расскажу про их суть. Сразу следует оговориться, что нижесказанное – всего лишь частное мнение, и его не обязательно придерживаться.

Мне всегда было неудобно работать с огромной папкой стилей. Я пробовал разные подходы к решению этой проблемы, и на данный момент считаю CSS в JS наиболее оптимальным.

Давайте посмотрим, что может CSS в JS.

Проекты отсортированы по размеру

Что такое CSS в языке JS?

Имейте в виду, что стили Inline и CSS в JS – не одно и то же! Ниже краткая демонстрация различий.

Как работают встроенные стили?

const textStyles = {
  color: white,
  backgroundColor: black
}

<p style={textStyles}>inline style!</p>

В браузере это будет привязано к узлу DOM следующим образом:

<p style="color: white; backgrond-color: black;">inline style!</p>

Как работают CSS в JS?

import styled from 'styled-components';

const Text = styled.div`
  color: white,
  background: black
`

<Text>Hello CSS-in-JS</Text>

В браузере это будет привязано к DOM, например вот так:

<style>
.hash136s21 {
  background-color: black;
  color: white;
}
</style>

<p class="hash136s21">Hello CSS-in-JS</p>

Различия

Увидели разницу? CSS в языке JS приложил тег <style> поверх DOM, а встроенные стили просто привязали свойства к узлу DOM.

Ну и почему это важно?

Не все CSS-функции корректно работают с обработчиками событий JavaScript, многие псевдоселекторы (например disabled, before, nth-child) невозможны, не поддерживаются html и body, а также другие неприятные вещи.

Используя эту технологию, все возможности CSS остаются у вас под рукой. Поскольку создается фактический CSS, вы можете использовать каждый медиа-запрос и псевдоселектор. Некоторые библиотеки (например, jss, styled-components) даже добавляют поддержку функций, не связанных с CSS, и это круто!

Если хотите ещё подробнее, можно почитать в этом блоге.

CSS никогда не использовался для компонентных подходов. CSS в JS решают именно эту проблему.

В чём преимущества использования?

  • Вам больше не нужно поддерживать набор стилей. CSS в JS абстрагируют модель CSS на уровне компонентов, а не на уровне документа (это называется модульность).
  • Данная технология использует всю мощь экосистемы JavaScript для улучшения CSS.
  • Ограниченных селекторов недостаточно. CSS имеет свойства, которые автоматически наследуются от родительского элемента, если они явно не определены. Благодаря плагину jss-isolate, правила JSS не наследуют свойства.
  • Невозможно избежать селекторных столкновений в нетривиальных приложениях. Соглашения об именах, таких как BEM, могут помочь в рамках одного проекта, но не будут использоваться при интеграции стороннего кода. При компиляции JSS генерирует уникальные имена классов по умолчанию JSON-представления в CSS.
  • Правила CSS автоматически начинаются с префикса, поэтому вам не нужно об этом думать.
  • Легкое разделение констант и функций между JS и CSS (для тех кто не понял, это про совместное использование кода).
  • В DOM находятся те же стили, которые в настоящее время используются на вашем экране.
  • Удаление кода.
  • Юнит-тесты для CSS.

В чём недостатки использования?

  • Не так просто освоить.
  • Новые зависимости, к которым нужно привыкать.
  • Новичкам сложнее адаптироваться к кодовой базе.

Короче, если всё освоить, то недостатков нет.

Наиболее популярные библиотеки

Styled Components

import React, { Component } from 'react';
import styled from 'styled-components';

const Title = styled.h1`
  color: white;
`;

const Wrapper = styled.div`
    background: black
`

class App extends Component {
  render() {
    return (
        <Wrapper>
            <Title>Hello World!</Title>
        </Wrapper>
    );
  }
}

export default App;

JSS-React

import React from 'react'
import injectSheet from 'react-jss'

const styles = {
    wrapper: {
        background: 'black'
    },
    title: {
        color: 'white'
    }
}


const App = ({classes}) => (
    <div className={classes.wrapper}>
        <h1 className={classes.title}>
            Hello JSS-React!
        </h1>
    </div>
)

export default injectSheet(styles)(App)

glamorous

import React from 'react'
import glamorous from 'glamorous'

const Wrapper = glamorous.div({
    backgroundColor: 'black'
})

const Title = glamorous.h1({
    color: 'white'
})

const App = () => (
    <Wrapper>
        <Title> Hello JSS-React!</Title>
    </Wrapper>
)

export default App;

Radium

import React, { Component } from 'react';
import Radium from 'radium';

@Radium // decorator
class App extends Component {
	render() {

        const styles = {
            wrapper: {
                background: 'blue',
            }
            title: {
                color: 'white'
            }
        };

		return (
            <div style={styles.wrapper}>
                <h1 style={styles.title}>Hello Radium!</h1>
            </div>
		);
	}
}

export default Radium(App);

Внимание: Radium использует декораторы!

Aphrodite

import React, { Component } from 'react';
import { StyleSheet, css } from 'aphrodite';

const styles = StyleSheet.create({
    wrapper: {
        backgroundColor: 'red'
    },
    title: {
        backgroundColor: 'blue'
    }
});

class App extends Component {
    render() {
        return (
            <div className={css(styles.wrapper)}>
                <h1 className={css(styles.title)}>Hello Aphrodite!<h1>
            </div>;
        )
    }
}

Stylotron

import React, { Component } from 'react';
import { styled } from 'styletron-react';

const Wrapper = styled('div', {
    backgroundColor: 'black'
})

const Title = styled('h1', {
    color: 'white'
})

class App extends Component {
    render() {
        return (
            <Wrapper>
                <Title>Hello Styletron!<Titleh1>
            </Wrapper>;
        )
    }
}

Это действительно простые примеры, демонстрирующие основные функции. Само собой, все библиотеки имеют гораздо больше функциональных возможностей.

Несколько полезных ссылок

Перевод статьи Indrek Lasn

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

Frog Proger
25 ноября 2024

🎨 5 CSS-приемов, которые нужно знать каждому фронтендеру

5 мощных CSS-техник для современной веб-разработки: селектор :has(), компак...
Frog Proger
22 августа 2024

🤹 25 CSS-трюков, которые должен знать каждый разработчик

Современный веб-дизайн требует глубокого понимания возможностей CSS. Мы рас...
mylnikovkirill103
05 августа 2024

🕸 7 HTML-трюков, которые вам нужно знать

Семь HTML-трюков, которые должны быть в арсенале каждого веб-разработчика. ...