- Введение
- Установка
- Первый Styled Component
- Кастомизация компонентов с помощью props
- Разширение стилей компонента
- Стилизация любого компонента
- Определение стилизованного компонента вне метода render
- Псевдоэлементы, псевдо-селекторы и вложенность
Введение
Styled Components являются одним из новых способов использования CSS в современном JavaScript. Они предназначен для написания CSS, который ограничен одним компонентом.
Что важно понять о Styled Components, так это то, что его название следует понимать буквально. Ты больше не стилизуешь элементы HTML на основе их класса:
<button className="btn">Click</button>
button.btn {
font-size: 2em;
background-color: black;
color: white;
}
Вместо этого ты определяешь стилизованные компоненты, которые имеют свои собственные инкапсулированные стили:
const Button = styled.button`
font-size: 2em;
background-color: black;
color: white;
`;
Styled Components позволяют писать простой CSS в компонентах, не беспокоясь о конфликтах имен классов.
Установка
Просто установи styled-components, используя npm или yarn:
npm install styled-components
yarn add styled-components
Важно!
Настоятельно рекомендуется (но не обязательно) использовать плагин Babel. Он предоставляет множество преимуществ, таких как более разборчивые имена классов, совместимость рендеринга на стороне сервера, небольшие пакеты и многое другое.
Первый Styled Component
Styled Components используют шаблонные строки (template literals) для стилизации компонентов; это простой JavaScript и способ передачи аргумента функции.
Когда ты определяешь свои стили, на самом деле ты создаешь нормальный React компонент, к которому прикреплены твои стили.
Импортировав styled
объект, можно начать создавать стилизованные компоненты. Например:
import styled from "styled-components";
const Button = styled.button`
// тут стили
`;
render(
<div>
<Button> Button </Button>
</div>,
);
Важно!
Styled-components
автоматически добавляют все необходимые вендорные префиксы, поэтому тебе больше не нужно об этом беспокоиться!
Кастомизация компонентов с помощью props
Когда ты передаешь props в Styled Component, то они передаются нижестоящим DOM узлам.
Например, вот как мы передаем placeholder
и type
компоненту input
:
const Input = styled.input`
font-size: 18px;
padding: 10px;
margin: 10px;
background: papayawhip;
border: none;
border-radius: 3px;
::placeholder {
color: palevioletred;
}
`;
render(
<div>
<Input type="text" placeholder="Name" />
<Input type="text" placeholder="Last Name" />
</div>,
);
Он, вставит эти props
в качестве атрибутов HTML. Также, на основе значений этих props, можно кастомизировать компонент.
Например:
const Button = styled.button`
color: ${(props) => (props.primary ? "white" : "palevioletred")};
background: ${(props) => (props.primary ? "palevioletred" : "white")};
font-size: 20px;
margin: 10px;
padding: 5px 20px;
border: 2px solid palevioletred;
border-radius: 3px;
`;
render(
<div>
<Button> Normal Button </Button>
<Button primary> Primary Button </Button>
</div>,
);
Добавив primary
prop, мы поменяли цвет и фон кнопки.
Разширение стилей компонента
Если у тебя есть один компонент, и ты хочешь создать аналогичный, поменяв немного стили, ты можешь просто поместить его в конструктор styled()
и он унаследует стили другого:
const Button = styled.button`
color: palevioletred;
font-size: 20px;
margin: 10px;
padding: 5px 20px;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// Новый компонент на основе Button, но с новыми стилями
const TomatoButton = styled(Button)`
color: tomato;
border-color: tomato;
`;
render(
<div>
<Button> Normal Button </Button>
<TomatoButton>Tomato Button</TomatoButton>
</div>,
);
В некоторых случаях может возникнуть необходимость изменить какой-то тег, например, при построении панели навигации, где есть несколько якорных ссылок и кнопок, но они должны быть стилизованы одинаково.
Ты можешь использовать полиморфный prop as
, чтобы динамически поменять элемент, который получает твои стили:
const Button = styled.button`
font-family: monospace;
display: inline-block;
color: palevioletred;
font-size: 18px;
margin: 20px;
padding: 10px 20px;
border: 2px solid palevioletred;
border-radius: 3px;
display: block;
text-decoration: none;
`;
const TomatoButton = styled(Button)`
color: tomato;
border-color: tomato;
`;
render(
<div>
<Button>Normal Button</Button>
<Button as="a" href="/">
Link with Button styles
</Button>
<TomatoButton as="a" href="/">
Link with Tomato Button styles
</TomatoButton>
</div>,
);
Это также работает и с кастомными компонентами!
const Button = styled.button`
// тут стили
`;
const ReversedButton = (props) => (
<button {...props} children={props.children.split("").reverse()} />
);
render(
<div>
<Button>Normal Button</Button>
<Button as={ReversedButton}>Custom Button with Normal Button styles</Button>
</div>,
);
Важно!
Если ты по-прежнему используешь более старую чем v4 версию, ты можешь использовать .withComponent или .extend API для достижения того же результата, что и при использовании свойства “as”. Но имей в виду, что это не рекомендуется, так как с v4 .extend
был удален, а .withComponent
в будущем больше не будет поддерживаться.
Стилизация любого компонента
Метод styled()
отлично работает на всех собственных или сторонних компонентах, если они используют переданный prop className
элементу DOM.
// Это может быть ссылка Link с react-router-dom, например:
const Link = ({ className, children }) => (
<a className={className}>{children}</a>
);
const StyledLink = styled(Link)`
color: palevioletred;
font-weight: bold;
`;
render(
<div>
<Link>Unstyled, boring Link</Link>
<br />
<StyledLink>Styled, exciting Link</StyledLink>
</div>,
);
Важно!
Ты также можешь передавать имена тегов в вызов фабрики styled()
, например: styled("div")
. На самом деле styled.tagname - это просто псевдонимы, которые делают то же самое.
Обрати внимание, что мы добавили префикс “Styled” в StyledLink
, чтобы React компонент Link
и стилизованный компонент StyledLink
не конфликтовали с именами, а оставались легко идентифицируемыми в React Developer Tools и Web Inspector.
Определение стилизованного компонента вне метода render
Важно определять стилизованный компонент вне метода render, иначе он будет воссоздан при каждом проходе рендеринга. Определение стилизованного компонента в методе рендеринга нарушит кеширование и существенно замедлит скорость рендеринга, поэтому его следует избегать.
Псевдоэлементы, псевдо-селекторы и вложенность
Псевдо-селекторы и псевдоэлементы без дальнейшей доработки автоматически присоединяются к компоненту:
const Thing = styled.button`
color: blue;
::before {
content: "🚀";
}
:hover {
color: red;
}
`;
render(<Thing>Hello world!</Thing>);
Для более сложных шаблонов, амперсанд (&) может использоваться для обращения к основному компоненту. Если ты используешь селекторы без амперсанда, они будут ссылаться на дочерние элементы компонента.
Также, амперсанд может быть использован для повышения специфичности правил для компонента; это может быть полезно, если ты имеешь дело со смесью стилевых компонентов и vanilla CSS, где могут быть конфликтующие стили:
const Thing = styled.div`
&& {
color: blue;
}
`;
const GlobalStyle = createGlobalStyle`
div${Thing} {
color: red;
}
`;
render(
<React.Fragment>
<GlobalStyle />
<Thing>I'm blue, da ba dee da ba daa</Thing>
</React.Fragment>,
);
Источник: Styled Components Basics.