From 6f1c78bc03ac6ef101a94d58f18bbb4a9d0b6459 Mon Sep 17 00:00:00 2001 From: AWESOMEDEV Date: Thu, 23 Jul 2026 13:35:12 +0900 Subject: [PATCH] =?UTF-8?q?fix(docs):=20=EB=AC=B8=EC=84=9C=20=EB=B7=B0?= =?UTF-8?q?=EC=96=B4=20:root=20=EB=B3=80=EC=88=98=20=EC=86=8C=EC=83=9D=20?= =?UTF-8?q?=E2=80=94=20=ED=95=9C=EA=B8=80=EC=9D=B4=20=EB=B0=B0=EA=B2=BD?= =?UTF-8?q?=EC=97=90=20=EB=AC=BB=ED=9E=88=EB=8D=98=20=EB=AC=B8=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shadow DOM 안엔 :root가 없어 문서가 :root에 정의한 CSS 변수(--ink 등)가 통째로 죽었다. var(--ink) 텍스트가 색을 잃고 배경과 같아짐(안드로이드·아이폰 공통). :root→:host로 변수를 그림자 트리에 심고, 기본 배경·글자색 폴백 추가. --- frontend/src/pages/DocViewerPage.jsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/DocViewerPage.jsx b/frontend/src/pages/DocViewerPage.jsx index 2c0ff03..d42833c 100644 --- a/frontend/src/pages/DocViewerPage.jsx +++ b/frontend/src/pages/DocViewerPage.jsx @@ -92,11 +92,21 @@ export default function DocViewerPage() { // 아니라서). 그러면 문서 CSS의 `body { ... }` 기본 규칙(폰트·배경 등)이 적용될 // 대상이 사라진다. 그래서 본문을 .__docbody div로 감싸고, CSS의 `body` 선택자를 // `.__docbody`로 바꿔치기해 규칙이 그 div에 걸리게 한다. (선택자 시작 위치에서만 치환) - styles = styles.replace(/(^|[}{,])(\s*)body\b/g, '$1$2.__docbody'); + styles = styles + .replace(/(^|[}{,])(\s*)body\b/g, '$1$2.__docbody') + // ⚠️ Shadow DOM 안에는 :root(=document의 html)가 없다. 문서가 :root에 정의한 + // CSS 변수(--ink, --paper …)가 통째로 죽어서, var(--ink)로 칠한 한글 텍스트가 + // 색을 잃고 배경과 같아진다(안드로이드·아이폰 공통). :root를 :host(그림자 뿌리)로 + // 바꿔 변수를 그림자 트리 안에 심는다. data-theme 규칙은 host에 속성이 없어 무시되고 + // OS 설정(prefers-color-scheme)만 따르는데, 최소한 텍스트가 보이는 게 우선이다. + .replace(/:root\b/g, ':host'); const bodyInner = parsed.body.innerHTML; const bodyClass = parsed.body.className; - setShadowHtml(`
${bodyInner}
`); + // 문서가 변수 정의에 실패하더라도 글자가 배경에 묻히지 않도록 기본 배경·글자색을 깐다 + // (문서 자체 규칙이 있으면 구체성으로 그게 이긴다). 라이트 팔레트 기준. + const base = ':host,.__docbody{background:var(--paper,#FAFBFD);color:var(--ink,#101A28);}'; + setShadowHtml(`
${bodyInner}
`); }) .catch(() => { if (!cancelled) setError(true);