Wikipedia-Appearance_UI
by Jason Park
HTML
<div class="container">
<div class="column-start">
<div class="sticky-pinned-container">
<div class="pinnable-header">Contents</div>
<ul class="toc-contents">
<li class="toc-level-1 toc-list-item">
<a class="toc-link toc-link-active" href="#">
<div class="toc-text">(Top)</div>
</a>
</li>
<li class="toc-level-1 toc-list-item">
<a class="toc-link" href="#Sentence_1">
<div class="toc-text">Sentence 1</div>
</a>
</li>
<li class="toc-level-1 toc-list-item toc-list-item-expanded">
<a class="toc-link" href="#Sentence_2" class="toc-link">
<div class="toc-text">Sentence 2</div>
</a>
<button
aria-controls="toc-Background-sublist"
class="toc-toggle-button"
aria-expanded="true"
>
<span class="vector-icon icon-expand"></span>
</button>
<ul class="toc-contents">
<li class="toc-level-2 toc-list-item">
<a class="toc-link" href="#Sentence_3">
<div class="toc-text">Sentence 3</div>
</a>
</li>
<li class="toc-level-2 toc-list-item">
<a class="toc-link" href="#Sentence_4">
<div class="toc-text">Sentence 4</div>
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
<main class="main">
<div class="content">
<h1>Lorem Ipsum</h1>
<h4>
"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet,
consectetur, adipisci velit..."
</h4>
<h5>
"There is no one who loves pain itself, who seeks after it and wants to
have it, simply because it is pain..."
</h5>
<hr />
<p>
Sollicitudin tristique blandit dictum viverra habitant luctus eleifend
dis. Fringilla tristique tempor hac consectetur pellentesque...
CSS
:root {
--background-color-base: #fff;
--background-color-base-fixed: #fff;
--background-color-interactive: #eaecf0;
--background-color-neutral-subtle: #f8f9fa;
--border-color-base: #a2a9b1;
--border-color-interactive: #72777d;
--border-color-progressive: #36c;
--color-base: #202122;
--color-subtle: #54595d;
--color-progressive: #36c;
--color-progressive--hover: #4b77d6;
--color-visited: #6a60b0;
body {
background-color: var(--background-color-neutral-subtle, #f8f9fa);
color: var(--color-base, #202122);
font-family: sans-serif;
margin: 0;
}
a {
text-decoration: none;
color: var(--color-progressive, #36c);
}
a:hover {
color: var(--color-progressive--hover, #4b77d6);
text-decoration: underline;
}
a:visited {
color: var(--color-visited, #6a60b0);
}
a:visited:hover {
color: var(--color-visited, #6a60b0);
}
p {
margin: 0.5em 0 1em 0;
}
}
.skin-theme-clientpref-night {
--background-color-base: #101418;
--background-color-interactive: #27292d;
--background-color-neutral-subtle: #202122;
--border-color-base: #72777d;
--border-color-interactive: #a2a9b1;
--color-base: #eaecf0;
--color-subtle: #a2a9b1;
--color-progressive: #88a3e8;
--color-progressive--hover: #b0c1f0;
--color-visited: #a799cd;
}
.feature-custom-font-size-clientpref-0 {
--font-size-medium: 0.875rem;
--line-height-medium: 1.5714285;
}
.feature-custom-font-size-clientpref-1 {
--font-size-medium: 1rem;
--line-height-medium: 1.6;
}
.feature-custom-font-size-clientpref-2 {
--font-size-medium: 1.25rem;
--line-height-medium: 1.5;
}
.feature-limited-width-clientpref-0 {
max-width: none !important;
}
.container {
background-color: var(--background-color-base, #fff);
column-gap: 24px;
display: grid;
grid-template-columns: 10rem auto;
grid-template-areas: "columnStart main";
max-width: 50rem;
margin: auto;
padding: 16px;
}
.heading {
display: flow-root;
margin:...
JavaScript
// Set default appearance
document.documentElement.classList.add("feature-custom-font-size-clientpref-1")
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
document.documentElement.classList.add("skin-theme-clientpref-night")
}
document.querySelector(
"#skin-client-pref-feature-custom-font-size-value-1",
).checked = true
document.querySelector(
"#skin-client-pref-feature-limited-width-value-0",
).checked = true
document.querySelector("#skin-client-pref-skin-theme-value-os").checked = true
// Handle TOC click
document.querySelectorAll(".toc-link").forEach((item) => {
item.addEventListener("click", (e) => {
document.querySelectorAll(".toc-link-active").forEach((item) => {
item.classList.remove("toc-link-active")
})
e.target.classList.add("toc-link-active")
})
})
// Handle TOC arrow button
document.querySelector(".toc-toggle-button").addEventListener("click", (e) => {
const currentTarget = e.currentTarget
const parent = currentTarget.parentElement
const isExpanded = currentTarget.getAttribute("aria-expanded") === "true"
currentTarget.setAttribute("aria-expanded", isExpanded ? "false" : "true")
if (isExpanded) {
parent.classList.remove("toc-list-item-expanded")
} else {
parent.classList.add("toc-list-item-expanded")
}
})
// Handle appearance text
for (let i = 0; i < 3; i++) {
document
.querySelector("#skin-client-pref-feature-custom-font-size-value-" + i)
.addEventListener("change", (e) => {
document.documentElement.classList.forEach((value, key, listObj) => {
if (value.startsWith("feature-custom-font-size")) {
document.documentElement.classList.remove(value)
}
})
document.documentElement.classList.add(
"feature-custom-font-size-clientpref-" + i,
)
})
}
// Handle page width
for (let i = 0; i < 2; i++) {
document
.querySelector("#skin-client-pref-feature-limited-width-value-" + i)
.addEventListener("change", (e) => {
...