Оглавление

  • Брифинг
  • Примечание для читателя
  • Рабочее пространство и HTML
  • JavaScript, React.js и Styled-компоненты
  • Больше модульности
  • Расширение стилизованных компонентов
  • Адаптивные стилизованные компоненты и использование реквизита
  • Заключительные мысли о стилизованных компонентах

Стилизованные компоненты становятся все более популярными. Многие проекты, созданные с помощью React.js, используют эту библиотеку. Это не удивительно. Стилизованные компоненты делают работу с CSS простой и увлекательной даже в JavaScript. Однако все требует практики, особенно когда вы хотите мастерства. Это цель данной статьи. Вернемся к основам стилизованных компонентов и практики.

Брифинг

Как обычно, давайте начнем с краткого введения и определим цели для сегодняшней практики. Итак, над чем мы будем работать? Эта статья будет посвящена практике работы со стилями-компонентами. Мы будем использовать эту библиотеку для создания ряда различных примеров. И, чтобы немного упростить задачу, мы начнем с простых примеров. Затем мы постепенно перейдем к более сложному.

Эта статья или руководство не требует каких-либо предварительных знаний о styled-components или React.js. Я постараюсь объяснить те части, которые могут доставить вам некоторые проблемы. Так что, даже если вы ничего не знаете о styled-components или React.js, вы сможете следовать ему. При этом, если у вас есть некоторые знания, вам будет легче понять код, как он работает и почему.

Если вы хотите узнать больше о стилизованных компонентах, вам обязательно стоит взглянуть на два ресурса. Первый - сайт и документация для styled-компонентов. Второй - введение в стилизованные компоненты, опубликованные в этом блоге. Вы можете взглянуть на оба варианта сейчас или сделать это позже, когда получите некоторый опыт работы со стилями-компонентами.

Примечание для читателя

Я хочу сказать еще кое-что. Если вам не нравится идея смешать код CSS с JavaScript, прямо в компоненте React, не уходите. Дайте возможность стилизованным компонентам. Я знаю, что ты чувствуешь. Я был в одной лодке. Мне очень не понравилась эта идея. Однако я попробовал стилизованные компоненты на нескольких примерах, а затем на паре проектов. И этот опыт изменил мое мнение.

Начать работу со стилями-компонентами было очень легко, и работа с ними казалась естественной, как работа с ванильным CSS, Sass или PostCSS. Я должен сказать, что стилизованные компоненты буквально подняли модульность моего кода на новый уровень. Это будет звучать легко, но наличие всего кода для компонента, CSS и JavaScript / React.js в одном месте намного понятнее и позволяет работать быстрее.

Итак, взгляните на примеры, над которыми мы сегодня будем работать. Играйте и экспериментируйте с кодом. Ознакомьтесь с документацией и введением в стилизованные компоненты. И убедитесь сами, нравится вам такой подход или нет. Есть шанс, что вы передумаете. Ну, может быть. А если нет, что может случиться в худшем случае? Вы узнаете что-то новое и вернетесь к понравившемуся подходу.

Рабочее пространство и HTML

Ладно, хватит болтать и приступим к работе. Во-первых, нам нужно настроить рабочее пространство. Помимо стилизованных компонентов, нам нужно будет использовать две дополнительные библиотеки. Мы будем использовать CDN, чтобы получить их обоих, а также библиотеку для styled-components. Это библиотеки React.js и React-DOM. Мы будем использовать CDN, чтобы получить и то, и другое. Еще воспользуемся транспайлером бабель. Это упростит работу с React.js.

Второе, что нам нужно, это подготовить HTML-документ, в котором мы будем отображать наши компоненты React.js. Это будет быстро и просто, так как остальная часть нашего кода будет в JavaScript / React.js. Все, что нам нужно, - это один элемент div. Как я уже сказал, мы будем использовать этот элемент в качестве «заполнителя» для рендеринга наших компонентов React. Дадим ему класс «контейнер». И это все, что касается HTML.

Код:

<div class="container"></div>

JavaScript, React.js и Styled-компоненты

