#107: CSSOM / getComputedStyle — Non-Visual-Layout mit UA-Defaults + Inline-Merge #107
Labels
No labels
bug
docs
feature
housekeeping
html-spec
performance
react-compat
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
glow-all/true-headless-browser#107
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problembeschreibung
getComputedStyle(element)gibt aktuell ein leeres Objekt{}zuruck. Viele Websites und Frameworks lesen berechnete CSS-Eigenschaften aus:getComputedStyle(el).transform,.opacity.display,.position.width,.height.display,.visibility.display !== "none",.visibility !== "hidden"Ohne CSSOM: Framework-Fehler, falsches Layout-Verhalten, kaputtes Sizing.
Architektur-Analyse
Aktueller Stand
Ziel-Architektur — Non-Visual-Optimized
Non-Visual Optimierungen
display: inline,position: static,visibility: visible). Diese werden einmal geladen, nie recalculated.width: auto→0px,height: auto→0px— kein Layout-Reflow notigstyle.setProperty()wird nur das Cache des Elements invalidated.getComputedStyle()aufgerufen wird ODER ein<style>-Tag perinnerHTMLoderappendChildeingefugt wird.offsetWidth,clientWidthetc. bleiben bei den Default-Shim-Werten —getComputedStyle(el).widthgibt aber den CSS-Wert zuruck (nicht den Layout-Wert).background,font,borderetc. werden zu longhands expandiert — aber nur die 20-30 haufig benutzten, nicht alle 600.Root Causes
color: inheritauf Kind-Elementen wird nicht aufgelostel.style.color = "red"setzt nur inline-style, abergetComputedStyleliest nicht von dortLosungsansatze
Option A (empfohlen): Non-Visual CSSOM mit Default-Values + Inline-Override
Kernidee: Ein
CSSStyleDeclaration-ahnliches Objekt, das aus drei Quellen merged: (1) UA-Defaults, (2) inline-style, (3) stylesheet-regeln (optional, lazy). Kein Layout, kein Reflow.Teil 1: CSS-Default-Value-Database
Teil 2: CSSStyleDeclaration (Non-Visual)
Teil 3: getComputedStyle Funktion
Non-Visual-Optimierungen:
pseudoEltwird ignoriert —::before/::aftersind visuell und fur Headless irrelevantwidth: auto→0pxstatt Layout-Reflow — kein Box-Model notwendigheight: auto→0px— kein Font-Metrics notwendigline-height: normal→1.2(geschatzter Wert) — kein Font-Metricsfont-size: medium→16px— kein Font-Matchingbackground-image: ...→none— kein Image-Loadingclip-path: ...→none— kein Path-Geometryel.style.setProperty()odersetAttribute("style", ...)— kein Re-Calc pro ZugriffVorteile:
el.style.color = "red"→getComputedStyle(el).color === "red".display,.position,.opacitykorrektNachteile:
::before/::afterContent nicht verfugbar (fur Headless irrelevant)font-size: largerwird nicht relative aufgelost (nur absolute Werte)Option B: Vollstandiges CSSOM mit Parser + Cascade
CSS parsen, alle Regeln in eine Cascade-Ordnung bringen, Specificity-Berechnung, Inheritance-Resolution, Shorthand-Expansion.
Problem: ~3000 LOC fur CSS-Parser + Selector-Specificity + Cascade + Inheritance-Algorithmus. Der Overhead ist fur Headless nicht gerechtfertigt — Frameworks lesen selten stylesheet-definierte Eigenschaften, sondern meist
display/opacity/transformdie auch via Default funktionieren.Option C: Happy DOMs CSSStyleDeclaration recyceln
Happy DOM hat
window.getComputedStyleundwindow.CSSStyleSheet. Diese wurden installStyleEngine bereits importiert.Problem: Happy DOMs CSSOM erwartet Happy-DOM-Elemente, nicht unsere OwnElement-Instanzen. Ein Mapping ist aufwandig und buganfallig.
Entscheidung: Option A
.display, Vue liest.transform, CSS-in-JS liest.color— alles Werte die via Default + Inline abgedeckt sind..class { color: red !important }bedeutungslos — der Pixel auf dem Bildschirm existiert nicht.Akzeptanzkriterien
getComputedStyle(el).displaygibt "inline" zuruck (UA-Default fur div)getComputedStyle(el).positiongibt "static" zuruckgetComputedStyle(el).colorgibt "rgb(0, 0, 0)" zuruckel.style.display = "none"→getComputedStyle(el).displaygibt "none"el.style.color = "red"→getComputedStyle(el).colorgibt "red"el.style.setProperty("--custom", "10px")→getComputedStyle(el).getPropertyValue("--custom")gibt "10px"getComputedStyle(el, "::before")gibt leeren Style zuruck (kein visuelles ::before)el.style.cssText = "color: blue; font-size: 20px"wird korrekt geparst und ubernommenBetroffene Dateien
src/css/css-defaults.tssrc/css/computed-style.tssrc/css/style-engine.tssrc/dom/node.tsElement.stylesetter trigger Invalidationsrc/dom/style.tssrc/runtime-isolation.tstests/unit/css-computed.test.tsDependencies
Technische Risiken
color,font-*,line-height,visibility,cursor,direction,text-*,list-style-*,quotes). Die Liste muss vollstandig sein, sonst falsches Verhalten. Losung: Spec-konforme Liste aus CSS 2.1 + CSS3.background: redmuss zubackground-color: red,background-image: none, etc. expandiert werden. Losung: Fur Phase 1 nur die 10 haufigsten Shorthands expandieren.--custom: 10pxwird als Property gespeichert, abervar(--custom)in anderen Properties wird nicht aufgelost. Losung:var()wird in Phase 1 als Wert des Falls (z.B. leeren String) behandelt.currentColor: Referenziert den Wert dercolor-Eigenschaft. Losung:currentColorinborder-color,outline-color, etc. wird durch den aktuellencolor-Wert ersetzt.Performance-Impact
Testplan
Unit-Tests (20+)
color: blue→ Childcolor: bluemargin: 10px→ Childmargin: 0pxIntegration-Tests (3+)
✅ Resolved in commit
440573b#106: MutationObserver vollstandig implementiert — MutationRecord, MutationObserver, MutationRegistry mit Mikrotask-Queueing, Node-Hooks fur childList/attributes/characterData
#109: Custom Elements Lifecycle — connectedCallback/disconnectedCallback/attributeChangedCallback, Parser-Integration via _customElementsRegistry, attachShadow in OwnDOM
#105/#107/#108/#110: Bereits implementiert (99 Tests grun)
Tests: 247 pass, 0 fail