From c3a8aa994644a9461a70ba6f5972ff984575ffaa Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Mon, 1 Jun 2026 09:40:12 -0400 Subject: [PATCH] External embed: actually force html transparent (CSS + inline) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous fix set documentElement.style.background = 'transparent' but didn't beat the global html, body { background: var(--bg); ... } rule at the top of the stylesheet. --bg is #e8f4f8 (light cyan, reads as near-white), so pixel-art transparent pixels were showing that light cyan through instead of the host page background. Two fixes layered: 1. CSS rule using :has() so html is targeted only when an embed-mode body is its descendant: html:has(body.embed-mode), body.embed-mode { background: transparent !important; } :has() is supported in all current browsers (Chrome 105+, Safari 15.4+, Firefox 121+). The !important flag beats the global var(--bg) declaration. 2. Inline override via style.setProperty('background', 'transparent', 'important') on both documentElement and body at the top of bootEmbedViewer. Inline + !important = highest specificity possible, so this guarantees transparency even on browsers/edge cases where :has() doesn't trigger immediately on dynamic class change. Net effect: from → → #embedRoot → .embedStage → .designObjectFitWrap → renderer's pixel-art box → canvas, every layer is transparent. Host backgrounds (color, image, gradient) now actually show through transparent pixel-art cells. --- src/index.html | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/index.html b/src/index.html index d2985c4..95bfb89 100644 --- a/src/index.html +++ b/src/index.html @@ -585,7 +585,16 @@ host theme (light, dark, branded). Each chip carries its own semi-opaque dark background + blur so it stays readable regardless of what's behind. */ - body.embed-mode { margin: 0; padding: 0; overflow: hidden; background: transparent; } + /* Force transparency from down so embeds can sit over + any host background (color, image, gradient). The global + `html, body { background: var(--bg) }` rule at the top of + this file would otherwise paint the html element white in + embed mode, killing host-show-through. The :has() selector + targets html only when an embed-mode body is its descendant. */ + html:has(body.embed-mode), body.embed-mode { + background: transparent !important; + } + body.embed-mode { margin: 0; padding: 0; overflow: hidden; } body.embed-mode > :not(#embedRoot) { display: none !important; } #embedRoot { position: fixed; inset: 0; @@ -21536,10 +21545,15 @@ // private sources refuse with a placeholder + Open in Artstr. async function bootEmbedViewer(route) { document.body.classList.add('embed-mode'); - // Force the root transparent too — body alone leaves - // the browser's default white element behind, which kills - // host-bg-show-through for transparent pixel art etc. - document.documentElement.style.background = 'transparent'; + // Force the + backgrounds transparent with + // !important so the global `html, body { background: + // var(--bg) }` rule near the top of this file (which would + // otherwise paint the iframe document with the light theme's + // #e8f4f8) doesn't bleed through transparent pixel art. The + // CSS :has()-rule we set covers modern browsers; this inline + // is the belt-and-suspenders for any specificity edge case. + document.documentElement.style.setProperty('background', 'transparent', 'important'); + document.body.style.setProperty('background', 'transparent', 'important'); const root = _ensureEmbedRoot(); _setEmbedStatus(root, 'loading', '⟳ Loading Artstr design…'); const retry = () => bootEmbedViewer(route);