跳到主要内容

样式和布局

提示

本节重点关注通过样式表进行样式设置。对于更高级的自定义(DOM 结构、React 代码...),请参考交换指南

Docusaurus 站点是一个单页 React 应用程序。您可以像样式化 React 应用程序一样对其进行样式设置。

根据您的偏好和要构建的网站类型,有几种方法/框架可供选择。高度交互且更像 Web 应用程序的网站将受益于更现代的样式设置方法,这些方法将样式与组件共同定位。当您希望自定义或交换组件时,组件样式也特别有用。

全局样式

这是大多数开发者(包括非前端开发者)都熟悉的最传统的样式设置方式。对于没有太多自定义的小型网站来说,这种方式很有效。

如果您使用 @docusaurus/preset-classic,可以创建自己的 CSS 文件(例如 /src/css/custom.css),并通过传递经典主题的选项来全局导入它们。

docusaurus.config.js
export default {
// ...
presets: [
[
'@docusaurus/preset-classic',
{
theme: {
customCss: ['./src/css/custom.css'],
},
},
],
],
};

您在该文件中编写的任何 CSS 都将全局可用,并且可以直接使用字符串文字引用。

/src/css/custom.css
.purple-text {
color: rebeccapurple;
}
function MyComponent() {
return (
<main>
<h1 className="purple-text">紫色标题!</h1>
</main>
);
}

如果要为任何元素添加 CSS,可以在浏览器中打开开发者工具检查其类名。类名有几种类型:

  • 主题类名。这些类名在下一个小节中详尽列出。它们没有任何默认属性。您应该始终优先针对这些稳定的类名进行自定义 CSS。
  • Infima 类名。这些类名在经典主题中找到,通常遵循 BEM 约定,格式为 block__element--modifier。它们通常是稳定的,但仍被视为实现细节,因此通常应避免针对它们。但是,您可以修改 Infima CSS 变量
  • CSS 模块类名。这些类名以哈希结尾,可能会随时间变化(codeBlockContainer_RIuc)。它们被视为实现细节,您几乎总是应该避免在自定义 CSS 中针对它们。如果必须使用,可以使用属性选择器[class*='codeBlockContainer'])忽略哈希。

主题类名

我们提供了一些稳定的 CSS 类名,用于强大且可维护的全局布局样式。这些名称与主题无关,旨在通过自定义 CSS 进行定位。

提示

如果您找不到创建稳定 CSS 选择器的方法,请报告您的自定义用例,我们将考虑添加新的类名。

稳定类名的详尽列表
export const ThemeClassNames = {
page: {
blogListPage: 'blog-list-page',
blogPostPage: 'blog-post-page',
blogTagsListPage: 'blog-tags-list-page',
blogTagPostListPage: 'blog-tags-post-list-page',
blogAuthorsListPage: 'blog-authors-list-page',
blogAuthorsPostsPage: 'blog-authors-posts-page',
docsDocPage: 'docs-doc-page',
docsTagsListPage: 'docs-tags-list-page',
docsTagDocListPage: 'docs-tags-doc-list-page',
mdxPage: 'mdx-page',
},
wrapper: {
main: 'main-wrapper',
blogPages: 'blog-wrapper',
docsPages: 'docs-wrapper',
mdxPages: 'mdx-wrapper',
},
common: {
editThisPage: 'theme-edit-this-page',
lastUpdated: 'theme-last-updated',
backToTopButton: 'theme-back-to-top-button',
codeBlock: 'theme-code-block',
admonition: 'theme-admonition',
unlistedBanner: 'theme-unlisted-banner',
draftBanner: 'theme-draft-banner',
admonitionType: (type: string) => `theme-admonition-${type}`,
},
announcementBar: {
container: 'theme-announcement-bar',
},
layout: {
navbar: {
container: 'theme-layout-navbar',
containerLeft: 'theme-layout-navbar-left',
containerRight: 'theme-layout-navbar-right',
mobileSidebar: {
container: 'theme-layout-navbar-sidebar',
panel: 'theme-layout-navbar-sidebar-panel',
},
},
main: {
container: 'theme-layout-main',
},
footer: {
container: 'theme-layout-footer',
column: 'theme-layout-footer-column',
},
},
docs: {
docVersionBanner: 'theme-doc-version-banner',
docVersionBadge: 'theme-doc-version-badge',
docBreadcrumbs: 'theme-doc-breadcrumbs',
docMarkdown: 'theme-doc-markdown',
docTocMobile: 'theme-doc-toc-mobile',
docTocDesktop: 'theme-doc-toc-desktop',
docFooter: 'theme-doc-footer',
docFooterTagsRow: 'theme-doc-footer-tags-row',
docFooterEditMetaRow: 'theme-doc-footer-edit-meta-row',
docSidebarContainer: 'theme-doc-sidebar-container',
docSidebarMenu: 'theme-doc-sidebar-menu',
docSidebarItemCategory: 'theme-doc-sidebar-item-category',
docSidebarItemLink: 'theme-doc-sidebar-item-link',
docSidebarItemCategoryLevel: (level: number) =>
`theme-doc-sidebar-item-category-level-${level}` as const,
docSidebarItemLinkLevel: (level: number) =>
`theme-doc-sidebar-item-link-level-${level}` as const,
},
blog: {
blogFooterTagsRow: 'theme-blog-footer-tags-row',
blogFooterEditMetaRow: 'theme-blog-footer-edit-meta-row',
},
pages: {
pageFooterEditMetaRow: 'theme-pages-footer-edit-meta-row',
},
} as const;

