跳到主要内容
版本:Canary 🚧

样式和布局

提示

本章节侧重于通过样式表实现的样式。 对于更加高级的个性化需求(比如 DOM 结构、React 代码),请参阅 swizzle 教程

Docusaurus 网站是一个 React 单页应用。 你可以像一般的 React 应用一样给你的网站提供样式。

有几种可行的添加样式的手段/框架,取决于你的偏好和你正在搭建的网站的类型。 有些网站是高度可交互的,和 web 应用程序差不多,此时用更现代的样式手法,比如把样式和组件放在一起,会更加有益。 如果你想要定制某个组件或者 swizzle 它,基于组件的样式也会很有用。

全局样式

这是最传统的添加样式的方法,绝大多数开发者(包括非前端开发者)都应该比较熟悉。 对于没有多少个性化的小网站来说,它的效果不错了。

如果你用的是 @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',
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',
admonitionType: (type: string) => `theme-admonition-${type}`,
},
layout: {
},
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-classicInfima 作为底层样式框架。 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

提示

主色调最好至少有 WCAG-AA 对比度,以保证可读性。你可以用 Docusaurus 自己的网站来预览你的配色的效果。深色模式下,你可以换一套配色,因为同一种颜色一般不能在浅色和深色模式下都保持足够的可读性。

CSS 变量名称十六进制值颜色调整值对比度评分
--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 🏅

src/css/custom.css 中的变量替换成这些新变量。

/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;
}
提示

It is possible to initialize the Docusaurus theme directly from a docusaurus-theme query string parameter.

示例:

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

Data Attributes

It is possible to inject <html> data attributes with query string parameters following the docusaurus-data-<key> pattern. This gives you the flexibility to style a page differently based on the query string.

For example, let's render one of our pages with a red border and no navbar:

/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 Mode

If you plan to embed some Docusaurus pages on another site though an iframe, it can be useful to create an alternative display mode and use iframe urls such as https://mysite.com/docs/myDoc?docusaurus-data-mode=iframe. It is your responsibility to provide the additional styles and decide which UI elements you want to keep or hide.

移动设备视图

Docusaurus 使用 996px 作为移动屏幕和桌面设备之间的宽度分割线。 如果你希望你的布局在移动设备上有所不同,你可以用 CSS 媒体查询。

.banner {
padding: 4rem;
}
/** 在移动设备上,缩小 padding */
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
Customizing the breakpoint

Some React components, such as the header and the sidebar, implement different JavaScript logic when in mobile view. If you change the breakpoint value in your custom CSS, you probably also want to update the invocations of the useWindowSize hook by swizzling the components it's used in and passing an explicit option argument.

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}>你好!</h1>
<article className={styles.contents}>Lorem Ipsum</article>
</main>
);
}

构建过程中,类名会被 webpack 处理成全局唯一的。

CSS-in-JS

warning

CSS-in-JS 的支持尚未完工,所以 MUI 一类的库可能会有显示问题。 欢迎贡献代码

Sass/SCSS

To use Sass/SCSS as your CSS preprocessor, install the unofficial Docusaurus plugin 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 support

To enable TypeScript support for Sass/SCSS modules, the TypeScript configuration should be updated to add the docusaurus-plugin-sass type definitions. This can be done in the tsconfig.json file:

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