Re: [csswg-drafts] [css-ui-4][user-select] per-value inheritance

I've looked into splitting the current 'user-select' property into 
longhands, to see if it helps with the issue of a non inherited 
property that has one value whose effect depends on the value on the 
parent element (this has been described as quasi-inheritance or 
selective inheritance). So here's the attempt:

'user-select' becomes a shorthand for 'user-select-inside' and 
'user-select-outside' (to be bikesheded).

Name: user-select-inside 
Inherited: yes 
Values: text | none | all 
Initial: text 

The values mean the same as what they currently mean on 'user-select'.

Name: user-select-outside 
Inherited: no 
Values: auto | contain 
Initial: auto 

''contain'' on an element prevents a selection started within that 
element to be extended outside of it.

''user-select-outside:auto'' computes to (or alternatively, behaves 
as) ''user-select-outside: contain'' on editable elements.

''contain'' + ''none'' is the same as ''auto'' + ''none''.r 
''contain'' + ''all'' could either be the same as ''auto'' + ''all'', 
or have subttely different behavior when trying to select from 
outside. These two combination are not particularly problematic to 
handle, but it is doubtfull whether they are of any use.

| user-select | user-select-inside | user-select-outside |
|----|----|----|
| auto | inherit (Gecko / Edge / IE / Spec behavior) <br> text (Chrome
 / Safari behavior) | auto|
| text | text | auto |
| none | none | auto |
| all | all | auto |
|contain | text | contain |

This design can work, but it has two oddities. The first one, which is
 rare but not unique, being that one of the longhands is inherited and
 the other not. The second one, for which I believe there is no 
precendent, is that one value of the shorthand (''auto'') expands to 
the reserved keyword ''inherit'' in one of the longhands.

These longhands could be exposed to authors or possibly kept as 
internal implemenation details.

----

''user-select: auto'' in the Spec / Mozilla / Edge / IE behavior is 
used what is effectively partial inheritance in a non inherited 
property. In the Chrome / Safari behavior, 'user-select' is inherited,
 and ''user-select:auto'' behaves identically to ''user-select: 
text'', and serves no purpose.

If we keep ''contain'' in the same (non inherited) property, ''auto'' 
is necessary to make things work.

If we split ''contain'' into a separate property, ''auto'' serves no 
purpose other than backwards compatibility, with a different behavior 
in Chrome + Safari vs Gecko + Edge + IE. We could consider not 
including ''auto'' in the standard shorthand, an only keeping it in 
the prefixed versions.

If we keep the visible part as a single property, and implement it 
internally as the two longhands described above, we can keep the same 
behavior as if we only had a single property. I do not know whether 
this would be simpler to implement for Blink, due to the peculiar use 
of ''inherit'' as an expantion of ''auto'' on the shorthand. I suspect
 it is, since this would only come into play when ''auto'' is manually
 specified and the rest of the time you can do normal inheritance on 
one property and normal non-inheritance on the other, but that's for 
Google to see. When taking that route, a bit of fudging would be 
needed on getComputedStyle() since it normally returns nothing for 
shorhands, but that shouldn't be hard (`if ($user-select-outside == 
"contain") return "contain" else return $user-select-inside`)

---

I believe that the approach taken in the spec offers a simpler/better 
better author experience than trying to use the longhands (no useless 
combinations such as contain+none, no need to remeber to reset 
'user-select-inside' to ''text'' if you want to set 
'user-select-outside' to ''contain'' and have it do something useful),
 and has more separate implemenations (Gecko + IE/Edge vs Webkit/Blink
 pre-fork).

Moreover, looking at the value on a parent element to determine the 
computed value on a child element is explicitely mentioned in the 
cascading spec as something that can be expected of computed values:

> Note: In general, the computed value resolves the specified value as
 far as possible without laying out the document or performing other 
expensive or hard-to-parallelize operations, such as resolving network
 requests or retrieving values other than from the element and its 
parent. 


All in all, I could live with the two-properties-with-shorthand 
solution if all implementers prefered it, but I don't think it is a 
better solution than the one currently specified, which aligns with 
what IE/Edge and Gecko do.

The hidden longhand approach does seem to work around the difficulties
 you may run into if you were to do a straightforward implementation, 
and I am sure other implementation strategies exist.

I hope we can keep the spec as it is. 

-- 
GitHub Notification of comment by frivoal
Please view or discuss this issue at 
https://github.com/w3c/csswg-drafts/issues/336#issuecomment-246567000 
using your GitHub account

Received on Tuesday, 13 September 2016 03:58:47 UTC