跳到主要内容
版本:3.6.3

样式和布局

提示

本章节侧重于通过样式表实现的样式。 For more advanced customizations (DOM structure, React code...), refer to the swizzling guide.

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

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

Global styles

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

If you're using @docusaurus/preset-classic, you can create your own CSS files (e.g. /src/css/custom.css) and import them globally by passing them as an option of the classic theme.

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">Purple Heading!</h1>
</main>
);
}

如果你想要给某个元素添加 CSS,你可以打开浏览器的开发者工具,然后用审查元素审查它的类名。 有几种类名:

  • Theme class names. These class names are listed exhaustively in the next subsection. 它们没有默认样式。 你永远应该优先选择在 CSS 中引用这些稳定的类名。
  • Infima class names. These class names are found in the classic theme and usually follow the BEM convention of block__element--modifier. 它们通常是稳定的,但仍然被看作实现细节,所以你一般应该避免引用它们。 However, you can modify Infima CSS variables.
  • CSS module class names. These class names end with a hash which may change over time (codeBlockContainer_RIuc). 它们完全是实现细节,你几乎永远不应该在 CSS 里引用它们。 If you must, you can use an attribute selector ([class*='codeBlockContainer']) that ignores the hash.

Theme Class Names

为了让全局样式变得健壮而可维护,我们提供了一些稳定的 CSS 类名。 这些类名与主题无关,目的就是由自定义 CSS 来引用。

提示

If you can't find a way to create a robust CSS selector, please report your customization use-case and we will consider adding new class names.

Exhaustive list of stable class names
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}`,
},
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;

Styling your site with Infima

@docusaurus/preset-classic uses Infima as the underlying styling framework. Infima 提供了灵活的布局,以及常见的 UI 组件样式,适用于以内容为中心的网站(博客、文档、首页)。 For more details, check out the Infima website.

When you scaffold your Docusaurus project with create-docusaurus, the website will be generated with basic Infima stylesheets and default styling. 你可以全局覆盖 Infima CSS 变量。

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

Infima 每种颜色都使用 7 种色度。 We recommend using ColorBox to find the different shades of colors for your chosen primary color.

Alternatively, use the following tool to generate the different shades for your website and copy the variables into /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;
}

Dark Mode

In light mode, the <html> element has a data-theme="light" attribute; in dark mode, it's data-theme="dark". Therefore, you can scope your CSS to dark-mode-only by targeting html with a specific attribute.

/* 覆盖 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. 这给予了你基于查询字符串分别设置页面样式的灵活性。

比方说,让我们渲染一个带红色边框且无导航栏的页面:

/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. 你有责任自己提供额外的样式,决定哪些 UI 元素是你想要保留的,哪些是你想要隐藏的。

Mobile View

Docusaurus uses 996px as the cutoff between mobile screen width and desktop. 如果你希望你的布局在移动设备上有所不同,你可以用 CSS 媒体查询。

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

部分 React 组件,比如页眉和侧边栏,可能在移动设备视图中实现了不同的 JavaScript 逻辑。 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 modules

To style your components using CSS Modules, name your stylesheet files with the .module.css suffix (e.g. welcome.module.css). Webpack 会把这样的 CSS 文件作为 CSS 模块加载,你必须在引用类名时,使用导入的 CSS 模块的属性(而不是使用普通字符串)。 This is similar to the convention used in 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 一类的库可能会有显示问题。 Welcoming PRs.

Sass/SCSS

To use Sass/SCSS as your CSS preprocessor, install the unofficial Docusaurus plugin docusaurus-plugin-sass. 这个插件对于全局样式和 CSS 模块方案都适用。

  1. Install docusaurus-plugin-sass:
npm install --save docusaurus-plugin-sass sass
  1. Include the plugin in your docusaurus.config.js file:
docusaurus.config.js
export default {
// ...
plugins: ['docusaurus-plugin-sass'],
// ...
};
  1. 像平常一样,用 Sass/SCSS 编写样式表并导入。

Global styles using Sass/SCSS

You can now set the customCss property of @docusaurus/preset-classic to point to your Sass/SCSS file:

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

Modules using Sass/SCSS

Name your stylesheet files with the .module.scss suffix (e.g. welcome.module.scss) instead of .css. Webpack will use sass-loader to preprocess your stylesheets and load them as CSS modules.

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 支持

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": "@docusaurus/tsconfig",
"compilerOptions": {
...
+ "types": ["docusaurus-plugin-sass"]
}
}