Что нужно знать о 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>; ) } }
Это действительно простые примеры, демонстрирующие основные функции. Само собой, все библиотеки имеют гораздо больше функциональных возможностей.
Несколько полезных ссылок
- Обо всех возможностях технологии можно почитать тут;
- Полный список библиотек;
- Если CSS-in-JS не катит, посмотрите на CSS Modules;
- 21 совет профессионалов в CSS.