Если ты новичок в React, тебе может быть интересно, почему существует так много разных руководств, которые учат различным способам стилизации React приложения. По правде говоря, мы всё еще пытаемся понять, как лучше поступить.
Стили в React более или менее прорабатывались в таком порядке:
- глобальный CSS;
- модули CSS;
- CSS в JS (styled-components, Emotion, и тд.);
- статически извлеченный CSS в JS.
Я рекомендую начать с CSS в JS. Почему? Читай дальше 😄
Заметка
Когда я говорю о стилях, то имею в виду написание своих CSS стилей более или менее с нуля. Если ищешь готовые компоненты, лови руководство по часто используемым React UI библиотекам.
Глобальный CSS
Глобальный CSS - это, тот способ которым ты вероятно уже стилизовал веб-страницы. У тебя есть гигантский файл styles.css
, и ты используешь BEM или SMACSS методологию для всех своих классов. В качестве альтернативы, у тебя есть тонна крошечных файлов, и ты не всегда знаешь, где находится каждый класс.
Мы, как frontend разработчики, быстро поняли, что глобальный CSS не масштабируется. Чем больше команда редактирует один файл, тем больше вероятность, что будет CSS, который ничего не делает (люди слишком боятся что-либо удалять, вдруг они что-то сломают).
Если ты всё еще хочешь использовать Global CSS в своем React приложении, то всё, что нужно сделать - это импортировать файл CSS на верхнем уровне приложения React (при условии, что ты настроил для этого webpack или используешь приложение create-react-app).
//App.js
import './styles.css'; // <- Глобальный CSS
import React from 'react';
const App = () => {
return <div className="some-class">...твой код</div>;
};
Модули CSS
Модули CSS очень похожи на Global CSS в том смысле, что ты импортируешь CSS файл в свой React компонент, но внутри всё совсем иначе.
Многие проблемы, которые у нас были с Global CSS, исчезли с модулями CSS.
Твой CSS выглядит так:
/* style.css */
.makeItGreen {
color: green;
}
а твой React компонент выглядит так:
import React from 'react';
import styles from './style.css';
const MyComponent = () => {
return <div className={styles.makeItGreen}>Green!</div>;
};
Ключевое отличие здесь заключается в том, что только файлы, импортирующие style.css
, смогут получить доступ к именам классов, которые он определяет. Более того, имена классов, сгенерированные в процессе сборки, будут уникальными.
Больше никаких конфликтов, никакого «страшно что-либо удалять, вдруг что то сломаю», только локальный CSS. Ты также можешь настроить поддержку SCSS/LESS
, если это нужно.
По-настоящему круто то, что ты можешь начать экспериментировать с JavaScript, чтобы изменить стили компонента.
import React from 'react';
import styles from './style.css';
const MyComponent = (props) => {
const myStyle = props.color === 'RED' ? styles.makeItRed : styles.makeItGreen;
return <div className={myStyle}>{props.color}!</div>;
};
Правда, такой подход, начинает становиться немного запутанным, если ты используешь несколько свойств для изменения стиля и поведения компонентов. Что, если бы твои стили могли быть просто компонентами?
CSS в JS
Вот где на помощь приходит CSS в JS.
Библиотеки, такие как styled-components и Emotion, позволяют оборачивать компоненты (включая div, spans, теги p, теги a) стилями и использовать их в качестве компонентов React.
Самое приятное, что мы можем использовать все стандартные функции CSS, к которым привыкли, такие как медиа-запросы и селекторы :hover
и :focus
.
Наш пример сверху теперь выглядит следующим образом:
import React from 'react';
import styled from '@emotion/styled';
// Или
import styled from 'styled-components';
const StyledGreenThing = styled.div`
color: ${(props) => (props.color === 'RED' ? 'red' : 'green')};
`;
const MyComponent = (props) => {
return (
<StyledGreenThing color={props.color}>{props.color}!</StyledGreenThing>
);
};
Emotion и styled-components равномерно согласованы по производительности. Авторы styled-components работали, чтобы довести их производительность до уровня Emotion, поэтому решить, какой из них использовать не имеет больше значения.
Emotion предоставляет некоторые дополнительные возможности для стилизации: css prop. В то время как styled-components пытается сохранить единый стандартный способ работы с помощью styled
API.
Utility-first CSS
Руководство по стилизации React приложений было бы неполным, если бы я не упомянул CSS-фреймворки, такие как Tailwind. На самом деле тебе не нужен React для использования Utility-first CSS.
Короче говоря, Tailwind позволяет стилизовать компоненты по одному классу за раз. Вот как это выглядит:
<div className="md:flex bg-white rounded-lg p-6">
<img
className="h-16 w-16 md:h-24 md:w-24 rounded-full mx-auto md:mx-0 md:mr-6"
src="avatar.jpg"
/>
<div className="text-center md:text-left">
<h2 className="text-lg">Erin Lindford</h2>
<div className="text-purple-500">Product Engineer</div>
<div className="text-gray-600">erinlindford@example.com</div>
<div className="text-gray-600">(555) 765-4321</div>
</div>
</div>
Можно решить, что это не особо подходит для повторного использования, однако, можно использовать имена классов Tailwind с любимой библиотекой CSS in JS, используя twin.
Затем ты можешь стилизовать компоненты Tailwind:
import tw, { styled } from 'twin.macro';
const Input = styled.input`
color: purple;
${tw`border rounded`}
`;
export const MyStyledInput = () => {
return <Input />;
};
Styled System
Styled System использует styled
API, предоставляемый styled-components
или Emotion
, и добавляет утилиты в качестве свойств, а не имен классов.
Подход Styled System особенно эффективен, когда речь идет о темах, поскольку изменить внешний вид приложения можно, заменив предоставленный тобой файл theme.js
.
Твой компонент в конечном итоге будет выглядеть так:
import styled from '@emotion/styled';
import { typography, space, color } from 'styled-system';
const Box = styled('div')(typography, space, color);
const UsedBox = () => {
return (
<Box
fontSize={4}
fontWeight="bold"
p={3}
mb={[4, 5]}
color="white"
bg="primary"
>
Hello
</Box>
);
};
Статически извлеченный CSS в JS
Проблема с CSS в JS заключается в том, что для загрузки CSS требуется JavaScript. Это значительно замедляет работу, поэтому люди начали искать способы извлечения CSS из CSS-in-JS во время сборки.
Есть несколько библиотек, которые могут это сделать:
Compiled и linaria позволяют нам использовать styled
API, который мы знаем и любим, давая преимущество в производительности за счет отсутствия CSS в нашем бандле.