Стилизация CSS

В настоящее время ваша домашняя страница не имеет никаких стилей. Давайте рассмотрим различные способы стилизации вашего приложения Next.js.

Глобальные стили

Если вы заглянете в папку /app/ui, вы увидите файл под названием global.css. Вы можете использовать этот файл для добавления CSS-правил ко всем маршрутам в вашем приложении — например, правил сброса CSS, глобальных стилей для HTML-элементов, таких как ссылки, и т. д.

Вы можете импортировать global.css в любой компонент вашего приложения, но обычно рекомендуется добавлять его в ваш компонент верхнего уровня. В Next.js это корневой макет (root layout) (подробнее об этом позже).

Добавьте глобальные стили в ваше приложение, перейдя в /app/layout.tsx и импортировав файл global.css:

/app/layout.tsx
import '@/app/ui/global.css';
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

При работающем сервере разработки сохраните изменения и просмотрите их в браузере. Теперь ваша домашняя страница должна выглядеть так:

Стилизованная страница с логотипом 'Acme', описанием и ссылкой для входа.

Но подождите секунду, вы же не добавляли никаких CSS-правил, откуда взялись стили?

Если вы заглянете в global.css, вы заметите несколько директив @tailwind:

/app/ui/global.css
@tailwind base;
@tailwind components;
@tailwind utilities;

Tailwind

Tailwind — это CSS-фреймворк, который ускоряет процесс разработки, позволяя быстро писать утилитарные классы прямо в вашем React-коде.

В Tailwind вы стилизуете элементы, добавляя имена классов. Например, добавление "text-blue-500" сделает текст <h1> синим:

<h1 className="text-blue-500">I'm blue!</h1>

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

Когда вы используете create-next-app для создания нового проекта, Next.js спросит, хотите ли вы использовать Tailwind. Если вы выберете yes, Next.js автоматически установит необходимые пакеты и настроит Tailwind в вашем приложении.

Если вы посмотрите на /app/page.tsx, вы увидите, что в примере используются классы Tailwind.

/app/page.tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
 
export default function Page() {
  return (
    // Это классы Tailwind:
    <main className="flex min-h-screen flex-col p-6">
      <div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
    // ...
  )
}

Не беспокойтесь, если вы впервые используете Tailwind. Чтобы сэкономить время, мы уже стилизовали все компоненты, которые вы будете использовать.

Давайте поиграем с Tailwind! Скопируйте код ниже и вставьте его перед элементом <p> в /app/page.tsx:

/app/page.tsx
<div
  className="relative w-0 h-0 border-l-[15px] border-r-[15px] border-b-[26px] border-l-transparent border-r-transparent border-b-black"
/>

Если вы предпочитаете писать традиционные CSS-правила или держать стили отдельно от JSX, CSS-модули — отличная альтернатива.

CSS-модули

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

Мы продолжим использовать Tailwind в этом курсе, но давайте на мгновение посмотрим, как вы можете достичь тех же результатов из примера выше, используя CSS-модули.

Внутри /app/ui создайте новый файл под названием home.module.css и добавьте следующие CSS-правила:

/app/ui/home.module.css
.shape {
  height: 0;
  width: 0;
  border-bottom: 30px solid black;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
}

Затем в вашем файле /app/page.tsx импортируйте стили и замените имена классов Tailwind в добавленном вами <div> на styles.shape:

/app/page.tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import styles from '@/app/ui/home.module.css';
 
export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className={styles.shape} />
    // ...
  )
}

Сохраните изменения и просмотрите их в браузере. Вы должны увидеть ту же фигуру, что и раньше.

Tailwind и CSS-модули — два наиболее распространенных способа стилизации приложений Next.js. Использование того или иного метода — вопрос предпочтений, вы даже можете использовать оба в одном приложении!

Использование библиотеки clsx для переключения имен классов

Бывают случаи, когда вам может потребоваться условно стилизовать элемент в зависимости от состояния или какого-либо другого условия.

clsx — это библиотека, которая позволяет легко переключать имена классов. Мы рекомендуем ознакомиться с документацией для получения более подробной информации, но вот базовое использование:

  • Предположим, вы хотите создать компонент InvoiceStatus, который принимает status. Статус может быть 'pending' или 'paid'.
  • Если статус 'paid', вы хотите, чтобы цвет был зеленым. Если статус 'pending', вы хотите, чтобы цвет был серым.

Вы можете использовать clsx для условного применения классов, например так:

/app/ui/invoices/status.tsx
import clsx from 'clsx';
 
export default function InvoiceStatus({ status }: { status: string }) {
  return (
    <span
      className={clsx(
        'inline-flex items-center rounded-full px-2 py-1 text-sm',
        {
          'bg-gray-100 text-gray-500': status === 'pending',
          'bg-green-500 text-white': status === 'paid',
        },
      )}
    >
    // ...
)}

Другие решения для стилизации

В дополнение к подходам, которые мы обсудили, вы также можете стилизовать свое приложение Next.js с помощью:

  • Sass, который позволяет импортировать файлы .css и .scss.
  • CSS-in-JS библиотек, таких как styled-jsx, styled-components и emotion.

Ознакомьтесь с документацией по CSS для получения дополнительной информации.