DevGang
Авторизоваться

Лучшие CSS-утилиты для проектов на React: Практические фрагменты стилизации

В этой статье я хочу поделиться с вами некоторыми из наиболее полезных CSS-утилит, которые я использую в своих проектах на React. Думаю, что многие из них помогут вам не только сэкономить время, но и пригодятся в ваших проектах. Все эти функции и фрагменты можно найти в папке css в пакете ui в репозитории ReactKit.

centerContent - центрирование содержимого внутри

Одним из наиболее практичных сниппетов является centerContent. Он делает родительским элементом flexbox и центрирует дочерние элементы внутри него.

import { css } from "styled-components"

export const centerContent = css`
  display: flex;
  align-items: center;
  justify-content: center;
`

Например, этот флажок имеет заданную ширину и высоту и позиционирует значок флажка внутри с помощью centerContent:

const Box = styled.div<{ isChecked: boolean }>`
  ${sameDimensions(28)}
  ${centerContent};

sameDimensions - ширина и высота устанавливаются в одно и то же значение

Мы использовали функцию sameDimensions, чтобы придать блоку одинаковую ширину и высоту:

import { css } from "styled-components"
import { toSizeUnit } from "./toSizeUnit"

export const sameDimensions = (size: string | number) => {
  const value = toSizeUnit(size)

  return css`
    width: ${value};
    height: ${value};
    min-width: ${value};
    min-height: ${value};
  `
}

Как ширина, так и высота, а также минимальная ширина и минимальная высота устанавливаются этой функцией в одно и то же значение. В эту функцию можно передать строку или число. Если передается число, то оно будет преобразовано в пиксели с помощью функции toSizeUnit:

export const toSizeUnit = (value: number | string) =>
  typeof value === "number" ? `${value}px` : value

verticalPadding, horizontalPadding, verticalMargin, horizontalMargin - Отступы и поля устанавливаются в одно и то же значение

Функции verticalPadding, horizontalPadding, verticalMargin и horizontalMargin также весьма удобны. Часто нам необходимо установить одинаковое значение для верхней и нижней границы, левой и правой. Чтобы не повторять код, можно воспользоваться этими функциями:

import { css } from "styled-components"

import { toSizeUnit } from "./toSizeUnit"

export const verticalPadding = (value: string | number) => css`
  padding-top: ${toSizeUnit(value)};
  padding-bottom: ${toSizeUnit(value)};
`

export const horizontalPadding = (value: string | number) => css`
  padding-left: ${toSizeUnit(value)};
  padding-right: ${toSizeUnit(value)};
`

export const verticalMargin = (value: string | number) => css`
  margin-top: ${toSizeUnit(value)};
  margin-bottom: ${toSizeUnit(value)};
`

export const horizontalMargin = (value: string | number) => css`
  margin-left: ${toSizeUnit(value)};
  margin-right: ${toSizeUnit(value)};
`

За примером далеко ходить не надо. Здесь мы используем их для определения горизонтальной границы для кнопки. Это избавляет нас от излишеств при определении различных отступов для разных вариантов размеров:

 ${({ size }) =>
    match(size, {
      xs: () => css`
        ${horizontalPadding(8)}
        height: 28px;
        font-size: 14px;
      `,
      s: () => css`
        ${horizontalPadding(16)}
        height: 36px;
        font-size: 14px;
      `,
      m: () => css`
        ${horizontalPadding(20)}
        height: 40px;
        font-size: 16px;
      `,
      l: () => css`
        ${horizontalPadding(20)}
        height: 48px;
        font-size: 16px;
      `,
      xl: () => css`
        ${horizontalPadding(40)}
        height: 56px;
        font-size: 18px;
      `,
    })}

cropText - Обрезка текста с многоточием

Мы не хотим, чтобы текст выходил за границы своего блока. Для этого можно использовать функцию cropText, которая добавит многоточие в конце текста, если он не помещается.

import { css } from "styled-components"

export const cropText = css`
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;

Приведем пример, когда один из вариантов имеет длинное название и обрезается многоточием:

