跳到主要内容

如何使用 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

next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
sassOptions: {
additionalData: `$var: red;`,
},
}

export default nextConfig

实现

你可以使用 implementation 属性来指定要使用的 Sass 实现。默认情况下,Next.js 使用 sass 包。

next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
sassOptions: {
implementation: 'sass-embedded',
},
}

export default nextConfig

Sass 变量

Next.js 支持从 CSS 模块文件导出的 Sass 变量。

例如,使用导出的 primaryColor Sass 变量:

app/variables.module.scss
$primary-color: #64ff00;

:export {
primaryColor: $primary-color;
}
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>
)
}
pages/index.js
import styles from '../styles/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);
}

然后在你的根布局中导入:

app/layout.tsx
import './globals.scss'

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
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;
}
}
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>
)
}

嵌套和父选择器

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;
}
}
}

函数和混合器

Sass 提供了强大的函数和混合器功能:

app/styles/mixins.scss
// 混合器
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}

@mixin responsive($breakpoint) {
@if $breakpoint == tablet {
@media (min-width: 768px) { @content; }
} @else if $breakpoint == desktop {
@media (min-width: 1024px) { @content; }
} @else if $breakpoint == large {
@media (min-width: 1200px) { @content; }
}
}

@mixin gradient($start-color, $end-color) {
background: linear-gradient(to right, $start-color, $end-color);
}

// 函数
@function calculate-rem($pixels) {
@return ($pixels / 16) * 1rem;
}

使用这些混合器和函数:

app/components/Hero.module.scss
@import '../styles/mixins.scss';

.hero {
@include flex-center;
@include gradient(#667eea, #764ba2);
min-height: 400px;
padding: calculate-rem(40);

.content {
text-align: center;
color: white;

h1 {
font-size: calculate-rem(48);
margin-bottom: calculate-rem(20);

@include responsive(tablet) {
font-size: calculate-rem(64);
}

@include responsive(desktop) {
font-size: calculate-rem(72);
}
}

p {
font-size: calculate-rem(18);
margin-bottom: calculate-rem(30);

@include responsive(tablet) {
font-size: calculate-rem(20);
}
}
}
}

下一步