Главная Категории Контакты Поиск

Знакомство со Styled components

Что такое Styled components и как его использовать.

Css ·31.01.2019·читать 10 мин 🤓·Автор: Alex Myzgin

Введение

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.

Website, name & logo
Copyright © 2019. Alex Myzgin