maxTextLines - Обрезка текста с многоточием после заданного количества строк

Аналогичную задачу решает функция maxTextLines. Мы можем передать 3 в функцию maxTextLines, и она обеспечит обрезку текста с многоточием после трех строк.

import { css } from "styled-components"

export const maxTextLines = (number: number) => css`
  display: -webkit-box;
  -webkit-line-clamp: ${number};
  -webkit-box-orient: vertical;
  overflow: hidden;
`

absoluteOutline - Элемент контура с абсолютным положением

Следующая функция предназначена для более продвинутого использования.

import { css } from "styled-components"
import { toSizeUnit } from "./toSizeUnit"

export const absoluteOutline = (
  horizontalOffset: number | string,
  verticalOffset: number | string
) => {
  return css`
    pointer-events: none;
    position: absolute;
    left: -${toSizeUnit(horizontalOffset)};
    top: -${toSizeUnit(verticalOffset)};
    width: calc(100% + ${toSizeUnit(horizontalOffset)} * 2);
    height: calc(100% + ${toSizeUnit(verticalOffset)} * 2);
  `
}

Я использую её в Increaser в табло для обводки текущего пользователя:

И на сегодняшней временной шкале для выделения текущего времени:

В ReactKit он используется для многократно используемого компонента Hoverable, создающего эффект выделения при наведении.

takeWholeSpace и takeWholeSpaceAbsolutely - заполнение всего пространства родительского блока

TakeWholeSpace - это небольшая вспомогательная функция, которая устанавливает, что элемент будет занимать 100% ширины и высоты родительского элемента.

import { css } from "styled-components"

export const takeWholeSpace = css`
  width: 100%;
  height: 100%;
`

TakeWholeSpaceAbsolutely выполняет ту же задачу, но с абсолютным положением.

import { css } from "styled-components"
import { takeWholeSpace } from "./takeWholeSpace"

export const takeWholeSpaceAbsolutely = css`
  position: absolute;
  left: 0;
  top: 0;
  ${takeWholeSpace};

Практическое применение этой функции от Increaser - отображение оверлея над пусковой установкой сеанса фокусировки по окончании рабочего дня.

hideScrollbars и themedScrollbars - скрытие полос прокрутки и их стилизация

В ситуациях, подобных этой горизонтальной навигации, нам иногда требуется скрыть полосы прокрутки, что легко сделать с помощью функции hideScrollbars:

import { css } from "styled-components"

export const hideScrollbars = css`
  &::-webkit-scrollbar {
    display: none;
  }

  -ms-overflow-style: none;
  scrollbar-width: none;

Чтобы настроить внешний вид полос прокрутки в соответствии с темой нашего приложения, мы можем использовать тематические полосы прокрутки (themedScrollbars). Они могут быть размещены в глобальных стилях один раз.

import { css } from "styled-components"
import { round } from "./round"
import { getColor } from "../ui/theme/getters"

export const themedScrollbars = css`
  &::-webkit-scrollbar {
    width: 8px;
  }
  &::-webkit-scrollbar-track {
    background-color: transparent;
  }

  &::-webkit-scrollbar-thumb {
    ${round}
    cursor: pointer;
    background-color: ${getColor("mist")};
    :hover {
      background-color: ${getColor("mistExtra")};
    }
  }
`

interactive, round - Сделать элемент интерактивным и округлым

Последние два фрагмента, которыми я хочу поделиться: interactive, который добавляет указатель курсора и убирает выделение пользователя, чтобы пользователь случайно не выделил часть текста кнопки:

import { css } from "styled-components"

export const interactive = css`
  cursor: pointer;
  user-select: none;
`

Фрагмент round округляет элемент, устанавливая border-radius в произвольно большое число:

import { css } from "styled-components"

export const round = css`
  border-radius: 1000px;
`

На этом пока всё! Благодарим за чтение! В следующих статьях мы рассмотрим полезные абстрактные компоненты React.

Посмотреть на YouTube | GitHub

Источник:

#CSS #React
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу