但是现在你的主页没有任何样式。让我们来看看为 Next.js 应用程序添加样式的不同方式。
在本章中…
我们将涵盖以下主题:
- 如何向你的应用程序添加全局
CSS
文件。 - 两种不同的样式方式:
Tailwind
和CSS
模块。 - 如何使用
clsx
工具包有条件地添加类名。
全局样式
如果你查看 /app/ui
文件夹,会看到一个名为 global.css
的文件。你可以使用这个文件为应用程序中的所有路由添加 CSS 规则——例如 CSS 重置规则、HTML 元素的全局样式(如链接)等等。
你可以在应用程序的任何组件中导入 global.css
,但通常将其添加到顶级组件中是个好习惯。在 Next.js 中,这是 根布局
通过导航到 /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> ); }
在开发服务器仍在运行的情况下,保存更改并在浏览器中预览它们。你的主页现在应该看起来像这样:
...等等,你没有添加任何 CSS 规则,这些样式是从哪里来的?
如果你查看 global.css
,你会注意到一些 @tailwind
指令:
/* /app/ui/global.css */ @tailwind base; @tailwind components; @tailwind utilities;
Tailwind
Tailwind 是一个 CSS 框架,通过允许你直接在 TSX 标记中快速编写 实用类,加快开发过程。
在 Tailwind 中,你可以通过添加类名来为元素设置样式。例如,添加 "text-blue-500"
类将使 <h1>
文本变为蓝色:
<h1 className="text-blue-500">I'm blue!</h1>
尽管 CSS 样式在全局范围内共享,但每个类单独应用于每个元素。这意味着如果你添加或删除元素,不必担心维护单独的样式表、样式冲突,或者随着应用程序扩展你的 CSS 包大小增加。
当你使用 create-next-app
启动新项目时,Next.js 会询问你是否要使用 Tailwind。如果选择“是”,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"> // ... )}
:::tip
如果这是你第一次使用 Tailwind
,不用担心
为了节省时间,我们已经为你预先设计了所有将要使用的组件。
:::
让我们来玩玩 Tailwind!复制以下代码并将其粘贴到 /app/page.tsx
中的 <p>
元素上方:
// /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" />
小测验!
使用上面的代码片段时你看到了什么形状?
A. 黄色星星 B. 蓝色三角形 C. 黑色三角形 D. 红色圆形
如果你更喜欢编写传统的 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
文件中导入这些样式,并将你添加的 <div>
中的 Tailwind 类名替换为 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 应用程序添加样式的两种最常见方式。无论你选择哪一种,都是个人偏好问题——你甚至可以在同一个应用程序中同时使用两者!
小测验!
使用 CSS 模块的一个好处是什么?
A. 增加 CSS 类的全局范围,使它们更容易在不同文件中管理。 B. 提供一种使 CSS 类默认限定到组件范围的方法,减少样式冲突的风险。 C. 自动压缩和缩小 CSS 文件以加快页面加载速度。
使用 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', } )} > // ... )}
小测验!
在代码编辑器中搜索 "clsx",哪些组件使用它来有条件地应用类名?
A. status.tsx
和 pagination.tsx
B. table.tsx
和 status.tsx
C. nav-links.tsx
和 table.tsx
其他样式解决方案
除了我们已经讨论的方法,你还可以使用以下方式为你的 Next.js 应用程序添加样式:
- Sass,允许你导入
.css
和.scss
文件。 - CSS-in-JS 库,如 styled-jsx、styled-components 和 emotion。
可参阅 CSS 文档 获取更多信息。