Appearance
第9章:样式解决方案
9.1 基础样式写法(全局 CSS、组件内 CSS)
全局 CSS
在 Next.js 中,可以在 app/globals.css 文件中定义全局样式。
示例:
css
/* app/globals.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f5f5f5;
}
a {
color: #0070f3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
}
.btn-primary {
background-color: #0070f3;
color: white;
}
.btn-secondary {
background-color: #6c757d;
color: white;
}使用:
jsx
// app/layout.js
import './globals.css';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
// app/page.js
export default function Home() {
return (
<div className="container">
<h1>Home Page</h1>
<p>Welcome to my Next.js app!</p>
<button className="btn btn-primary">Primary Button</button>
<button className="btn btn-secondary">Secondary Button</button>
</div>
);
}组件内 CSS
可以在组件文件中直接使用 <style> 标签定义组件内样式。
示例:
jsx
// app/components/Button.jsx
export default function Button({ children, variant = 'primary' }) {
return (
<>
<button className={`btn btn-${variant}`}>
{children}
</button>
<style jsx>{`
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
}
.btn-primary {
background-color: #0070f3;
color: white;
}
.btn-secondary {
background-color: #6c757d;
color: white;
}
`}</style>
</>
);
}9.2 CSS 模块化(.module.css,避免样式冲突,实战必备)
CSS 模块化是 Next.js 推荐的样式解决方案,可以避免样式冲突。
创建 CSS 模块文件
创建 .module.css 文件,如 Button.module.css。
示例:
css
/* components/Button.module.css */
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
}
.primary {
background-color: #0070f3;
color: white;
}
.secondary {
background-color: #6c757d;
color: white;
}
.primary:hover {
background-color: #0056b3;
}
.secondary:hover {
background-color: #5a6268;
}使用 CSS 模块
示例:
jsx
// components/Button.jsx
import styles from './Button.module.css';
export default function Button({ children, variant = 'primary' }) {
return (
<button className={`${styles.btn} ${styles[variant]}`}>
{children}
</button>
);
}
// app/page.js
import Button from '@/components/Button';
export default function Home() {
return (
<div>
<h1>Home Page</h1>
<Button>Primary Button</Button>
<Button variant="secondary">Secondary Button</Button>
</div>
);
}9.3 CSS 预处理器(SCSS、Less 配置与使用)
Next.js 支持 CSS 预处理器,如 SCSS 和 Less。
安装依赖
SCSS:
bash
npm install sassLess:
bash
npm install less使用 SCSS
示例:
scss
/* components/Button.module.scss */
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
&.primary {
background-color: #0070f3;
color: white;
&:hover {
background-color: #0056b3;
}
}
&.secondary {
background-color: #6c757d;
color: white;
&:hover {
background-color: #5a6268;
}
}
}使用:
jsx
// components/Button.jsx
import styles from './Button.module.scss';
export default function Button({ children, variant = 'primary' }) {
return (
<button className={`${styles.btn} ${styles[variant]}`}>
{children}
</button>
);
}使用 Less
示例:
less
/* components/Button.module.less */
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
&.primary {
background-color: #0070f3;
color: white;
&:hover {
background-color: #0056b3;
}
}
&.secondary {
background-color: #6c757d;
color: white;
&:hover {
background-color: #5a6268;
}
}
}使用:
jsx
// components/Button.jsx
import styles from './Button.module.less';
export default function Button({ children, variant = 'primary' }) {
return (
<button className={`${styles.btn} ${styles[variant]}`}>
{children}
</button>
);
}9.4 第三方样式库集成(Tailwind CSS、Ant Design、Material UI)
Tailwind CSS
Tailwind CSS 是一个实用优先的 CSS 框架,可以快速构建现代网站。
安装与配置
bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p配置 tailwind.config.js:
javascript
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}配置 globals.css:
css
/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}使用
jsx
// app/page.js
export default function Home() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-3xl font-bold mb-4">Home Page</h1>
<p className="mb-6">Welcome to my Next.js app!</p>
<button className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
Primary Button
</button>
<button className="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600 ml-2">
Secondary Button
</button>
</div>
);
}Ant Design
Ant Design 是一个企业级 UI 组件库。
安装
bash
npm install antd使用
jsx
// app/components/AntButton.jsx
'use client';
import { Button } from 'antd';
export default function AntButton({ children, type = 'primary' }) {
return <Button type={type}>{children}</Button>;
}
// app/page.js
import AntButton from '@/components/AntButton';
export default function Home() {
return (
<div style={{ padding: '20px' }}>
<h1>Home Page</h1>
<p>Welcome to my Next.js app!</p>
<AntButton>Primary Button</AntButton>
<AntButton type="default" style={{ marginLeft: '8px' }}>Default Button</AntButton>
<AntButton type="dashed" style={{ marginLeft: '8px' }}>Dashed Button</AntButton>
<AntButton type="text" style={{ marginLeft: '8px' }}>Text Button</AntButton>
</div>
);
}Material UI
Material UI 是一个基于 Material Design 的 UI 组件库。
安装
bash
npm install @mui/material @emotion/react @emotion/styled使用
jsx
// app/components/MuiButton.jsx
'use client';
import Button from '@mui/material/Button';
export default function MuiButton({ children, variant = 'contained' }) {
return <Button variant={variant}>{children}</Button>;
}
// app/page.js
import MuiButton from '@/components/MuiButton';
export default function Home() {
return (
<div style={{ padding: '20px' }}>
<h1>Home Page</h1>
<p>Welcome to my Next.js app!</p>
<MuiButton>Contained Button</MuiButton>
<MuiButton variant="outlined" style={{ marginLeft: '8px' }}>Outlined Button</MuiButton>
<MuiButton variant="text" style={{ marginLeft: '8px' }}>Text Button</MuiButton>
</div>
);
}9.5 样式组件(Styled Components 集成 Next.js)
Styled Components 是一个 CSS-in-JS 库,可以在 JavaScript 中编写 CSS。
安装
bash
npm install styled-components配置
创建 babel.config.js:
javascript
module.exports = {
presets: ['next/babel'],
plugins: ['styled-components'],
};使用
jsx
// components/StyledButton.jsx
'use client';
import styled from 'styled-components';
const Button = styled.button`
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
${props => props.variant === 'primary' && `
background-color: #0070f3;
color: white;
&:hover {
background-color: #0056b3;
}
`}
${props => props.variant === 'secondary' && `
background-color: #6c757d;
color: white;
&:hover {
background-color: #5a6268;
}
`}
`;
export default function StyledButton({ children, variant = 'primary' }) {
return <Button variant={variant}>{children}</Button>;
}
// app/page.js
import StyledButton from '@/components/StyledButton';
export default function Home() {
return (
<div style={{ padding: '20px' }}>
<h1>Home Page</h1>
<p>Welcome to my Next.js app!</p>
<StyledButton>Primary Button</StyledButton>
<StyledButton variant="secondary" style={{ marginLeft: '8px' }}>Secondary Button</StyledButton>
</div>
);
}小结
本章介绍了 Next.js 的样式解决方案,包括基础样式、CSS 模块化、CSS 预处理器、第三方样式库集成和样式组件。通过本章的学习,你应该已经掌握了:
- 基础样式写法:全局 CSS 和组件内 CSS
- CSS 模块化:使用
.module.css文件避免样式冲突 - CSS 预处理器:配置和使用 SCSS、Less
- 第三方样式库集成:Tailwind CSS、Ant Design、Material UI
- 样式组件:使用 Styled Components 进行 CSS-in-JS 开发
选择合适的样式解决方案对于构建美观、可维护的 Next.js 应用至关重要。在实际开发中,建议:
- 对于简单项目,使用基础样式或 CSS 模块化
- 对于需要快速开发的项目,使用 Tailwind CSS
- 对于企业级应用,使用 Ant Design 或 Material UI
- 对于需要高度自定义的项目,使用 Styled Components
接下来,我们将学习 Next.js 的 API 路由开发,这是 Next.js 内置的后端能力。