使用 Infima 设置站点样式

@docusaurus/preset-classic 使用 Infima 作为底层样式框架。Infima 提供了灵活的布局和常见的 UI 组件样式,适用于以内容为中心的网站(博客、文档、登陆页面)。有关更多详细信息,请查看 Infima 网站

使用 create-docusaurus 搭建 Docusaurus 项目时,网站将生成基本的 Infima 样式表和默认样式。您可以全局覆盖 Infima CSS 变量。

/src/css/custom.css
:root {
--ifm-color-primary: #25c2a0;
--ifm-code-font-size: 95%;
}

Infima 为每种颜色使用 7 种阴影。我们建议使用 ColorBox 为您选择的主要颜色找到不同的颜色阴影。

或者,使用以下工具为您的网站生成不同的颜色阴影,并将变量复制到 /src/css/custom.css

提示

Aim for at least WCAG-AA contrast ratio for the primary color to ensure readability. Use the Docusaurus website itself to preview how your color palette would look like. You can use alternative palettes in dark mode because one color doesn't usually work in both light and dark mode.

CSS Variable NameHexAdjustmentContrast Rating
--ifm-color-primary-lightest#3cad6eFail 🔴
--ifm-color-primary-lighter#359962Fail 🔴
--ifm-color-primary-light#33925dFail 🔴
--ifm-color-primary#2e85550AA 👍
--ifm-color-primary-dark#29784cAA 👍
--ifm-color-primary-darker#277148AA 👍
--ifm-color-primary-darkest#205d3bAAA 🏅

Replace the variables in src/css/custom.css with these new variables.

/src/css/custom.css
:root {
--ifm-color-primary: #2e8555;
--ifm-color-primary-dark: #29784c;
--ifm-color-primary-darker: #277148;
--ifm-color-primary-darkest: #205d3b;
--ifm-color-primary-light: #33925d;
--ifm-color-primary-lighter: #359962;
--ifm-color-primary-lightest: #3cad6e;
}

深色模式

在浅色模式下,<html> 元素具有 data-theme="light" 属性;在深色模式下,为 data-theme="dark"。因此,您可以通过定位具有特定属性的 html 来将 CSS 作用域限定为仅深色模式。

/* 覆盖根 Infima 变量 */
[data-theme='dark'] {
--ifm-color-primary: #4e89e8;
}
/* 在深色模式下特别设置一个类的样式 */
[data-theme='dark'] .purple-text {
color: plum;
}
提示

可以直接从 docusaurus-theme 查询字符串参数初始化 Docusaurus 主题。

示例:

