样式和布局
本节的重点是通过样式表进行样式化。对于更高级的定制(DOM 结构,React 代码…),请参考swizzling 指南。
Docusaurus 站点是一个单页 React 应用程序。你可以像设计 React 应用一样设计它。
有一些方法/框架可以工作,这取决于你的喜好和你想要建立的网站类型。交互性强、行为更像 web 应用程序的网站将受益于更现代的样式方法,即与组件共同定位样式。当您希望自定义或混合组件时,组件样式也可能特别有用。
全局风格
这是大多数开发人员(包括非前端开发人员)熟悉的最传统的样式方式。它适用于没有太多定制的小网站。
如果你使用@docusaurus/preset-classic
,你可以创建自己的 CSS 文件(例如:/src/css/custom.css
),并将它们作为经典主题的一个选项全局导入。
module.exports = {
// ...
presets: [
[
"@docusaurus/preset-classic",
{
theme: {
customCss: [require.resolve("./src/css/custom.css")],
},
},
],
],
};
您在该文件中编写的任何 CSS 都将在全局可用,并且可以直接使用字符串字面量引用。
.purple-text {
color: rebeccapurple;
}
function MyComponent() {
return (
<main>
<h1 className="purple-text">Purple Heading!</h1>
</main>
);
}
如果你想给任何元素添加 CSS,你可以在浏览器中打开 DevTools 来检查它的类名。类名有几种类型:
- 主题类名称. 这些类名在下一小节中详细列出。它们没有任何默认属性。您应该始终优先考虑自定义 CSS 中那些稳定的类名。
- Infima 类名. 这些类名可以在经典主题中找到,通常遵循
block__element——modifier
的BEM 约定。它们通常是稳定的,但仍然被认为是实现细节,因此通常应该避免以它们为目标。然而,你可以[修改 Infima CSS 变量](# style -your-site-with-infima)。 - CSS 模块类名. 这些类名在生产中有一个散列(
codeBlockContainer_RIuc
),并在开发中附加了一个长文件路径。它们被认为是实现细节,你应该尽量避免在你的自定义 CSS 中将它们作为目标。如果必须,您可以使用属性选择器 ([class*='codeBlockContainer']
)来忽略哈希值。
主题类名称
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.
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',
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: {
},
} as const;
用 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.
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.
:root {
--ifm-color-primary: #25c2a0;
--ifm-code-font-size: 95%;
}
Infima uses 7 shades of each color. 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 变量名 | Hex | 调整 | 对比评级 |
---|---|---|---|
--ifm-color-primary-lightest | #3cad6e | Fail 🔴 | |
--ifm-color-primary-lighter | #359962 | Fail 🔴 | |
--ifm-color-primary-light | #33925d | Fail 🔴 | |
--ifm-color-primary | #2e8555 | 0 | AA 👍 |
--ifm-color-primary-dark | #29784c | AA 👍 | |
--ifm-color-primary-darker | #277148 | AA 👍 | |
--ifm-color-primary-darkest | #205d3b | AAA 🏅 |
将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;
}
黑暗的模式
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;
}
It is possible to initialize the Docusaurus theme directly from a docusaurus-theme
query string parameter.
Examples:
数据属性
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:
html[data-navbar="false"] .navbar {
display: none;
}
html[data-red-border] div#__docusaurus {
border: red solid thick;
}
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 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;
}
}
CSS 模块
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.
.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>
);
}
The class names will be processed by webpack into a globally unique class name during build.
CSS-in-JS
CSS-in-JS support is a work in progress, so libs like MUI may have display quirks. Welcoming PRs.
Sass/SCSS
To use Sass/SCSS as your CSS preprocessor, install the unofficial Docusaurus 2 plugin docusaurus-plugin-sass
. This plugin works for both global styles and the CSS modules approach:
- Install
docusaurus-plugin-sass
:
- npm
- Yarn
- pnpm
npm install --save docusaurus-plugin-sass sass
yarn add docusaurus-plugin-sass sass
pnpm add docusaurus-plugin-sass sass
- Include the plugin in your
docusaurus.config.js
file:
module.exports = {
// ...
plugins: ["docusaurus-plugin-sass"],
// ...
};
- Write and import your stylesheets in Sass/SCSS as normal.
使用 Sass/SCSS 的全局样式
You can now set the customCss
property of @docusaurus/preset-classic
to point to your Sass/SCSS file:
module.exports = {
presets: [
[
"@docusaurus/preset-classic",
{
// ...
theme: {
customCss: [require.resolve("./src/css/custom.scss")],
},
// ...
},
],
],
};
模块使用 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.
.main {
padding: 12px;
article {
color: #ccc;
}
}
import styles from "./styles.module.scss";
function MyComponent() {
return (
<main className={styles.main}>
<article>Lorem Ipsum</article>
</main>
);
}