Теперь, когда все настроено и готово, мы, наконец, можем начать играть со стилями-компонентами. Как я уже упоминал в начале, мы начнем с основных вещей. Что ж, на самом деле нет ничего сложного в стилизованных компонентах или CSS, если на то пошло. В любом случае, давайте начнем с основ и создадим несколько стилей оформления для заголовков и основного текста, используя font-weight и font-size.

Код:

// Import React.js and styled-components
import React from 'react'
import styled from 'styled-components'
const container = document.querySelector('.container')
// Define typography styles
const H1 = styled.h1`
  font-size: 54px;
  font-weight: bold;
`
const H2 = styled.h2`
  font-size: 36px;
  font-weight: bold;
`
const H3 = styled.h3`
  font-size: 24px;
  font-weight: bold;
`
const H4 = styled.h4`
  font-size: 16px;
  font-weight: bold;
`
const H5 = styled.h5`
  font-size: 14px;
  font-weight: bold;
`
const H6 = styled.h6`
  font-size: 12px;
  font-weight: bold;
`
const Text = styled.p`
  font-size: 16px;
`
const Small = styled.small`
  font-size: 80%;
`
// Use our styles
const WrapperContainer = () => (
  <div>
    <H1>Heading h1</H1>
    <H2>Heading h2</H2>
    <H3>Heading h3</H3>
    <H4>Heading h4</H4>
    <H5>Heading h5</H5>
    <H6>Heading h6</H6>
    <Text>Body text</Text>
    <Small>Small text</Small>
  </div>
)
ReactDOM.render(
  <WrapperContainer />,
  container
)

Больше модульности

Как вы можете видеть в приведенном выше примере, работа со стилями-компонентами похожа на работу с ванильным CSS. Возможно, вам понадобится немного времени, чтобы запомнить другой способ определения стилей, например, с помощью const, как в нашем примере. Однако до ракетостроения еще далеко. Теперь вернемся к нашему примеру. Вы что-то заметили на нем? Да, мы используем один и тот же font-weight несколько раз.

Это не проблема, когда наш код очень короткий, как в этом случае. Однако мы можем написать наш код лучше и более модульным, чем это. Что, если мы определим новый const, установим для его font-weight значение «bold», а затем будем использовать эту переменную в каждом стиле заголовка? Затем, если что-то случится, мы решим изменить этот font-weight, мы должны изменить его только в одном месте.

Это изменение будет простым и быстрым. Однако нам нужно будет импортировать еще один метод из библиотеки стилизованных компонентов. Этот метод определяется и экспортируется из библиотеки стилизованных компонентов как css. Давайте изменим вторую строку с помощью импорта стилизованных компонентов и включим метод css. Помните, что «css» пишется строчными буквами. Затем мы можем определить эту многократно используемую const жирным шрифтом.

После этого мы можем использовать эту новую const когда угодно и где угодно. Все, что нам нужно сделать, это использовать синтаксис ${} с именем конкретной const в фигурных скобках.

Код:

// Import React.js, styled-components and css
import React from 'react'
import styled, { css } from 'styled-components'
const container = document.querySelector('.container')
// Define new const with bold style
const headingStyle = css`
  font-weight: bold;
`
// Define typography styles
const H1 = styled.h1`
  font-size: 54px;
  // Using headingStyle const
  ${headingStyle}
`
const H2 = styled.h2`
  font-size: 36px;
  // Using headingStyle const
  ${headingStyle}
`
const H3 = styled.h3`
  font-size: 24px;
  // Using headingStyle const
  ${headingStyle}
`
const H4 = styled.h4`
  font-size: 16px;
  // Using headingStyle const
  ${headingStyle}
`
const H5 = styled.h5`
  font-size: 14px;
  // Using headingStyle const
  ${headingStyle}
`
const H6 = styled.h6`
  font-size: 12px;
  // Using headingStyle const
  ${headingStyle}
`
const Text = styled.p`
  font-size: 16px;
`
const Small = styled.small`
  font-size: 80%;
`
// Use our styles
const WrapperContainer = () => (
  <div>
    <H1>Heading h1</H1>
    <H2>Heading h2</H2>
    <H3>Heading h3</H3>
    <H4>Heading h4</H4>
    <H5>Heading h5</H5>
    <H6>Heading h6</H6>
    <Text>Body text</Text>
    <Small>Small text</Small>
  </div>
)
ReactDOM.render(
  <WrapperContainer />,
  container
)

