如何使用 Sass
Next.js 在安装包后内置支持与 Sass 集成,支持 .scss
和 .sass
扩展。你可以通过 CSS 模块和 .module.scss
或 .module.sass
扩展使用组件级 Sass。
首先,安装 sass
:
Terminal
npm install --save-dev sass
提示:
Sass 支持两种不同的语法,每种都有自己的扩展。
.scss
扩展要求你使用 SCSS 语法, 而.sass
扩展要求你使用缩进语法("Sass")。如果你不确定选择哪一个,从
.scss
扩展开始,它是 CSS 的超集,不需要你学习 缩进语法("Sass")。
自定义 Sass 选项
如果你想配置 Sass 选项,请在 next.config
中使用 sassOptions
。
- TypeScript
- JavaScript
next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
sassOptions: {
additionalData: `$var: red;`,
},
}
export default nextConfig
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
sassOptions: {
additionalData: `$var: red;`,
},
}
module.exports = nextConfig
实现
你可以使用 implementation
属性来指定要使用的 Sass 实现。默认情况下,Next.js 使用 sass
包。
- TypeScript
- JavaScript
next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
sassOptions: {
implementation: 'sass-embedded',
},
}
export default nextConfig
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
sassOptions: {
implementation: 'sass-embedded',
},
}
module.exports = nextConfig
Sass 变量
Next.js 支持从 CSS 模块文件导出的 Sass 变量。
例如,使用导出的 primaryColor
Sass 变量:
app/variables.module.scss
$primary-color: #64ff00;
:export {
primaryColor: $primary-color;
}
- JavaScript
- TypeScript
app/page.js
// 映射到根 `/` URL
import styles from './variables.module.scss'
export default function Page() {
return (
<div style={{ color: styles.primaryColor }}>
<h1>Hello, Next.js!</h1>
</div>
)
}
app/page.tsx
// 映射到根 `/` URL
import styles from './variables.module.scss'
export default function Page() {
return (
<div style={{ color: styles.primaryColor }}>
<h1>Hello, Next.js!</h1>
</div>
)
}
全局样式
你可以创建全局 Sass 文件来定义全局样式和变量:
app/globals.scss
// 全局变量
$primary-color: #007bff;
$secondary-color: #6c757d;
$font-family: 'Arial', sans-serif;
// 全局样式
body {
font-family: $font-family;
margin: 0;
padding: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 15px;
}
// 混合器
@mixin button-style($bg-color, $text-color) {
background-color: $bg-color;
color: $text-color;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
opacity: 0.8;
}
}
.btn-primary {
@include button-style($primary-color, white);
}
.btn-secondary {
@include button-style($secondary-color, white);
}
然后在你的根布局中导入:
- TypeScript
- JavaScript
app/layout.tsx
import './globals.scss'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
app/layout.js
import './globals.scss'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
组件级样式
你可以使用 CSS 模块创建组件级 Sass 样式:
app/components/Button.module.scss
.button {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s ease;
&.primary {
background-color: #007bff;
color: white;
&:hover {
background-color: #0056b3;
}
}
&.secondary {
background-color: #6c757d;
color: white;
&:hover {
background-color: #545b62;
}
}
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
}
- TypeScript
- JavaScript
app/components/Button.tsx
import styles from './Button.module.scss'
interface ButtonProps {
children: React.ReactNode
variant?: 'primary' | 'secondary'
disabled?: boolean
onClick?: () => void
}
export default function Button({
children,
variant = 'primary',
disabled = false,
onClick
}: ButtonProps) {
const buttonClass = `${styles.button} ${styles[variant]} ${disabled ? styles.disabled : ''}`
return (
<button
className={buttonClass}
disabled={disabled}
onClick={onClick}
>
{children}
</button>
)
}
app/components/Button.js
import styles from './Button.module.scss'
export default function Button({
children,
variant = 'primary',
disabled = false,
onClick
}) {
const buttonClass = `${styles.button} ${styles[variant]} ${disabled ? styles.disabled : ''}`
return (
<button
className={buttonClass}
disabled={disabled}
onClick={onClick}
>
{children}
</button>
)
}
嵌套和父选择器
Sass 的强大功能之一是嵌套和父选择器:
app/components/Card.module.scss
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
// 嵌套选择器
.title {
font-size: 24px;
font-weight: bold;
margin-bottom: 10px;
// 使用父选择器
&:hover {
color: #007bff;
}
}
.content {
line-height: 1.6;
p {
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
}
// 修饰符
&.featured {
border-color: #007bff;
background-color: #f8f9ff;
}
&.compact {
padding: 10px;
.title {
font-size: 18px;
}
}
}