Skip to content

[css-ui] The computed value rules of user-select is problematic. #3344

@emilio

Description

@emilio

(Note: this is somewhat similar to #336)

I've been looking at user-select issues in https://bugzilla.mozilla.org/show_bug.cgi?id=1506547.

The rules for computing the value of user-select as specified in https://drafts.csswg.org/css-ui-4/#propdef-user-select have pretty problematic implications (which is why at least Gecko / Blink / WebKit don't implement it as such):

  • The initial computed value of the property depends on the element. If the element is editable the computed value should be contain, but otherwise it should be text. That is problematic since there's no canonical "initial computed style" anymore.

  • The computed value of a reset property depends on the parent style: This is problematic performance-wise. This is not unsolvable (justify-items has the same issue), but adds a lot of complexity and memory usage. This is worse for user-select since the common behavior is to "inherit" unlike justify-items. But basically this means that two elements that match the same rules no longer have the same computed style for reset properties, which is the invariant that powers some of Gecko's style engine optimizations.

Gecko / Blink / WebKit do all these checks at used-value time, but the initial value is auto. In Gecko the property is not inherited, but in Blink / WebKit it is inherited:

https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/css/css_properties.json5?l=3952&rcl=77578ccb4082ae20a9326d9e673225f1189ebb63
http://webkit.crisal.io/webkit/rev/324bfaa99696312d8e2daefbe60ae2ab0e616daf/Source/WebCore/css/CSSProperties.json#6250

Can we make these checks at used-value time instead, keeping auto as a computed value? You may need to walk the tree up anyway because of user-select: all, so this seems better.

We could implement this efficiently to some extent in Gecko by making it inherited and adding some hacks to set the default value when the parent style is contain and it's not overriden, or something of that sort, but I honestly don't think the complexity is worth it.

So concrete proposal would be:

  • Make user-select a non-inherited property (as it is today), with initial computed and specified value of auto.
  • auto means the following at used-value time:
    • If the element is an editable root, then the value is contain.
    • If there's no ancestor with a non-auto used value, or that auto used value is contain, then text.

Behavior-wise this is identical to the current spec, except auto is a valid computed value, and maybe related to display: contents depending if we choose to use ancestor box or ancestor element in the flat tree.

cc @frivoal @kojiishi @FremyCompany @rniwa

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions