Skip to content

Discard invalid color declarations instead of dropping the property (…#1065

Open
StefanoD wants to merge 1 commit into
linebender:mainfrom
StefanoD:fix/issue-914-invalid-color-declaration
Open

Discard invalid color declarations instead of dropping the property (…#1065
StefanoD wants to merge 1 commit into
linebender:mainfrom
StefanoD:fix/issue-914-invalid-color-declaration

Conversation

@StefanoD

Copy link
Copy Markdown

Fixes #914.

Figma exports SVGs with a dual stroke definition: a valid hex fallback
followed by a wide-gamut value, e.g.

style="stroke:#FAFAFA;stroke:color(display-p3 0.9804 0.9804 0.9804);stroke-opacity:1;"

When splitting a style attribute (or applying a CSS rule), the last
declaration for a property always won, regardless of validity. The
unsupported color(display-p3 ...) value overwrote the valid #FAFAFA
one, and since stroke parsing later falls back to "no stroke", the
element was rendered invisibly.

Per CSS error recovery, a declaration with an invalid value must be
discarded so a previously declared valid value (or the presentation
attribute) is kept. This PR validates the color-bearing presentation
properties (fill, stroke, color, flood-color, lighting-color,
stop-color) before inserting them and skips invalid declarations.

Behavior for a single invalid declaration is unchanged (stroke → none,
fill → default/inherited).

Testing

  • Added regression test invalid_style_declaration_falls_back_to_valid_one
    (fails before, passes after).
  • Full usvg test suite passes; cargo build clean with no new clippy warnings.

Generated by Claude

…inebender#914)

Figma exports SVGs with a dual stroke definition: a valid hex fallback
followed by a wide-gamut value, e.g.

    style="stroke:#FAFAFA;stroke:color(display-p3 0.9804 0.9804 0.9804);"

When splitting a `style` attribute (or applying a CSS rule), the last
declaration for a property always won, regardless of validity. The
unsupported `color(display-p3 ...)` value thus overwrote the valid
`#FAFAFA` one, and since stroke parsing later fell back to "no stroke",
the element was rendered invisibly.

Per CSS error recovery, a declaration with an invalid value must be
discarded so a previously declared valid value (or the presentation
attribute) is kept. Validate the color-bearing presentation properties
(`fill`, `stroke`, `color`, `flood-color`, `lighting-color`,
`stop-color`) before inserting them and skip invalid declarations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@StefanoD StefanoD force-pushed the fix/issue-914-invalid-color-declaration branch from 82ea3e6 to 12949e8 Compare June 14, 2026 14:00

@nicoburns nicoburns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concept of discarding invalid declarations so that earlier valid ones take effect seems correct, but this implementation looks like it ends up parsing the declaration twice. Could we make use of Option<T> so that it only needs to be parsed once?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SVG with both hex colored stroke and display-p3 stroke color is rendered with no stroke

2 participants