Нам нужно помнить об одном. Если мы определим эту const в другом файле и захотим использовать ее в другом месте, нам нужно будет экспортировать ее из исходного файла, а затем импортировать туда, где мы хотим использовать.

Код:

// File foo.js
// Import React.js, styled-components and css
import React from 'react'
import styled, { css } from 'styled-components'
// Define and export new const with bold style
export const headingStyle = css`
  font-weight: bold;
`
// File bar.js
// Import React.js, styled-components and css
import React from 'react'
import styled, { css } from 'styled-components'
// Import our const
import { headingStyle } from './styles/foo'
const container = document.querySelector('.container')
// Define typography styles
const H1 = styled.h1`
  font-size: 54px;
  // Using headingStyle const
  ${headingStyle}
`
// Use our styles
const WrapperContainer = () => (
  <div>
    <H1>Heading h1</H1>
  </div>
)
ReactDOM.render(
  <WrapperContainer />,
  container
)

Опять же, важно помнить, что мы должны экспортировать любую без исключения переменную const, которую мы хотели бы использовать, как в приведенном выше примере, а затем импортировать ее туда, где мы хотим ее использовать. При этом, если у нас есть только одна переменная, функция, метод или классы, которые мы хотим экспортировать из файла, мы можем экспортировать их как «по умолчанию». Тогда нам не нужно будет использовать фигурные скобки («{}») при импорте.

Код:

// File foo.js
// Import React.js, styled-components and css
import React from 'react'
import styled, { css } from 'styled-components'
// Define new const with bold style
const headingStyle = css`
  font-weight: bold;
`
// Export our const as default
export default headingStyle
// File bar.js
// Import React.js and styled-components
import React from 'react'
import styled from 'styled-components'
// Import our const - without curly brackets
import headingStyle from './styles/foo'
const container = document.querySelector('.container')
// Define typography styles
const H1 = styled.h1`
  font-size: 54px;
  // Using headingStyle const
  ${headingStyle}
`
// Use our styles
const WrapperContainer = () => (
  <div>
    <H1>Heading h1</H1>
  </div>
)
ReactDOM.render(
  <WrapperContainer />,
  container
)

Сказав это, мы можем использовать экспорт по умолчанию вместе с именованным экспортом, чтобы мы могли экспортировать несколько переменных, функций, методов или классов. Однако нам нужно помнить, какой экспорт мы использовали для какой переменной, функции, метода или класса. Помните, что по умолчанию для экспорта не требуются фигурные скобки, в отличие от именованных.

Код:

// File foo.js
// Import React.js, styled-components and css
import React from 'react'
import styled, { css } from 'styled-components'
// Define and export some consts
const firstVariable = css`
  font-size: 21px;
  text-decoration: none;
`
const secondVariable = css`
  text-align: center;
  color: #black;
`
const thirdVariable = css`
  padding: 4px;
  border: 1px solid gray;
`
// Export our first const as default ad the rest as named
export { firstVariable as default, secondVariable, thirdVariable }
// File bar.js
// Import React.js and styled-components
import React from 'react'
import styled from 'styled-components'
// Import our const - default without curly brackets, named with curly brackets
import firstVariable, { secondVariable, thirdVariable } from './styles/foo'
// Or, we can import our const this way:
// default without curly brackets, named by using "*"
import firstVariable, * from './styles/foo'

Вам интересны операторы import и export? Если вы хотите узнать о них больше, я предлагаю взглянуть на документацию MDN, как для экспорта, так и для импорта. Существует множество примеров, которые помогут вам понять суть этих утверждений и понять, как их правильно использовать. Я надеюсь, что сделал.

Расширение стилизованных компонентов

Хорошо. Теперь мы знаем, как создавать новые компоненты с определенными стилями через переменные с помощью styled-components. Что, если мы хотим иметь одну переменную с определенными стилями и использовать ее для обоих компонентов, а также для расширения стилей других компонентов, как мы это сделали с «headingStyle» и «H1»? Мы можем сделать именно это, расширить компонент, я имею в виду почти буквально. Мы можем использовать extend.

