Доброго времени суток, друзья!
Представляю вашему вниманию перевод небольшой заметки про использование стилизованных компонентов (далее — СК) в React.
Без лишних слов.
Что такое СК?
СК — это библиотека для React и React Native для создания и управления CSS.
Данное решение относится к концепции «CSS-in-JS», когда вы определяете CSS прямо в JavaScript-файле (т.е. в компоненте в случае с React).
О популярности этого решения в среде React-разработчиков свидетельствует около 8 млн скачиваний в месяц из npm и 30 тыс звезд на GitHub.
Разумеется, для знакомства со СК необходимо хотя бы в общих чертах знать React.
Преимуществами СК является следующее:
- Это обычный CSS. Да, вы пишете CSS в JS-файле, но синтакис от этого не меняется
- При использовании СК автоматически добавляются вендорные префиксы, обеспечивающие кроссбраузерность
- Неиспользуемые стили также автоматически удаляются
- Более того, автоматически генерируются названия классов компонентов, что избавляет от необходимости использования методогии типа БЭМ
Установка СК
Для использования СК нужно их сначала установить:
npm i styled-components
Далее их нужно импортировать в каждом файле, в котором они будут использоваться:
import styled from 'styled-components'
После этого можно с ними работать.
Создание СК
Откройте проект, над которым вы работаете, или быстро создайте его с помощью npx create-react-app app-name и откройте любой компонент, например, App.js.
Давайте добавим в него наш первый СК:
// App.js
import React from 'react'
import styled from 'styled-components'
// СК
const Button = styled.a`
background-color: teal;
color: white;
padding: 1rem 2rem;
`
const App = () => {
return (
<Button>Кнопка</Button>
)
}
export default App
Разберем данный код:
- Объявляем название компонента посредством const Button
- styled предоставляет нам функционал СК
- Обратите внимание на «a» после styled. Это HTML-тег «a». В СК можно использовать любые HTML-теги (section, h1, div и т.д.)
<Button>, возвращаемый в App, это обычный React-компонент.
В предыдущем примере мы создали СК внутри существующего компонента.
Однако это можно (и даже нужно) сделать в отдельном файле (например, в Button.js):
// Button.js
import styled from 'styled-components'
const Button = styled.a`
background-color: teal;
color: white;
padding: 1rem 2rem;
`
export default Button
После этого мы можем импортировать Button как любой другой компонент:
// App.js
import React from 'react'
import styled from 'styled-components'
// импортируем кнопку
import Button from './Button'
const App = () => {
return (
<Container>
<Button>Кнопка</Button>
</Container>
)
}
export default App
Готово.
Поздравляю, вы только что создали свой первый СК.
Использование пропсов для редактирования СК
Представьте, что у вас есть компонент Button, и вам нужно применять к нему разные стили в зависимости от назначения кнопки (primary — главная или основная, secondary — второстепенная или дополнительная, danger — опасность, предупреждение и т.д.)
Для этого можно использовать пропсы.
Рассмотрим пример.
Здесь мы рендерим две кнопки, стиль одной из который зависит от пропса:
// App.js
import React from 'react'
import styled from 'styled-components'
import Button from './Button'
const App = () => {
return (
<>
<Button>Кнопка</Button>
<Button primary>Главная кнопка</Button>
</>
)
}
export default App
Обратите внимание на использование сокращенного синтаксиса фрагмента (<></>).
После этого добавляем динамические стили в компонент Button:
// Button.js
import styled from 'styled-components'
const Button = styled.a`
display: imline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
border: 2px solid white;
background: ${props => props.primary ? 'white' : 'palevioletred'};
color: ${props => props.primary ? 'palevioletred' : 'white'};
`
export default Button
Здесь мы возвращаем то или иное значение CSS-свойства в зависимости от пропса.
Выражение background: ${props => props.primary? 'white': 'palevioletred'} означает, что если пропс будет иметь значение true, то цвет фона будет белым, а цвет текста — palevioletred.
Такой способ можно использовать в простых случаях, однако он не подходит для случаев, когда нужно обрабатывать несколько пропсов, а также при наличии нескольких свойств, зависящих от них.
Поэтому имеет смысл импортировать { css } из styled-components:
// Button.js
import styled, { css } from 'styled-components'
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
${props => props.primary && css`
background: white;
color: palevioletred;
`}
`
export default Button
Это позволяет использовать динамические стили для разных пропсов.
Например, добавим стили для danger:
// Button.js
import styled, { css } from 'styled-components'
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
${props => props.primary && css`
background: white;
color: palevioletred;
`}
${props => props.danger && css`
backround: red;
color: white;
`}
`
export default Button
Отлично.
Как сделать кнопку более отзывчивой или адаптированной?
Использование медиа-запросов
Для этого следует добавить медиа-запросы в шаблон (внутрь шаблонного или строкового литерала):
// Button.js
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 9rem;
background: transparent;
color: white;
border: 2px solid white;
@media (min-width: 768px) {
padding: 1rem 2rem;
width: 11rem;
}
@media (min-width: 1024px) {
padding: 1.5rem 2.5rem;
width: 13rem;
}
`
export default Button
Обработка псевдоселекторов
Это делается по аналогии с медиа-запросами.
Например, добавим обработку наведения курсора на кнопку (псевдоселектор hover):
// Button.js
import styled from 'styled-components'
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 9rem;
background: transparent;
color: white;
border: 2px solid white;
:hover {
border-color: green;
}
`
export default Button
Создание глобальных стилей
Основная ментальная модель React — все есть компонент.
Для этого интерфейс приложения разбивается на отдельные части, а затем эти части собираются в один файл таким образом, чтобы сохранялась возможность расширения или масштабирования приложения.
Такой подход имеет ряд преимуществ, но существует одна проблема: как использовать одинаковые стили для нескольких компонентов? Т.е. как применить глобальные стили?
Мы можем, например, захотеть следующее:
- Установить шрифт для всего текста
- Установить фон для всех страниц
- Перезаписать некоторые браузерные стили (т.е. стили, устанавливаемые по умолчанию)
В СК для этого используется функция createClodabStyle.
Сначала откройте основной компонент приложения.
Таким компонентом, обычно, является App.js.
Затем импортируйте в него createClodabStyle и определите некоторые стили в компоненте GlobalStyle (вы можете назвать его как угодно):
// App.js
import React from 'react'
import styled, { createGlobalStyle } from 'styled-components'
import { Container, Nav, Content } from '../components'
const GlobalStyle = createGlobalStyle`
body {
margin: 0;
padding: 0;
background: teal;
font-family: Open-Sans, Helvetica, Sans-Serif;
}
`
const App = () => {
return (
<Container>
<Nav />
<Content />
</Container>
)
}
export default App
Для того, чтобы это работало, нужно добавить созданный компонент в начало App:
// App.js
import React from 'react'
import styled, { createClodabStyle } from 'styled-components'
import { Container, Nav, Content } from '../components'
const GlobalStyle = createGlobalStyle`
body {
margin: 0;
padding: 0;
background: teal;
font-family: Open-Sans, Helvetica, Sans-Serif;
}
`
const App = () => {
return (
<>
<GlobalStyle />
<Container>
<Nav />
<Content />
</Container>
</>
)
}
export default App
Добавление GlobalStyle в качестве узла в начало виртуального DOM является обязательным требованием для использования глобальных стилей.
Надеюсь, статья была вам полезной. Благодарю за внимание.
alexr64
Каким боком?