Skip to content

Support dark mode toggle for SVGs and highlight.js #4925

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions examples/darkmode.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="color-scheme" content="light dark">
<title>Replace me with a real title</title>
<script src="../profiles/w3c.js" type="module" class="remove"></script>
<script class="remove">
// All config options at https://respec.org/docs/
var respecConfig = {
specStatus: "ED",
editors: [
{
name: "Your Name",
url: "https://your-site.com",
},
],
github: "speced/respec",
shortName: "respec",
xref: "web-platform",
group: "webapps",
noRecTrack: true,
};
</script>
</head>
<body>
<section id="abstract">
<p>This is required.</p>
</section>
<section id="sotd">
<p>This is required.</p>
</section>
<section class="informative">
<h2>Introduction</h2>
<p>Some informative introductory text.</p>
<aside class="note" title="A useful note">
<p>I'm a note!</p>
</aside>
<figure id="figure1">
<object data="figure1-lightdark.svg" aria-labelledby="figure1-label"></object>
<figcaption id="figure1-label">A figure</figcaption>
</figure>
</section>
<section>
<h2>A section</h2>
<aside class="example">
<p>This is an example.</p>
<pre class="js">
// Automatic syntax highlighting
function someJavaScript(){}
</pre>
</aside>
<section>
<h3>I'm a sub-section</h3>
<p class="issue" data-number="3524">
<!-- Issue can automatically be populated from GitHub -->
</p>
</section>
</section>
<section data-dfn-for="Foo">
<h2>Start your spec!</h2>
<pre class="idl">
[Exposed=Window]
interface Foo {
attribute DOMString bar;
undefined doTheFoo();
};
</pre>
<p>The <dfn>Foo</dfn> interface represents a {{Foo}}.</p>
<p>
The <dfn>doTheFoo()</dfn> method does the foo. Call it by running
{{Foo/doTheFoo()}}.
</p>
<ol class="algorithm">
<li>A |variable:DOMString| can be declared like this.</li>
</ol>
</section>
<section id="conformance">
<p>
This is required for specifications that contain normative material.
</p>
</section>
<section id="index"></section>
</body>
</html>
37 changes: 37 additions & 0 deletions examples/figure1-lightdark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 25 additions & 14 deletions src/styles/highlight.css.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,29 @@ Original One Light Syntax theme from https://github.com/atom/one-light-syntax

const css = String.raw;

// Repeatably used in media rule and selector-based override.
const hljsDarkVars = `
--base: #282c34;
--mono-1: #abb2bf;
--mono-2: #818896;
--mono-3: #5c6370;
--hue-1: #56b6c2;
--hue-2: #61aeee;
--hue-3: #c678dd;
--hue-4: #98c379;
--hue-5: #e06c75;
--hue-5-2: #be5046;
--hue-6: #d19a66;
--hue-6-2: #e6c07b;
`;

// Prettier ignore only to keep code indented from level 0.
// prettier-ignore
export default css`
.hljs {
/* Use light by default, when no dark scheme present, or light scheme is checked. */
.hljs,
head:not(:has(meta[name='color-scheme'][content~='dark'])) + body .hljs,
body:has(input[name='color-scheme'][value='light']:checked) .hljs {
--base: #fafafa;
--mono-1: #383a42;
--mono-2: #686b77;
Expand All @@ -24,23 +43,15 @@ export default css`
--hue-6-2: #9a6a01;
}

/* There's no way to adapt this to "manual" theme toggle yet. */
/* Use dark by default when preferred, or when dark scheme is checked. */
@media (prefers-color-scheme: dark) {
.hljs {
--base: #282c34;
--mono-1: #abb2bf;
--mono-2: #818896;
--mono-3: #5c6370;
--hue-1: #56b6c2;
--hue-2: #61aeee;
--hue-3: #c678dd;
--hue-4: #98c379;
--hue-5: #e06c75;
--hue-5-2: #be5046;
--hue-6: #d19a66;
--hue-6-2: #e6c07b;
${hljsDarkVars}
}
}
body:has(input[name='color-scheme'][value='dark']:checked) .hljs {
${hljsDarkVars}
}

.hljs {
display: block;
Expand Down
13 changes: 13 additions & 0 deletions src/styles/respec.css.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,17 @@ aside.example .marker > a.self-link {
display: none;
}
}

/**
* Control prefers-color-scheme behavior in linked SVGs:
* - use light when no dark scheme present, or light scheme is checked.
* - use dark when dark scheme is checked.
*/
head:not(:has(meta[name='color-scheme'][content~='dark'])) + body,
body:has(input[name='color-scheme'][value='light']:checked) {
color-scheme: light;
}
body:has(input[name='color-scheme'][value='dark']:checked) {
color-scheme: dark;
}
`;