CSS Modules: начало
В приложении для учёта расходов визуальная часть так же важна, как и логика. Пользователь должен быстро ориентироваться в интерфейсе, видеть чёткую структуру данных, а главное — получать эстетическое удовольствие от работы с приложением.
Мы рассмотрим два способа стилизации:
- CSS Modules — традиционный CSS, но с локальной областью видимости;
- styled-components — современный способ писать стили прямо в компоненте.
Оба подхода подходят для нашего проекта. Главное — выбрать один и использовать его последовательно.
Стилизация с помощью CSS Modules
CSS Modules позволяют писать обычный CSS, но так, чтобы классы применялись только внутри компонента. Это защищает стили от конфликтов и облегчает масштабирование.
Пример: кнопка
Создадим простой компонент кнопки.
Файл src/components/Button.tsx
import React from "react";
import styles from "./Button.module.css";
interface ButtonProps {
label: string;
}
const Button: React.FC<ButtonProps> = ({ label }) => {
return <button className={styles.button}>{label}</button>;
};
export default Button;
Теперь создаём CSS-файл с тем же именем:
Файл src/components/Button.module.css
/* Button.module.css */
.button {
background-color: #007bff;
color: white;
font-size: 16px;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.button:hover {
background-color: #0056b3;
}
Что мы получаем
- Изоляцию:
.buttonне конфликтует с другими.buttonв проекте. - Простоту: привычный синтаксис CSS.
- Удобство поддержки в больших проектах.
Стилизация через styled-components
styled-components — это библиотека, позволяющая писать стили прямо внутри компонента, используя JavaScript/TypeScript. Такой подход особенно удобен, если вы хотите использовать пропсы или тему.
Установка
npm install styled-components
npm install --save-dev @types/styled-components
Пример: та же кнопка
Файл src/components/Button.tsx
import React from "react";
import styled from "styled-components";
interface ButtonProps {
label: string;
}
const StyledButton = styled.button`
background-color: #007bff;
color: white;
font-size: 16px;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
`;
const Button: React.FC<ButtonProps> = ({ label }) => {
return <StyledButton>{label}</StyledButton>;
};
export default Button;
Что получаем:
- Полная связанность логики и стилей.
- Читаемость: стили находятся рядом с компонентом.
- Расширяемость: можно использовать пропсы, условия, темы и анимации.
Динамические стили с пропсами
Давайте расширим компонент: добавим возможность менять цвет кнопки через проп.
Файл src/components/Button.tsx
import React from "react";
import styled from "styled-components";
interface ButtonProps {
label: string;
color?: string;
}
const StyledButton = styled.button<ButtonProps>`
background-color: ${(props) => props.color || "#007bff"};
color: white;
font-size: 16px;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
`;
const Button: React.FC<ButtonProps> = ({ label, color }) => {
return <StyledButton color={color}>{label}</StyledButton>;
};
export default Button;
Теперь можно использовать компонент так:
<Button label="Сохранить" color="#28a745" />
Темизация приложения
Когда проект разрастается, удобно централизованно управлять цветами, шрифтами и отступами. Для этого в styled-components используется ThemeProvider.
Шаг 1. Создаём тему
Файл src/theme.ts
export const theme = {
colors: {
primary: "#007bff",
secondary: "#6c757d",
background: "#f4f4f4",
},
fonts: {
main: "Arial, sans-serif",
},
};
Шаг 2. Подключаем тему
Файл src/App.tsx
import React from "react";
import { ThemeProvider } from "styled-components";
import { theme } from "./theme";
import Button from "./components/Button";
const App: React.FC = () => {
return (
<ThemeProvider theme={theme}>
<div>
<Button label="Добавить транзакцию" />
</div>
</ThemeProvider>
);
};
export default App;
Шаг 3. Используем тему в компонентах
Файл src/components/Button.tsx
import styled from "styled-components";
const StyledButton = styled.button`
background-color: ${(props) => props.theme.colors.primary};
color: white;
font-size: 16px;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: ${(props) => props.theme.colors.secondary};
}
`;
Теперь все компоненты могут использовать цвета и шрифты из общей темы, и вы всегда можете их централизованно изменить.
Расширение типов для темы
Чтобы TypeScript не ругался на props.theme.colors, нужно немного расширить типы:
Файл src/styled.d.ts
import "styled-components";
import { theme } from "./theme";
type Theme = typeof theme;
declare module "styled-components" {
export interface DefaultTheme extends Theme {}
}
Типичные ошибки и рабочие хитрости
- Ошибка:
props.themeundefined Убедитесь, что компонент обёрнут вThemeProvider. - Конфликты стилей в глобальной CSS Используйте CSS Modules или
styled-componentsвместо обычных *.css файлов, чтобы избежать "перетирания" стилей. - Микс стилей Не рекомендуется одновременно использовать CSS Modules и styled-components — выберите один стиль на весь проект для единообразия.
- Неправильная типизация пропсов Убедитесь, что вы явно указываете интерфейсы при использовании пропсов в стилях.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