Skip to content

[css-typed-om] Change CSSKeywordValue's attribute to allow forward-compatible upgrades #735

@tabatkins

Description

@tabatkins

Many properties today accept single keywords. These are well-handled by CSSKeywordValue objects.

Some, tho, are more complex. 'font-synthesis', for example, has the grammar weight || style || small-caps, so you can provide 1-3 keywords. How best to reflect this? Two ways I can see right now:

  1. When the value is a single keyword, reflect as CSSKeywordValue; when two or more, reflect as a specialized object type (currently just the generic CSSStyleValue).
  2. Always reflect as a specialized object type (or, currently, generic CSSStyleValue).

(2) gives authors a consistent way to interact with the value - whichever way the API provides for you to ask "is small-caps in the value?", you can use that no matter what the value is. (1) is less consistent, but allows for more convenient authoring in simple cases.

The problem here is that a property might start as a single keyword, and then later be upgraded to a more complex value. This has happened many times in CSS's history. So backwards-compat might force us into (1) for a particular property, even if we'd have chosen (2) if we were designing the property's reification from scratch. That suggests that, for overall consistency, we should choose (1) for all properties now, so we future changes give a consistent result rather than messy legacy.


So, my suggestion: we should make the common general-purpose types (CSSKeywordValue and CSSNumericValue) have distinct and memorable attributes which aren't likely to conflict with more specialized object types in the future.

That way, when we do upgrade a property to a more complex grammar, we can define that the new specialized object also has a convenience attribute matching the appropriate general-purpose type, reflecting the same as the general-purpose type would as long as the value is simple enough to match.

To be more concrete, we can leave CSSUnitValue how it is, and change CSSKeywordValue to have a .keyword attribute instead. (CSSStringValue, when we add it, would have a .string attribute.) Then the special CSSFontSynthesisValue type would (a) expose a set for the keywords it contains, and (b) also have a nullable .keyword attribute which, when the value it's reifying is just a single keyword, would contain that keyword.

Code that was written assuming that the property only took a single keyword (and thus reified as a CSSKeywordValue) would continue to work, as long as the page continues to only use a single keyword. (If the page starts using the new values, any code assuming the old values would break, so that's not a concern.) This should make upgrading properties much less fraught with back-compat concerns, which is a big win.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions