On most pages I was able to add support for dark/light mode.
One page has an expandable tree component, and everything I tried failed and most changes made the formatting (text, alignment, etc.) change for the worse. I attempted to modify the code by using ID, class, add a "dark-mode" to the leaves, etc..
When I was successful with dark/light mode, all the text formatting was lost.
Here's the code I managed to get so far:
// Toggle dark/light mode
const toggleModeButton = document.querySelector('.toggle-mode');
toggleModeButton.addEventListener('click', () => {
document.body.classList.toggle('dark-mode');
document.body.classList.toggle('light-mode');
});
body {
background-color: white;
color: SlateGray;
}
.dark-mode {
background-color: black;
color: SlateGray;
}
/* Tree container style */
.tree {
max-width: 100%;
padding: 0;
list-style: none;
background: white;
font-family: 'consolas', monospace;
font-size: 1.5vw;
background-color: white;
color: SlateGray;
margin: 0;
}
.tree ul {
list-style: none;
padding-left: 1em;
}
.tree li {
padding-left: 0.25em;
margin: 0.3em 0;
position: relative;
cursor: pointer;
}
/* Remove emphasis on text selection */
.tree label {
cursor: pointer;
user-select: none;
display: inline-flex;
align-items: center;
}
/* Hide native checkboxes */
.tree input[type="checkbox"] {
position: absolute;
opacity: 0;
left: 0;
top: 0.2em;
width: 1em;
height: 1em;
cursor: pointer;
}
/* Custom triangle toggle icon before label */
.tree input[type="checkbox"]+label::before {
content: '▶';
/* Closed node arrow */
display: inline-block;
width: 1em;
margin-right: 6px;
color: #888;
transition: transform 0.2s ease;
}
/* Rotate the arrow when checkbox checked (expanded) */
.tree input[type="checkbox"]:checked+label::before {
transform: rotate(90deg);
color: #4a90e2;
}
/* Style for leaf nodes (no children) - no arrow */
.tree li.leaf>label::before {
content: '';
margin-right: 1.5em; /*align label text with toggles */
}
/* Hide nested UL by default */
.tree input[type="checkbox"]~ul {
display: none;
}
/* Show nested UL when checkbox checked */
.tree input[type="checkbox"]:checked~ul {
display: block;
}
/* Accessibility: focus highlight */
.tree input[type="checkbox"]:focus+label {
outline: 1px solid #4a90e2;
outline-offset: 2px;
}
<button class="toggle-mode">Toggle Dark/Light Mode</button>
<ul id="treeView" class="tree" role="tree" aria-label="Communications tree view">
<li role="treeitem" aria-expanded="false">
<input type="checkbox" id="item-2">
<label for="item-2">Alpha</label>
<ul role="group">
<li class="leaf" role="treeitem">Analog input, output, value</li>
<li class="leaf" role="treeitem">Binary input, output, value</li>
<li class="leaf" role="treeitem">Loop</li>
<li class="leaf" role="treeitem">Multi state input, Multi state output, Multi state value</li>
<li class="leaf" role="treeitem">Averaging</li>
<li class="leaf" role="treeitem">Life safety point, Life safety zone</li>
<li class="leaf" role="treeitem">Read property</li>
<li class="leaf" role="treeitem">Write property</li>
</ul>
</li>
<li role="treeitem" aria-expanded="false">
<input type="checkbox" id="item-6">
<label for="item-6">Bravo</label>
<ul role="group">
<input type="checkbox" id="item-6-1">
<label for="item-6-1">RTU</label>
<ul>
<li class="leaf" role="treeitem">RS-232</li>
<li class="leaf" role="treeitem">TCP/IP</li>
</ul>
</ul>
<ul role="group">
<input type="hidden" id="item-6-2">
<label for="item-6-2">Some river</label>
</ul>
<ul role="group">
<input type="hidden" id="item-6-3">
<label for="item-6-3">All register types</label>
</ul>
</li>
<li role="treeitem" aria-expanded="false">
<input type="checkbox" id="item-13">
<label for="item-13">Charlie</label>
<ul role="group">
<li class="leaf" role="treeitem">Some devices</li>
<li class="leaf" role="treeitem">All register types</li>
</ul>
</li>
</ul>
Just add the style you want prefixed with the .dark-mode
class:
.dark-mode .tree {
background: black;
}
// Toggle dark/light mode
const toggleModeButton = document.querySelector('.toggle-mode');
toggleModeButton.addEventListener('click', () => {
document.body.classList.toggle('dark-mode');
document.body.classList.toggle('light-mode');
});
body {
background-color: white;
color: SlateGray;
/* text */
}
.dark-mode {
background-color: black;
color: SlateGray;
/* text */
}
/* Tree container style */
.tree {
max-width: 100%;
/* margin: 20px auto;*/
padding: 0;
list-style: none;
background: white;
font-family: 'consolas';
/*, tahoma, arial, helvetica, sans-serif*/
font-size: 1.5vw;
background-color: white;
/* background: white; */
color: SlateGray;
margin: 0;
}
.tree ul {
list-style: none;
/* margin-left: 1em; /* Indentation for nested lists */
padding-left: 1em;
}
.tree li {
padding-left: 0.25em;
margin: 0.3em 0;
position: relative;
cursor: pointer;
}
/* Remove emphasis on text selection */
.tree label {
cursor: pointer;
user-select: none;
display: inline-flex;
align-items: center;
}
/* Hide native checkboxes */
.tree input[type="checkbox"] {
position: absolute;
opacity: 0;
left: 0;
top: 0.2em;
width: 1em;
height: 1em;
cursor: pointer;
}
/* Custom triangle toggle icon before label */
.tree input[type="checkbox"]+label::before {
content: '▶';
/* Closed node arrow */
display: inline-block;
width: 1em;
margin-right: 6px;
color: #888;
transition: transform 0.2s ease;
}
/* Rotate the arrow when checkbox checked (expanded) */
.tree input[type="checkbox"]:checked+label::before {
transform: rotate(90deg);
color: #4a90e2;
}
/* Style for leaf nodes (no children) - no arrow */
.tree li.leaf>label::before {
content: '';
margin-right: 1.5em;
/*align label text with toggles */
}
/* Hide nested UL by default */
.tree input[type="checkbox"]~ul {
display: none;
}
/* Show nested UL when checkbox checked */
.tree input[type="checkbox"]:checked~ul {
display: block;
}
/* Accessibility: focus highlight */
.tree input[type="checkbox"]:focus+label {
outline: 1px solid #4a90e2;
outline-offset: 2px;
}
.dark-mode .tree {
background: black;
}
<button class="toggle-mode">Toggle Dark/Light Mode</button>
<ul id="treeView" class="tree" role="tree" aria-label="Communications tree view">
<!-- -->
<li role="treeitem" aria-expanded="false">
<input type="checkbox" id="item-2">
<label for="item-2">Alpha</label>
<ul role="group">
<li class="leaf" role="treeitem">Analog input, output, value</li>
<li class="leaf" role="treeitem">Binary input, output, value</li>
<li class="leaf" role="treeitem">Loop</li>
<li class="leaf" role="treeitem">Multi state input, Multi state output, Multi state value</li>
<li class="leaf" role="treeitem">Averaging</li>
<li class="leaf" role="treeitem">Life safety point, Life safety zone</li>
<li class="leaf" role="treeitem">Read property</li>
<li class="leaf" role="treeitem">Write property</li>
</ul>
</li> <!-- -->
<!-- -->
<li role="treeitem" aria-expanded="false">
<input type="checkbox" id="item-6">
<label for="item-6">Bravo</label>
<ul role="group">
<input type="checkbox" id="item-6-1">
<label for="item-6-1">RTU</label>
<ul>
<li class="leaf" role="treeitem">RS-232</li>
<li class="leaf" role="treeitem">TCP/IP</li>
</ul>
</ul>
<ul role="group">
<input type="hidden" id="item-6-2">
<label for="item-6-2">Some river</label>
</ul>
<ul role="group">
<input type="hidden" id="item-6-3">
<label for="item-6-3">All register types</label>
</ul>
</li> <!-- -->
<!-- -->
<li role="treeitem" aria-expanded="false">
<input type="checkbox" id="item-13">
<label for="item-13">Charlie</label>
<ul role="group">
<li class="leaf" role="treeitem">Some devices</li>
<li class="leaf" role="treeitem">All register types</li>
</ul>
</li> <!-- -->
</ul>