Files
Zachary D. Rowitsch 366395487c
Some checks failed
ci / fast (linux) (push) Failing after 3m59s
Update acid2 investigation report for F-002 paint order fix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 09:24:50 -05:00

129 lines
9.5 KiB
Markdown

# Investigation: Acid2 Test
**URL**: http://acid2.acidtests.org/
**Last investigated**: 2026-03-03
## Summary
The Acid2 test renders a smiley face using advanced CSS 2.1 features including fixed/absolute positioning, floats, stacking order, attribute selectors, table display, generated content, and CSS parsing edge cases. The intro box renders correctly at the top of the viewport. The face is positioned ~2650px below the viewport top (behind a 100em margin). At the default scroll position, only the intro and fixed-position scalp elements are in the viewport (the scalp is correctly hidden behind the z-index:2 intro box).
The viewport clipping (F-001) is now working correctly — `PushClip rect=(0, 0, 800, 600)` clips the html element to the viewport. However, the CSS paint order within the eyes section (F-002) remains incorrect — blocks, floats, and inlines paint in reverse order, causing `#eyes-c` (block) to cover the eyes PNG from `#eyes-a` (inline). A new issue was found: absolutely positioned elements with auto height don't include floating descendants per §10.6.4, causing missing side borders on the second face line.
## Findings
### F-001: overflow:hidden on html clips to content area instead of viewport
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: Layout
- **Severity**: High
- **Description**: The CSS rule `html { overflow: hidden }` should clip the html element's content to the viewport dimensions (800x600). Previously the PushClip used the full content area dimensions.
- **Evidence**: Display list line 3: `PushClip rect=(0, 0, 800, 600)` — now correctly clips to viewport. Confirmed fixed.
- **Suggested fix**: N/A — fixed in commit `a4cedec`.
### F-002: CSS paint order incorrect per Appendix E (stacking context)
- **Status**: Open
- **Found**: 2026-03-02
- **Category**: Display
- **Severity**: High
- **Description**: The eyes section tests CSS 2.1 Appendix E paint order: block-level descendants paint first (bottom), then floats, then inline-level content (top). The display list still paints them in the wrong order, causing block-level content (#eyes-c) to overwrite the inline content (#eyes-a, including the eyes PNG image). Previously reported as fixed in commit `1ca5068` but the issue persists in the current render.
- **Evidence**: Display list paint order for the eyes area (later items paint ON TOP):
- Line 17: `.eyes` parent red background (correct — bottom layer)
- Lines 18-20: `#eyes-a` inline content (object bg at `img#5`, border, eyes PNG `img#1`) — painted SECOND (should be LAST/top)
- Lines 21-22: `#eyes-b` float (bg image `img#2` with `attachment=Fixed`, border) — painted THIRD (correct relative to block)
- Lines 23-24: `#eyes-c` block (red bg `SolidRect`, yellow left border 24px) — painted LAST/top (should be FIRST after parent)
Correct order per Appendix E step 4/5/7: parent bg → `#eyes-c` (block bg/border) → `#eyes-b` (float bg/border/content) → `#eyes-a` (inline content). Currently `#eyes-c`'s red background paints on top of the eyes PNG, hiding it.
- **Suggested fix**: The display list builder needs to sort children within a stacking context according to Appendix E: step 4 (block-level in-flow backgrounds), step 5 (floats), step 7 (inline-level content). Currently children appear to paint in DOM order regardless of their flow category.
### F-003: background-attachment:fixed may not position correctly
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: CSS Support
- **Severity**: Medium
- **Description**: Several elements use `background-attachment: fixed` with small tiled images that must align precisely to create the eyes (two 2x2 pixel images offset by 1px to form a solid yellow block).
- **Evidence**: Display list confirms `attachment=Fixed` on both eye backgrounds (lines 18 and 21) with correct position offsets.
### F-004: Escaped space in attribute selector may not parse
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: CSS Support
- **Severity**: Medium
- **Description**: The CSS uses `[class=second\ two]` (escaped space in unquoted attribute value). Fixed in commit `9b694fd`.
- **Evidence**: The address.second.two element correctly receives float styling (yellow 48x12 block at layout line 150-154).
### F-005: float:inherit not verified
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: CSS Support
- **Severity**: Medium
- **Description**: The smile section uses `float: inherit` on an `em` element. Implemented via `copy_property_from_parent` for CSS `inherit` keyword.
- **Evidence**: Layout tree shows the em element (node #75) correctly positioned as a float within the smile structure.
### F-006: Negative clearance calculation may be incorrect
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: Layout
- **Severity**: Medium
- **Description**: The `.smile { clear: both }` after the floated `.nose` requires negative clearance per CSS 2.1 §8.3.1.
- **Evidence**: Smile border edge at y=2771.6 equals nose float's bottom margin edge (content 2771.6 + border 12 + margin -12 = 2771.6). Clearance calculation is correct — smile is exactly at the float's margin edge. ✓
### F-007: CSS parsing edge cases
- **Status**: Verified
- **Found**: 2026-03-02
- **Category**: CSS Support
- **Severity**: Medium
- **Description**: The `.parser` rules test several CSS parsing edge cases. All verified correct in previous investigation with tests added.
- **Evidence**: Parser section renders with correct yellow background, 3em height (from `height: 3em` on line 98 overriding `height: 1em` from line 94), and 2em black side borders. Width correctly uses 2em (the `width: 200` on line 99 is correctly rejected as shown in render log).
### F-008: `[class=second two]` without quotes should be invalid selector
- **Status**: Verified
- **Found**: 2026-03-02
- **Category**: CSS Support
- **Severity**: Low
- **Description**: Line 43 `[class=second two] { background: red; }` has an unquoted attribute value with a space. Parser correctly rejects this. Test added.
- **Evidence**: No elements receive the spurious `background: red` from this invalid rule.
### F-009: `* html .parser` star-html hack should not match
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: CSS Support
- **Severity**: Low
- **Description**: Line 95 `* html .parser { background: gray; }` uses the "star-html" hack. In standards-compliant rendering, `* html` never matches.
- **Evidence**: Parser section has yellow background (not gray), confirming the selector doesn't match.
### F-010: display:inline on .chin div may interact with font-size
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: Layout
- **Severity**: Low
- **Description**: The chin uses `display: inline; font: 2px/4px serif` on its inner div. The strut from `.chin { line-height: 1em }` (= 12px) correctly determines the line box height.
- **Evidence**: Layout shows chin height=12px (1em strut), with the inline NBSP fragment at font_size=2px and line-height=4px correctly positioned within the 12px line box. Display list line 39 confirms `font_size=2 font_family=serif`.
### F-011: Generated content (:before/:after) border diamond for nose
- **Status**: Fixed (2026-03-02)
- **Found**: 2026-03-02
- **Category**: Display
- **Severity**: Low
- **Description**: The nose uses `::before` and `::after` pseudo-elements with colored borders to create a diamond shape.
- **Evidence**: Display list lines 28-29 show correct border patterns:
- `::before` (line 28): Border (144, 2747.6, 24, 12) widths=(0 12 12 12) colors=(red, yellow, black, yellow) — downward-pointing arrowhead
- `::after` (line 29): Border (144, 2759.6, 24, 12) widths=(12 12 0 12) colors=(black, yellow, red, yellow) — upward-pointing arrowhead
Together forming the nose diamond with yellow sides and black center points.
### F-012: Abs pos element auto height excludes floating descendants
- **Status**: Open
- **Found**: 2026-03-03
- **Category**: Layout
- **Severity**: Medium
- **Description**: The blockquote.first.one (second line of face) has `position: absolute` and contains a float (address.second.two, 48x12px yellow). Per CSS 2.1 §10.6.4, an absolutely positioned element with auto height must include floating descendants in its height calculation: "if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges." Currently the blockquote's content height is 0, making its 24px side borders (border-style: none solid) invisible.
- **Evidence**: Layout line 144-148: blockquote content=(132, 2687.6, 48.015625, **0**). The address float has content=(132.01563, 2687.6, 48, 12), so float bottom margin edge = 2699.6. Per §10.6.4, blockquote height should be 12px (not 0). Display list line 11: `Border rect=(108, 2687.6, 96.015625, 0)` — side borders have 0 height and are invisible. In the reference, the second face line should show [24px black border][48px yellow][24px black border] as a 12px-tall horizontal bar.
- **Suggested fix**: In the height calculation for absolutely positioned elements with `height: auto`, after computing the initial content height from in-flow children, check if any floating descendants extend beyond the content bottom edge and increase the height accordingly (CSS 2.1 §10.6.4 paragraph 5).
## Stats
| Status | High | Medium | Low | Total |
|--------|------|--------|-----|-------|
| Open | 1 | 1 | 0 | 2 |
| Verified | 0 | 1 | 1 | 2 |
| Fixed | 1 | 4 | 3 | 8 |