--- id: wiki-2026-0508-cssom title: CSSOM category: 10_Wiki/Topics status: verified canonical_id: self aliases: [CSS Object Model, "CSSOM(CSS Object Model)"] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [css, dom, browser, frontend, render] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: JavaScript framework: none --- # CSSOM ## 매 한 줄 > **"매 CSS 의 JS-accessible object tree"**. CSSOM (CSS Object Model) 은 browser 가 parsed CSS 의 representation 의 object 의 노출 의 API. DOM 의 sibling 의 매 render tree 의 input. 2026 modern browser 의 매 `getComputedStyle`, CSS Typed OM (Houdini) 의 안정 사용. ## 매 핵심 ### 매 CSSOM 구조 - `document.styleSheets` — `StyleSheetList` - 각 `CSSStyleSheet` → `cssRules` (CSSRule list) - `CSSStyleRule` → `selectorText`, `style` (CSSStyleDeclaration) - `element.style` — inline style 의 declaration - `getComputedStyle(el)` — cascaded + inherited final value ### 매 Render pipeline 의 위치 1. HTML → DOM tree 2. CSS → CSSOM tree 3. **DOM + CSSOM → Render tree** 4. Layout (reflow) → Paint → Composite ### 매 CSSOM 조작 의 cost - `style` 읽기/쓰기: 매 cheap (inline 만) - `getComputedStyle`: 매 expensive (force layout) - `cssRules` 의 mutation: 매 sheet 전체 invalidation ### 매 응용 1. Theme switching (CSS variable 의 JS 조작). 2. Animation (Web Animations API). 3. Style introspection (DevTools, testing). 4. Houdini (CSS Typed OM, Paint Worklet). 5. Stylesheet 의 동적 generation. ## 💻 패턴 ### CSS Variable 의 JS 조작 ```js const root = document.documentElement; root.style.setProperty('--accent', '#0070f3'); // 읽기 const accent = getComputedStyle(root) .getPropertyValue('--accent') .trim(); ``` ### getComputedStyle (final value) ```js const el = document.querySelector('.card'); const styles = getComputedStyle(el); console.log(styles.fontSize); // "16px" console.log(styles.color); // "rgb(17, 17, 17)" console.log(styles.gridTemplateColumns); // resolved tracks ``` ### Inline style 직접 ```js el.style.transform = 'translateX(100px)'; el.style.setProperty('--x', '100px'); ``` ### CSSStyleSheet API (constructable) ```js const sheet = new CSSStyleSheet(); sheet.replaceSync(` .toast { background: #111; color: #fff; padding: 1rem; } `); document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]; ``` ### CSS Typed OM (Houdini) ```js const el = document.querySelector('.box'); el.attributeStyleMap.set('width', CSS.px(200)); const w = el.computedStyleMap().get('width'); console.log(w.value, w.unit); // 200, "px" ``` ### Stylesheet 의 inspection ```js for (const sheet of document.styleSheets) { try { for (const rule of sheet.cssRules) { if (rule.type === CSSRule.STYLE_RULE) { console.log(rule.selectorText, rule.style.cssText); } } } catch (e) { // CORS-blocked external sheet } } ``` ### Web Animations API (CSSOM 기반) ```js el.animate( [{ opacity: 0 }, { opacity: 1 }], { duration: 300, easing: 'ease-out', fill: 'forwards' } ); ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Final computed value 필요 | `getComputedStyle` | | CSS variable toggle | `style.setProperty('--x', ...)` | | Dynamic stylesheet | `CSSStyleSheet` + `adoptedStyleSheets` | | Type-safe value | CSS Typed OM (`CSS.px()`) | | 1회 animation | Web Animations API | | 큰 DOM 의 style read | batch — RAF 의 sync | **기본값**: CSS variable + `setProperty` (가장 cheap + composable). ## 🔗 Graph - 부모: [[DOM]] · [[Browser Rendering]] - 응용: [[Theme Switching]] · [[Web Animations API]] - Adjacent: [[Render Tree]] · [[Critical Rendering Path (CRP)|Critical Rendering Path]] · [[CSS_Architecture_and_Styling|CSS Variables]] ## 🤖 LLM 활용 **언제**: theme system, dynamic styling, JS-driven animation 코드 generation. **언제 X**: 매 declarative CSS 의 sufficient — 매 JS 의 X. ## ❌ 안티패턴 - **Layout thrashing**: read → write → read pattern — 매 batch read first. - **`style.cssText` 의 overwrite**: 기존 style 의 destroy — 매 individual property. - **`!important` 의 JS 의 abuse**: cascade 의 deadlock. - **모든 frame 의 `getComputedStyle`**: layout force — RAF 의 sync. ## 🧪 검증 / 중복 - Verified (W3C CSSOM spec, MDN CSSOM, Houdini). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — CSSOM API + Typed OM + WAAPI |