refactor: recommend using data-theme without html element selector (#6668)

* refactor: recommend using data-theme without html element selector

* simplify site CSS

* refactor
This commit is contained in:
Joshua Chen 2022-02-14 10:23:42 +08:00 committed by GitHub
parent 4b7bea950f
commit b89d93fab5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 88 additions and 64 deletions

View file

@ -17,7 +17,7 @@
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
html[data-theme='dark'] {
[data-theme='dark'] {
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;
@ -34,6 +34,6 @@ html[data-theme='dark'] {
padding: 0 var(--ifm-pre-padding);
}
html[data-theme='dark'] .docusaurus-highlight-code-line {
[data-theme='dark'] .docusaurus-highlight-code-line {
background-color: rgba(0, 0, 0, 0.3);
}

View file

@ -26,7 +26,7 @@
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
html[data-theme='dark'] {
[data-theme='dark'] {
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;

View file

@ -24,7 +24,7 @@
box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%);
}
html[data-theme='dark'] .cardContainer.cardContainerLink:hover {
[data-theme='dark'] .cardContainer.cardContainerLink:hover {
--ifm-card-background-color: #2d2d2d; /* original, non-hovered color is #242526 */
}

View file

@ -69,12 +69,12 @@
transform: rotate(0);
}
html[dir='rtl'] .expandSidebarButtonIcon {
[dir='rtl'] .expandSidebarButtonIcon {
transform: rotate(180deg);
}
html[data-theme='dark'] .collapsedDocSidebar:hover,
html[data-theme='dark'] .collapsedDocSidebar:focus {
[data-theme='dark'] .collapsedDocSidebar:hover,
[data-theme='dark'] .collapsedDocSidebar:focus {
background-color: var(--collapse-button-bg-color-dark);
}

View file

@ -72,16 +72,16 @@
margin-top: 4px;
}
html[dir='rtl'] .collapseSidebarButtonIcon {
[dir='rtl'] .collapseSidebarButtonIcon {
transform: rotate(0);
}
html[data-theme='dark'] .collapseSidebarButton {
[data-theme='dark'] .collapseSidebarButton {
background-color: var(--collapse-button-bg-color-dark);
}
html[data-theme='dark'] .collapseSidebarButton:hover,
html[data-theme='dark'] .collapseSidebarButton:focus {
[data-theme='dark'] .collapseSidebarButton:hover,
[data-theme='dark'] .collapseSidebarButton:focus {
background-color: var(--ifm-color-emphasis-200);
}
}

View file

@ -9,10 +9,10 @@
display: none;
}
html[data-theme='light'] .themedImage--light {
[data-theme='light'] .themedImage--light {
display: initial;
}
html[data-theme='dark'] .themedImage--dark {
[data-theme='dark'] .themedImage--dark {
display: initial;
}

View file

@ -120,11 +120,11 @@ import DocusaurusSvg from './docusaurus.svg';
```
```css
html[data-theme='light'] .themedDocusaurus [fill='#FFFF50'] {
[data-theme='light'] .themedDocusaurus [fill='#FFFF50'] {
fill: greenyellow;
}
html[data-theme='dark'] .themedDocusaurus [fill='#FFFF50'] {
[data-theme='dark'] .themedDocusaurus [fill='#FFFF50'] {
fill: seagreen;
}
```
@ -173,8 +173,8 @@ GitHub uses its own [image theming approach](https://github.blog/changelog/2021-
To toggle the visibility of an image using the path fragment (for GitHub, it's `#gh-dark-mode-only` and `#gh-light-mode-only`), add the following to your custom CSS (you can also use your own suffix if you don't want to be coupled to GitHub):
```css title="src/css/custom.css"
html[data-theme='light'] img[src$='#gh-dark-mode-only'],
html[data-theme='dark'] img[src$='#gh-light-mode-only'] {
[data-theme='light'] img[src$='#gh-dark-mode-only'],
[data-theme='dark'] img[src$='#gh-light-mode-only'] {
display: none;
}
```

View file

@ -197,7 +197,7 @@ To accomplish this, Docusaurus adds the `docusaurus-highlight-code-line` class t
}
/* If you have a different syntax highlighting theme for dark mode. */
html[data-theme='dark'] .docusaurus-highlight-code-line {
[data-theme='dark'] .docusaurus-highlight-code-line {
/* Color which works with dark mode syntax highlighting theme */
background-color: rgb(100, 100, 100);
}

View file

@ -191,7 +191,7 @@ By default, DocSearch comes with a fine-tuned theme that was designed for access
Still, you can reuse the [Infima CSS variables](styling-layout.md#styling-your-site-with-infima) from Docusaurus to style DocSearch by editing the `/src/css/custom.css` file.
```css title="/src/css/custom.css"
html[data-theme='light'] .DocSearch {
[data-theme='light'] .DocSearch {
/* --docsearch-primary-color: var(--ifm-color-primary); */
/* --docsearch-text-color: var(--ifm-font-color-base); */
--docsearch-muted-color: var(--ifm-color-secondary-darkest);
@ -209,7 +209,7 @@ html[data-theme='light'] .DocSearch {
--docsearch-footer-background: var(--ifm-color-white);
}
html[data-theme='dark'] .DocSearch {
[data-theme='dark'] .DocSearch {
--docsearch-text-color: var(--ifm-font-color-base);
--docsearch-muted-color: var(--ifm-color-secondary-darkest);
--docsearch-container-background: rgba(47, 55, 69, 0.7);

View file

@ -112,11 +112,11 @@ In light mode, the `<html>` element has a `data-theme="light"` attribute; and in
```css
/* Overriding root Infima variables */
html[data-theme='dark'] {
[data-theme='dark'] {
--ifm-color-primary: #4e89e8;
}
/* Styling one class specially in dark mode */
html[data-theme='dark'] .purple-text {
[data-theme='dark'] .purple-text {
color: plum;
}
```

View file

@ -35,7 +35,7 @@
width: 10%;
}
html[data-theme='light'] {
[data-theme='light'] {
--ifm-background-color: #fff;
}
@ -50,7 +50,7 @@ html[data-theme='light'] {
user-select: none;
}
html[data-theme='dark'] .browserWindowAddressBar {
[data-theme='dark'] .browserWindowAddressBar {
color: var(--ifm-color-gray-300);
}

View file

@ -66,9 +66,9 @@ function ColorGenerator(): JSX.Element {
// State changes -> update DOM styles
useEffect(() => {
updateDOMColors({baseColor, background, shades});
updateDOMColors({baseColor, background, shades}, isDarkTheme);
storage.set(JSON.stringify({baseColor, background, shades}));
}, [baseColor, background, shades, storage]);
}, [baseColor, background, shades, storage, isDarkTheme]);
function updateColor(event: React.ChangeEvent<HTMLInputElement>) {
// Only prepend # when there isn't one.
@ -287,7 +287,7 @@ function ColorGenerator(): JSX.Element {
</Translate>
</p>
<CodeBlock className="language-css" title="/src/css/custom.css">
{`${isDarkTheme ? "html[data-theme='dark']" : ':root'} {
{`${isDarkTheme ? "[data-theme='dark']" : ':root'} {
${getAdjustedColors(shades, baseColor)
.sort((a, b) => a.codeOrder - b.codeOrder)
.map((value) => ` ${value.variableName}: ${value.hex.toLowerCase()};`)

View file

@ -12,7 +12,21 @@
*/
--site-primary-hue-saturation: 167 68%;
--site-primary-hue-saturation-light: 167 56%; /* do we really need this extra one? */
--site-color-favorite-background: #f6fdfd;
--site-color-tooltip: #fff;
--site-color-tooltip-background: #353738;
--site-color-svg-icon-favorite: #e9669e;
--site-color-checkbox-checked-bg: hsl(167deg 56% 73% / 25%);
--site-color-feedback-background: #fff;
}
html[data-theme='dark'] {
--site-color-feedback-background: #f0f8ff;
--site-color-favorite-background: #1d1e1e;
--site-color-checkbox-checked-bg: hsl(167deg 56% 73% / 10%);
}
[data-theme='light'] {
--ifm-color-primary: hsl(var(--site-primary-hue-saturation) 30%);
--ifm-color-primary-dark: hsl(var(--site-primary-hue-saturation) 26%);
--ifm-color-primary-darker: hsl(var(--site-primary-hue-saturation) 23%);
@ -25,16 +39,9 @@
--ifm-color-primary-lightest: hsl(
var(--site-primary-hue-saturation-light) 58%
);
--ifm-color-feedback-background: #fff;
--site-color-favorite-background: #f6fdfd;
--site-color-tooltip: #fff;
--site-color-tooltip-background: #353738;
--site-color-svg-icon-favorite: #e9669e;
--site-color-checkbox-checked-bg: hsl(167deg 56% 73% / 25%);
}
html[data-theme='dark'] {
[data-theme='dark'] {
--ifm-color-primary: hsl(var(--site-primary-hue-saturation) 45%);
--ifm-color-primary-dark: hsl(var(--site-primary-hue-saturation) 41%);
--ifm-color-primary-darker: hsl(var(--site-primary-hue-saturation) 38%);
@ -47,9 +54,6 @@ html[data-theme='dark'] {
--ifm-color-primary-lightest: hsl(
var(--site-primary-hue-saturation-light) 73%
);
--site-color-feedback-background: #f0f8ff;
--site-color-favorite-background: #1d1e1e;
--site-color-checkbox-checked-bg: hsl(167deg 56% 73% / 10%);
}
.docusaurus-highlight-code-line {
@ -59,7 +63,7 @@ html[data-theme='dark'] {
padding: 0 var(--ifm-pre-padding);
}
html[data-theme='dark'] .docusaurus-highlight-code-line {
[data-theme='dark'] .docusaurus-highlight-code-line {
background-color: rgb(66 66 66 / 30%);
}
@ -76,7 +80,7 @@ html[data-theme='dark'] .docusaurus-highlight-code-line {
no-repeat;
}
html[data-theme='dark'] .header-github-link::before {
[data-theme='dark'] .header-github-link::before {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}
@ -97,15 +101,15 @@ html[data-theme='dark'] .header-github-link::before {
background-color: var(--ifm-tabs-color-active);
}
html[data-theme='light'] .themedDocusaurus [fill='#FFFF50'] {
[data-theme='light'] .themedDocusaurus [fill='#FFFF50'] {
fill: greenyellow;
}
html[data-theme='dark'] .themedDocusaurus [fill='#FFFF50'] {
[data-theme='dark'] .themedDocusaurus [fill='#FFFF50'] {
fill: seagreen;
}
html[data-theme='light'] .DocSearch {
[data-theme='light'] .DocSearch {
/* --docsearch-primary-color: var(--ifm-color-primary); */
/* --docsearch-text-color: var(--ifm-font-color-base); */
--docsearch-muted-color: var(--ifm-color-emphasis-700);
@ -123,7 +127,7 @@ html[data-theme='light'] .DocSearch {
--docsearch-footer-background: var(--ifm-color-white);
}
html[data-theme='dark'] .DocSearch {
[data-theme='dark'] .DocSearch {
--docsearch-text-color: var(--ifm-font-color-base);
--docsearch-muted-color: var(--ifm-color-secondary-darkest);
--docsearch-container-background: rgb(47 55 69 / 70%);
@ -179,8 +183,8 @@ div[class^='announcementBar_'] {
white-space: nowrap;
}
html[data-theme='light'] img[src$='#gh-dark-mode-only'],
html[data-theme='dark'] img[src$='#gh-light-mode-only'] {
[data-theme='light'] img[src$='#gh-dark-mode-only'],
[data-theme='dark'] img[src$='#gh-light-mode-only'] {
display: none;
}

View file

@ -142,7 +142,7 @@ function Home(): JSX.Element {
return (
<Layout title={tagline} description={description}>
<main>
<div className={styles.hero}>
<div className={styles.hero} data-theme="dark">
<div className={styles.heroInner}>
<h1 className={styles.heroProjectTagline}>
<img
@ -185,7 +185,9 @@ function Home(): JSX.Element {
</div>
</div>
</div>
<div className={clsx(styles.announcement, styles.announcementDark)}>
<div
className={clsx(styles.announcement, styles.announcementDark)}
data-theme="dark">
<div className={styles.announcementInner}>
<Translate
values={{

View file

@ -56,12 +56,12 @@
background-color: var(--ifm-color-secondary-dark);
}
html[data-theme='dark'] .showcaseCardSrcBtn {
[data-theme='dark'] .showcaseCardSrcBtn {
background-color: var(--ifm-color-emphasis-200) !important;
color: inherit;
}
html[data-theme='dark'] .showcaseCardSrcBtn:hover {
[data-theme='dark'] .showcaseCardSrcBtn:hover {
background-color: var(--ifm-color-emphasis-300) !important;
}

View file

@ -39,7 +39,9 @@
.announcementDark {
background-color: #20232a;
color: #fff;
--ifm-link-color: hsl(var(--site-primary-hue-saturation) 45%);
/* Reapply the primary color, because it has been locally overridden as
* the dark theme color */
--ifm-link-color: var(--ifm-color-primary);
}
.announcementInner {
@ -50,8 +52,6 @@
.hero {
background-color: #2b3137;
padding: 48px;
--ifm-color-primary: hsl(var(--site-primary-hue-saturation) 45%);
--ifm-color-primary-dark: hsl(var(--site-primary-hue-saturation) 41%);
}
.heroInner {

View file

@ -39,7 +39,7 @@ export default function Toggle(props: Props): JSX.Element {
: LIGHT_BACKGROUND_COLOR,
shades: COLOR_SHADES,
};
updateDOMColors(colorState);
updateDOMColors(colorState, isDarkMode);
}}
/>
);

View file

@ -95,14 +95,32 @@ export function getAdjustedColors(shades: Shades, baseColor: string) {
}));
}
export function updateDOMColors({
shades,
baseColor,
background,
}: ColorState): void {
const root = document.documentElement;
getAdjustedColors(shades, baseColor).forEach((value) => {
root.style.setProperty(value.variableName, value.hex);
});
root.style.setProperty('--ifm-background-color', background);
export function updateDOMColors(
{shades, baseColor, background}: ColorState,
isDarkTheme: boolean,
): void {
const styleSheet = Array.from(document.styleSheets).find((item) =>
item.href?.match(/styles(?:\.[0-9a-f]+)?\.css/),
)!;
const rules = Array.from(styleSheet.cssRules) as CSSStyleRule[];
// The rule that looks the most like definition for custom theme colors
const ruleToDelete = rules.findIndex(
(rule) =>
rule.selectorText ===
(isDarkTheme ? '[data-theme="dark"]' : '[data-theme="light"]') &&
Array.from(rule.style).includes('--ifm-color-primary') &&
rule.style.length < 10,
);
if (ruleToDelete >= 0) {
styleSheet.deleteRule(ruleToDelete);
}
const overrideStyle = `${
isDarkTheme ? '[data-theme="dark"]' : '[data-theme="light"]'
} {
${getAdjustedColors(shades, baseColor)
.map((value) => ` ${value.variableName}: ${value.hex};`)
.join('\n')}
--ifm-background-color: ${background};
}`;
styleSheet.insertRule(overrideStyle, styleSheet.cssRules.length - 1);
}