Что нам нужно сделать, так это определить новую переменную для некоторого компонента, скажем, кнопки. Затем мы добавим несколько стилей, чтобы эта кнопка выглядела лучше. После этого мы создадим другую переменную или другую кнопку, которая унаследует стили первой, но при этом будет иметь свои собственные. Вместо синтаксиса const * = styled.*, который мы использовали для первой кнопки, мы будем использовать const * = Button.extend.

И еще одно: нам не нужно импортировать какие-либо дополнительные методы из библиотеки styled-components, как это было в случае с css. Нам нужно импортировать только стилизованные компоненты и использовать extend по своему усмотрению. Обратите внимание, что мы импортируем экспорт по умолчанию, потому что нам не нужно заключать «стилизованный» импорт в фигурные скобки.

Код:

// Import React.js and styled-components
import React from 'react'
import styled from 'styled-components'
const container = document.querySelector('.container')
const Button = styled.button`
  padding: 12px 24px;
  font-size: 16px;
  color: #fff;
  border: 0;
  border-radius: 35px;
  box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
  cursor: pointer;
`
// Using extend to create a red variant of the button
const ButtonRed = Button.extend`
  background-color: #e74c3c;
`
// Using extend to create a green variant of the button
const ButtonGreen = Button.extend`
  background-color: #2ecc71;
`
// Use our styles
const WrapperContainer = () => (
  <div>
    <Button>Defaul button</Button>
    <ButtonRed>Red button</ButtonRed>
    <ButtonGreen>Green button</ButtonGreen>
  </div>
)
ReactDOM.render(
  <WrapperContainer />,
  container
)

Адаптивные стилизованные компоненты и использование реквизита

До сих пор мы создавали новые компоненты с определенными стилями с помощью переменных. Затем мы также попрактиковались в том, как определять повторно используемые переменные и как использовать extend. Проблема в том, что код в предыдущем примере все еще слишком длинный. Мы можем сделать его короче и лаконичнее. Для этого мы будем использовать props. Примечание: нам снова нужно будет импортировать «css» из библиотеки стилизованных компонентов.

Затем мы можем использовать props для определения вариантов нашей переменной или компонента без необходимости создавать новые. Мы можем сделать это, используя синтаксис ${props => props.componentProp && css` some styles `}, где «componentProp» - это свойство, которое мы будем прикреплять к варианту нашего компонента по умолчанию.

Код:

// Import React.js, styled-components and css
import React from 'react'
import styled, { css } from 'styled-components'
const container = document.querySelector('.container')
const Button = styled.button`
  padding: 12px 24px;
  font-size: 16px;
  border: 0;
  border-radius: 35px;
  box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
  cursor: pointer;
  // Using props to create a gray variant of the button
  ${props => props.gray && css`
    background-color: #95a5a6;
  `}
  // Using props to create a green variant of the button
  ${props => props.green && css`
    background-color: #2ecc71;
  `}
  // Using props to create a red variant of the button
  ${props => props.red && css`
    background-color: #e74c3c;
  `}
  // We can also use a ternary operator for "binary" changes
  // if button has prop "gray", the color will be "#2c3e50" otherwise it will be "#fff"
  color: ${props => props.gray ? '#2c3e50' : '#fff'};
`
const WrapperContainer = () => (
  <div>
    <Button>Defaul button</Button>
    {/* Button with prop "red" */}
    <Button red>Red button</Button>
    {/* Button with prop "green" */}
    <Button green>Green button</Button>
  </div>
)
ReactDOM.render(
  <WrapperContainer />,
  container
)

Заключительные мысли о стилизованных компонентах

Итак, убедили ли вас стилизованные компоненты передумать о смешивании CSS с JavaScript? Если вы, как и я, привыкли работать с ванильным CSS, Sass или PostCSS, это может показаться странным. Если вы все еще не полностью уверены, возможно, дайте ему немного времени. Затем вы можете взглянуть на примеры, которые мы создали сегодня, свежим взглядом и ясным умом. Или вернитесь к тому, что вам нравится.

И последнее, что я хочу сказать. Сегодня мы сосредоточились на основах styled-components. И, может быть, даже слишком. В результате, возможно, вы сочли эту статью слишком простой. И вы правы. Это было просто, очень просто. Однако необходимо овладеть основами, прежде чем мы сможем двигаться дальше и практиковать более сложные темы.