Files
unraid-glass/CLAUDE.md
Kaloyan Danchev c4b11fce6b Add project documentation with CSS/DOM lessons learned
CLAUDE.md covers: Unraid sidebar DOM structure, critical CSS pitfalls
(position:fixed override, inline-flex display, backdrop-filter containing
block), icon font mapping, deployment paths, search overlay architecture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:30:04 +02:00

5.8 KiB

Unraid Glass — visionOS Glassmorphism Theme

Project

Custom CSS + JS theme for Unraid 7.2.3 WebGUI. B&W mountain wallpaper with frosted glass cards, collapsible sidebar, dashboard individual glass cards.

Gitea: https://git.xtrm-lab.org/jazzymc/unraid-glass Local: ~/xtrm/unraid-glass/

Files

File Purpose Deploy path (persistent) Deploy path (live)
style.css Main CSS theme /boot/config/plugins/custom.css/style.css /usr/local/emhttp/plugins/custom.css/style.css
sidebar.js Sidebar toggle + search overlay /boot/config/plugins/custom.css/assets/sidebar.js /usr/local/emhttp/plugins/custom.css/assets/sidebar.js

Deployment

Both files must be deployed to TWO paths — persistent (survives reboot) and live (active now):

scp -i ~/.ssh/id_ed25519_unraid -P 422 style.css root@192.168.10.20:/boot/config/plugins/custom.css/style.css
scp -i ~/.ssh/id_ed25519_unraid -P 422 style.css root@192.168.10.20:/usr/local/emhttp/plugins/custom.css/style.css
scp -i ~/.ssh/id_ed25519_unraid -P 422 sidebar.js root@192.168.10.20:/boot/config/plugins/custom.css/assets/sidebar.js
scp -i ~/.ssh/id_ed25519_unraid -P 422 sidebar.js root@192.168.10.20:/usr/local/emhttp/plugins/custom.css/assets/sidebar.js

JS injection is handled by CustomJS_Loader.page on the server (persisted via /boot/config/go).

Unraid Sidebar DOM Structure

#menu (position: fixed — Unraid's default, DO NOT override)
├── #sidebar-logo (injected by sidebar.js — absolute positioned)
├── #sidebar-toggle-btn (injected by sidebar.js — absolute positioned)
└── #nav-block (position: absolute; top:0; bottom:12px; width:100% — Unraid's default)
    ├── .nav-tile (main nav items — block flow)
    │   └── .nav-item > a (display: inline-flex — Unraid's default)
    │       ├── ::before (icon via font-family: docker-icon, fontawesome, unraid)
    │       ├── bare text node (page name, not wrapped in span)
    │       ├── <b> (only on utility items, display: none in our CSS)
    │       └── <span> (only on utility items, display: none in collapsed)
    └── .nav-tile.right (utility nav items)
        └── .nav-item.CLASSNAME.util > a
            ├── ::before (icon code from page Code= property)
            ├── <b class="icon-u-XXX system"> (icon from page Icon= property)
            └── <span>Label</span>

Critical CSS Lessons

DO NOT override position on #menu

Unraid sets position: fixed on #menu. Overriding with position: relative causes the sidebar to collapse and disappear.

DO NOT override display on .nav-item a

Unraid sets display: inline-flex on .Theme--sidebar .nav-item a. Fighting this with display: grid or display: block doesn't reliably work. Instead, work WITH inline-flex:

  • Center inline elements via text-align: center on parent .nav-item
  • Center icon via position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) on ::before

backdrop-filter creates a containing block

backdrop-filter on #menu creates a new containing block for position: fixed descendants. This means position: fixed inside the sidebar is relative to #menu, NOT the viewport. The search popup must be moved to document.body via JS to escape this.

Work WITH #nav-block, don't replace it

Unraid's #nav-block has position: absolute; top: 0; bottom: 12px; width: 100%; overflow-y: scroll. Only override top (to clear logo+toggle space) and padding-left. Don't add flex/grid layout.

Utility items have DOUBLE icons

Utility .nav-item elements have BOTH a ::before pseudo-element (from page Code= property) AND a <b> HTML element (from page Icon= property). Hide <b> with .nav-item a > * { display: none }.

font-size: 0 for hiding bare text nodes

Main nav items have bare text nodes (not wrapped in <span>). CSS display: none can't target text nodes. Use font-size: 0 on the a element, then explicit font-size on ::before.

gap affects invisible flex items

Even with font-size: 0, text nodes are still flex items. With gap: 25px (Unraid default), invisible text creates spacing. Override gap: 0 in collapsed mode.

Icon Fonts on Unraid

Font Family name Used by
Unraid icons unraid icon-u-* classes, utility nav ::before (thicker strokes)
Font Awesome 4 FontAwesome .fa classes, single weight only
Docker icons docker-icon Docker page nav icon
Combined docker-icon, fontawesome, unraid Main nav ::before (set by Unraid CSS)

Utility nav ::before icons use the unraid font which has heavier strokes. We replace them with FontAwesome equivalents for consistent thin appearance.

Utility Button Pages

Class name Title FA4 replacement
gui_search Search \f002
LanguageButton Switch Language \f0ac
LogoutButton Logout \f08b
TerminalButton Terminal \f120
BrowseButton File Manager \f115
FeedbackButton Feedback \f075
InfoButton Info \f05a
LogButton Log \f0f6
HelpButton Help \f059
LockButton Lock/Unlock \f09c (no page Code=, needs manual ::before)

Search Overlay

The dynamix.gui.search plugin uses hover-trigger in sidebar theme. We replace it with:

  • Click-trigger on the search nav-item
  • gui_search() creates #guiSearchBoxSpan inside the sidebar
  • JS moves it to document.body (escapes backdrop-filter containing block)
  • Backdrop overlay with blur
  • Cmd+K / Ctrl+K keyboard shortcut
  • Escape to close

Wallpaper

Place wallpaper at /boot/config/plugins/custom.css/assets/wallpaper.jpg — accessible at /custom/wallpaper.jpg.