Skip to main content
Version: 3.5.1

样式和布局

¥Styling and Layout

提示

本节重点介绍通过样式表设置样式。有关更高级的自定义(DOM 结构、React 代码...),请参阅 调酒指南

¥This section is focused on styling through stylesheets. For more advanced customizations (DOM structure, React code...), refer to the swizzling guide.

Docusaurus 站点是一个单页 React 应用。你可以像设计 React 应用一样设计它。

¥A Docusaurus site is a single-page React application. You can style it the way you style React apps.

有几种可行的方法/框架,具体取决于你的偏好和你尝试构建的网站类型。高度交互且行为更像 Web 应用的网站将受益于将样式与组件共置的更现代的样式方法。当你希望自定义或调整组件时,组件样式也特别有用。

¥There are a few approaches/frameworks which will work, depending on your preferences and the type of website you are trying to build. Websites that are highly interactive and behave more like web apps will benefit from more modern styling approaches that co-locate styles with the components. Component styling can also be particularly useful when you wish to customize or swizzle a component.

全局样式

¥Global styles

这是大多数开发者(包括非前端开发者)熟悉的最传统的样式方式。它适用于没有太多自定义功能的小型网站。

¥This is the most traditional way of styling that most developers (including non-front-end developers) would be familiar with. It works fine for small websites that do not have much customization.

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

¥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 都将在全局作用域内可用,并且可以使用字符串字面量直接引用。

¥Any CSS you write within that file will be available globally and can be referenced directly using string literals.

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

如果你想将 CSS 添加到任何元素,你可以在浏览器中打开 DevTools 以检查其类名称。类名有几种:

¥If you want to add CSS to any element, you can open the DevTools in your browser to inspect its class names. Class names come in several kinds:

  • 主题类名称。这些类名在 下一小节 中详尽列出。它们没有任何默认属性。你应该始终优先考虑在自定义 CSS 中定位那些稳定的类名称。

    ¥Theme class names. These class names are listed exhaustively in the next subsection. They don't have any default properties. You should always prioritize targeting those stable class names in your custom CSS.

  • Infima 类名。这些类名可以在经典主题中找到,通常遵循 BEM 惯例block__element--modifier。它们通常是稳定的,但仍被视为实现细节,因此你通常应该避免将它们作为目标。但是,你可以 修改 Infima CSS 变量

    ¥Infima class names. These class names are found in the classic theme and usually follow the BEM convention of block__element--modifier. They are usually stable but are still considered implementation details, so you should generally avoid targeting them. However, you can modify Infima CSS variables.

  • CSS 模块类名称。这些类名在生产中具有哈希值 (codeBlockContainer_RIuc),并且在开发中附加有长文件路径。它们被视为实现细节,你几乎应该始终避免在自定义 CSS 中定位它们。如果必须,你可以使用忽略哈希值的 属性选择器 ([class*='codeBlockContainer'])。

    ¥CSS module class names. These class names have a hash in production (codeBlockContainer_RIuc) and are appended with a long file path in development. They are considered implementation details and you should almost always avoid targeting them in your custom CSS. If you must, you can use an attribute selector ([class*='codeBlockContainer']) that ignores the hash.

主题类名称

¥Theme Class Names

我们提供了一些稳定的 CSS 类名称,以实现健壮且可维护的全局布局样式。这些名称与主题无关,旨在由自定义 CSS 定位。

¥We provide some stable CSS class names for robust and maintainable global layout styling. These names are theme-agnostic and meant to be targeted by custom 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;

使用 Infima 设计你的网站

¥Styling your site with Infima

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

¥@docusaurus/preset-classic uses Infima as the underlying styling framework. Infima provides a flexible layout and common UI components styling suitable for content-centric websites (blogs, documentation, landing pages). For more details, check out the Infima website.

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

¥When you scaffold your Docusaurus project with create-docusaurus, the website will be generated with basic Infima stylesheets and default styling. You can override Infima CSS variables globally.

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

Infima 每种颜色使用 7 种色调。我们建议使用 ColorBox 来查找适合你选择的原色的不同深浅的颜色。

¥Infima uses 7 shades of each color. We recommend using ColorBox to find the different shades of colors for your chosen primary color.

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

¥Alternatively, use the following tool to generate the different shades for your website and copy the variables into /src/css/custom.css.

tip

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

夜间模式

¥Dark Mode

在光照模式下,<html> 元素具有 data-theme="light" 属性;在黑夜间模式下,它是 data-theme="dark"。因此,你可以通过使用特定属性定位 html,将 CSS 范围限定为仅夜间模式。

¥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.

/* Overriding root Infima variables */
[data-theme='dark'] {
--ifm-color-primary: #4e89e8;
}
/* Styling one class specially in dark mode */
[data-theme='dark'] .purple-text {
color: plum;
}
提示

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

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

示例:

¥Examples:

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

数据属性

¥Data Attributes

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

¥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 在另一个网站上嵌入一些 Docusaurus 页面,那么创建替代显示模式并使用 iframe url(例如 https://mysite.com/docs/myDoc?docusaurus-data-mode=iframe)可能会很有用。你有责任提供附加样式并决定要保留或隐藏哪些 UI 元素。

¥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.

移动端视图

¥Mobile View

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

¥Docusaurus uses 996px as the cutoff between mobile screen width and desktop. If you want your layout to be different in the mobile view, you can use media queries.

.banner {
padding: 4rem;
}
/** In mobile view, reduce the padding */
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
自定义断点

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

¥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 modules

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

¥To style your components using CSS Modules, name your stylesheet files with the .module.css suffix (e.g. welcome.module.css). Webpack will load such CSS files as CSS modules and you have to reference the class names as properties of the imported CSS module (as opposed to using plain strings). 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 处理为全局唯一的类名。

¥The class names will be processed by webpack into a globally unique class name during build.

JS 中的 CSS

¥CSS-in-JS

警告

CSS-in-JS 支持正在进行中,因此像 MUI 这样的库可能有显示怪癖。欢迎 PR

¥CSS-in-JS support is a work in progress, so libs like MUI may have display quirks. Welcoming PRs.

Sass/SCSS

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

¥To use Sass/SCSS as your CSS preprocessor, install the unofficial Docusaurus plugin docusaurus-plugin-sass. This plugin works for both global styles and the CSS modules approach:

  1. 安装 docusaurus-plugin-sass

    ¥Install docusaurus-plugin-sass:

npm install --save docusaurus-plugin-sass sass
  1. 将该插件包含在你的 docusaurus.config.js 文件中:

    ¥Include the plugin in your docusaurus.config.js file:

docusaurus.config.js
export default {
// ...
plugins: ['docusaurus-plugin-sass'],
// ...
};
  1. 像平常一样在 Sass/SCSS 中编写和导入样式表。

    ¥Write and import your stylesheets in Sass/SCSS as normal.

使用 Sass/SCSS 的全局样式

¥Global styles using Sass/SCSS

你现在可以将 @docusaurus/preset-classiccustomCss 属性设置为指向你的 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'],
},
// ...
},
],
],
};

使用 Sass/SCSS 的模块

¥Modules using Sass/SCSS

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

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

¥TypeScript support

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

¥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"]
}
}