/docs/?docusaurus-theme=dark
/docs/configuration?docusaurus-theme=light

数据属性

可以使用遵循 docusaurus-data-<key> 模式的查询字符串参数注入 <html> 数据属性。这使您可以根据查询字符串灵活地为页面设置不同的样式。

例如,让我们渲染一个带有红色边框且无导航栏的页面:

/src/css/custom.css
html[data-navbar='false'] .navbar {
display: none;
}

html[data-red-border] div#__docusaurus {
border: red solid thick;
}
/docs/?docusaurus-data-navbar=false&docusaurus-data-red-border
Iframe 模式

如果您计划通过 iframe 在另一个站点上嵌入一些 Docusaurus 页面,创建一个替代显示模式并使用 iframe URL(如 https://mysite.com/docs/myDoc?docusaurus-data-mode=iframe)可能很有用。您有责任提供额外的样式并决定要保留或隐藏哪些 UI 元素。

移动视图

Docusaurus 使用 996px 作为移动屏幕宽度和桌面之间的分界点。如果您希望在移动视图中布局不同,可以使用媒体查询。

.banner {
padding: 4rem;
}
/** 在移动视图中,减少内边距 */
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
自定义断点

某些 React 组件(如标题和侧边栏)在移动视图中实现了不同的 JavaScript 逻辑。如果您在自定义 CSS 中更改断点值,可能还需要通过交换使用 useWindowSize 钩子的组件并传递显式选项参数来更新其调用。

CSS 模块

要使用 CSS 模块 为您的组件设置样式,请将样式表文件命名为 .module.css 后缀(例如 welcome.module.css)。Webpack 将加载这些 CSS 文件作为 CSS 模块,您必须将类名引用为导入的 CSS 模块的属性(而不是使用普通字符串)。这类似于 Create React App 中使用的约定。

styles.module.css
.main {
padding: 12px;
}

.heading {
font-weight: bold;
}

.contents {
color: #ccc;
}
import styles from './styles.module.css';

function MyComponent() {
return (
<main className={styles.main}>
<h1 className={styles.heading}>Hello!</h1>
<article className={styles.contents}>Lorem Ipsum</article>
</main>
);
}

类名将在构建期间由 webpack 处理为全局唯一的类名。

CSS-in-JS

注意

CSS-in-JS 支持仍在进行中,因此像 MUI 这样的库可能会出现显示问题。欢迎提交 PR

Sass/SCSS

要使用 Sass/SCSS 作为 CSS 预处理器,请安装非官方 Docusaurus 插件 docusaurus-plugin-sass。此插件适用于全局样式和 CSS 模块方法:

  1. 安装 docusaurus-plugin-sass
npm install --save docusaurus-plugin-sass sass
  1. docusaurus.config.js 文件中包含插件:
docusaurus.config.js
export default {
// ...
plugins: ['docusaurus-plugin-sass'],
// ...
};
  1. 像往常一样编写和导入您的 Sass/SCSS 样式表。

使用 Sass/SCSS 的全局样式

现在,您可以将 @docusaurus/preset-classiccustomCss 属性设置为指向您的 Sass/SCSS 文件:

docusaurus.config.js
export default {
presets: [
[
'@docusaurus/preset-classic',
{
// ...
theme: {
customCss: ['./src/css/custom.scss'],
},
// ...
},
],
],
};

使用 Sass/SCSS 的模块

将样式表文件命名为 .module.scss 后缀(例如 welcome.module.scss),而不是 .css。Webpack 将使用 sass-loader 预处理您的样式表并将其作为 CSS 模块加载。

styles.module.scss
.main {
padding: 12px;

article {
color: #ccc;
}
}
import styles from './styles.module.scss';

function MyComponent() {
return (
<main className={styles.main}>
<article>Lorem Ipsum</article>
</main>
);
}

TypeScript 支持

要为 Sass/SCSS 模块启用 TypeScript 支持,应在 tsconfig.json 文件中更新 TypeScript 配置以添加 docusaurus-plugin-sass 类型定义:

{
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
...
+ "types": ["docusaurus-plugin-sass"]
}
}