NextJS学习笔记 - 样式篇
内联 CSS
最基础的添加样式的方式便是使用内联 CSS
CSS 模块
Next.js 内置了对 CSS 模块的支持。使用 CSS 模块,你只需要使用 .module.css作为文件后缀名,然后在你需要的文件中导入,Next.js 就会自动进行处理。
全局样式
全局样式,顾名思义,应用到所有路由的样式,像我们传统写页面 CSS 的时候,都会引入 normalize.css 或者 reset.css等,这种场景就适合使用全局样式。
全局样式可以被导入 app 目录下的任意 layout、page 或者组件中。
外部样式表
你也可以通过导入外部包的方式添加样式,举个例子:
import 'bootstrap/dist/css/bootstrap.css'
不过要注意,该外部包必须是从 npm 包直接导入或者下载完和你的代码放在一起。
如果我想引用外部 CDN CSS 文件呢?就比如https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css 这种文件?
那你可以使用 <link> 标签添加在 Root Layout 中,就像这样:
// app/layout.js
import "./globals.css";
export default function RootLayout({ children }) {
return (
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>{ children }</body>
</html>
);
}
Tailwind CSS
Tailwind CSS 是一个非常知名的 CSS 框架,本质是一个工具集,包含了大量比如 flex、pt-4、text-center、rotate-90等工具类,可以组合使用并直接在 HTML 代码上实现任何 UI 设计。与 Next.js 搭配使用非常顺手。Next.js 官方便是用的 Tailwind CSS。
在使用 create-next-app创建项目的时候,如果你在命令行中选择了使用 Tailwind CSS,则相关配置都会自动生成,可以直接使用。如果没有选择,希望引入 Tailwind CSS,可以参考此步骤。其实 Tailwind CSS 官方也提供了针对各个框架的使用指南
安装
在项目根目录执行以下命令:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
会同时生成 tailwind.config.js和 postcss.config.js文件。
配置 Tailwind
postcss.config.js 不需要修改。在 tailwind.config.js 中添加使用 Tailwind CSS 类名的文件路径:
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
// 嫌麻烦,你也可以直接使用 `src` 目录
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
}
contentTailwind CSS 是按需生成类名的,它需要扫描你项目中用到的类名,然后才会生成对应的 CSS。
比如你写了:<div className="bg-red-500 text-white px-4 py-2">按钮</div>
Tailwind 就会在打包时生成 .bg-red-500、.text-white 等对应的 CSS。
但它要知道你在哪些文件中用了这些类名,这就需要你告诉它扫描哪些路径。
导入样式
添加 Tailwind CSS 指令,将 Tailwind 的样式注入到全局样式中。使用方式如下:
// app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
在根布局(app/layout.tsx),导入 globals.css :
// app/layout.js
import './globals.css'
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
使用类名
然后你就可以在应用里使用 Tailwind 的工具类名:
// app/page.js
export default function Page() {
return <h1 className="text-3xl font-bold underline">Hello, Next.js!</h1>
}
辅助使用
在 VSCode 中使用的时候,可以安装 Tailwind CSS IntelliSense 这个插件,提供自动功能、语法校验、悬停预览等功能。
Tailwind CSS 中的工具类众多,记不清的时候也可以查询这个速查表。
CSS-in-JS
介绍
配置方式
在 Next.js 中配置 CSS-in-JS 的基本原理分为三步:
- 在渲染的时候有一个包含所有 CSS 规则的样式注册表
- 使用
useServerInsertedHTMLhook 在内容被使用前注入样式规则 - 使用包含样式注册表的客户端组件包裹应用
Styled Components
注意使用 styled-components@6 或者更高版本。
首先,创建一个全局注册表:
'use client'
// lib/registry.js
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({ children }) {
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}</>
})
if (typeof window !== 'undefined') return <>{children}</>
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
然后用此包含注册表的组件包裹根组件的 children:
// app/layout.js
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({ children }) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}
然后你就可以在 page.js 中使用:
'use client';
import styled from 'styled-components';
const Container = styled.div`
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1.5rem /* 24px */;
`;
const SkeletonInner = styled.div`
padding: 1rem /* 16px */;
background-color: rgb(24 24 27 / 0.8);
border-radius: 1rem /* 16px */;
`;
const SkeletonImg = styled.div`
height: 3.5rem /* 56px */;
border-radius: 0.5rem /* 8px */;
background-color: rgb(63 63 70 / 1);
`;
const SkeletonBtn = styled.div`
margin-top: 0.75rem /* 12px */;
width: 25%;
height: 0.75rem /* 12px */;
border-radius: 0.5rem /* 8px */;
background-color: rgb(255 0 128 / 1);
`;
const Skeleton = () => (
<SkeletonInner>
<SkeletonImg />
<SkeletonBtn />
</SkeletonInner>
);
export default function Page() {
return (
<div className="space-y-4">
<h1 className="text-xl font-medium text-gray-400/80">
Styled with Styled Components
</h1>
<Container>
<Skeleton />
<Skeleton />
<Skeleton />
</Container>
</div>
);
}
Sass
使用
Sass 作为知名的 CSS 预处理器已无须过多介绍。Next.js 内置了对 Sass 文件的支持,你需要使用 .scss和 .sass作为文件后缀。
你也可以结合 CSS 模块使用组件级别的 Sass, 你需要使用.module.scss或者 .module.sass作为文件后缀。
使用 sass,你需要首先安装 sass:npm install --save-dev sass
自定义配置
如果你希望配置 Sass 编译器,使用 next.config.js 的 sassOptions选项:
// next.config.js
const path = require('path')
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles')],
},
}
Sass 变量
Next.js 支持从 CSS 模块文件导出 Sass 变量。这是一个示例代码:
// app/variables.module.scss
$primary-color: #64ff00;
:export {
primaryColor: $primary-color;
}
// app/page.js
// maps to root `/` URL
import variables from './variables.module.scss'
export default function Page() {
return <h1 style={{ color: variables.primaryColor }}>Hello, Next.js!</h1>
}