-
Notifications
You must be signed in to change notification settings - Fork 708
[css-ui-4] computed value of user-select #336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Since there is no layout involved, it seems more natural to me to do it on the computed value, but I suppose we could do as a used value as well. Let's see what the group thinks |
Using computed value has additional cost to implement at least for Blink, even if it doesn't involve layout, so we prefer used value unless there is strong reasons to use computed values. @dbaron ? |
Not completely sure what is the question here. Is this about the special computing rules under
If it is, I think that making it computed value adds complexity to impl for Gecko as well, especially the rule for editable elements. I hope it could be done either in the UA sheet (so as specified value, no special computation rule), or as used value. |
I don't think it cannot be done in the UA stylesheet, but I don't think there's a big problem in doing it as a used value instead of computed value. The need to lookup the value on parent elements, and to check whether the element it applies to is editable or not remains, so there is some inherent complexity to solve, but if that's more easily dealt with at used value time in both Gecko and Blink, we should probably do it there. |
Dealing things as non-queryable value is always easier than queryable value I suppose :) |
We implemented |
I spoke from general principle, but then read the spec a bit more and wrote a test to understand the situation around this property. This looks like complicated enough that it's hard to make a call just from a general principle.
Were there discussions and resolutions to make this property non-inherited, but do its own inheritance only for |
I don't remember where we discussed this, so finding the minutes will take a while, but yes, I did present this design and explain the justification behind it to the WG when adding it to the spec. Long story short: Yes, I do know that this description is not a perfect match with existing reality, but nothing is, since existing reality is not fully interoperable. This is meant to be a compromise trying to preserve as much as possible interoperability where there is some already, and at the same time to be as sane as possible when we have some room for maneuver. |
Links to previous discussions:
|
Thank you for the pointers. @yoichio, @yosinch, and I discussed on this, it looks like our concern was not explicitly discussed yet in the past, so please allow us to raise. BackgroundFrom the spec, it looks like the intention is to make We compute all properties for all elements, regardless whether a property is used or not. Inheritance is normally computed by sharing a data structure that contains all inherited properties from parents. Since the current spec defines user-select as not-inherited, but computes ProposalWe propose to split values to two separate properties depends on whether we want to inherit or not.
This change will add a new combination, Thoughts? |
Can you clarify if my understanding is correct?
Is that right? I'd need to think deeper about this, but based on this first read (and bikeshedding aside), I think this might work. A couple things we would probably need to tweak, though:
|
@gregwhitworth Since Microsoft has the only implementation of |
Also, note that one other reason for the magic auto-based pseudo inheretiance was to make it possible to preserve a Mozilla behavior: in their implementation, user-select doesn't inherit into absolute positioned children. Mozilla has said that this was a historical accident, and that they're OK with changing that, so I've changed the computed value rules of |
Yes.
Yes.
Yes.
Yes. The latter case is an additional behavior from the current spec.
I'm ok with it, but a question is if author wants to set
correct?
I haven't tested this yet, is it interoperable today, including Blink and WebKit? Is there a test? Assuming yes, again, if you just want to set to a specific value in specific cases, |
BTW, Gecko's implementation of And Gecko doesn't implement |
It is probably not useful to allow editable elements to have |
Gecko does implement By the way, I am basing my conclusions not on doing various queries via the OM, as I don't fully trust the OM to accurately reflect what the browser's internals are. Instead, I am checking the actual behavior. Your test uses getComputedStyle(), and in this case it seems indeed not to match reality. On top of inconsistencies across browsers, this sort of wackyness is also why my spec isn't a 100% match of existing implementations. Instead I tried to preserve the useful observable behavior. |
I think it's ok to allow override when needed in edge cases, such as nested editable host. We should provide the correct default, while allowing authors to override, looks good design to me. BTW, the link to "editable host" is broken in the spec, you probably mean http://w3c.github.io/editing/contentEditable.html#dfn-editing-host correct? Thanks for the info for Gecko, I didn't know it can support properties without exposing to OM. |
The specs have been moved around, and urls and links not preserved 😢. The HTML5 REC has the same issue btw: if you try to follow the links from https://www.w3.org/TR/html5/editing.html#editing-host, you'll end up in the same place. The link you suggest seems to be the correct one in W3C land, but the WHATWG definition is more exhaustive: https://w3c.github.io/editing/execCommand.html#editing-host @johanneswilm, Is the difference between your definition and the WHATWG's intentional? Could you work with the WHATWG to resolve the differences (you don't have the mention about |
Also, I believe the opposite is also true, there are a few properties in gecko which are parsed (and I think exposed to the OM, but I might be wrong about that, or it might only be sometimes), yet do absolutely nothing. A long time ago, it seems that people in charge of the parser thought it would be a good idea to support anything they found in a spec, regardless of whether the teams in charge of the rest of the engine were prepared to do the rest. Thankfully, this hasn't happened in a looong time, but I believe there are a few remains of this. |
Maybe. Does any browser support that behavior though? Browsers that don't have the |
We experimented how feasible the suggestion to create two internal properties, one inherit and one not-inherit, and make It worked ok, but a discussion with style-dev concluded that we prefer not making them internal. So we'd like to back to the discussion if WG is ok to make 3 properties; one inherit, one not inherit, and @frivoal can you update your side? IIUC you're talking to someone for the 3 properties proposal? |
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 The values mean the same as what they currently mean on 'user-select'. Name: user-select-outside ''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.
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 ( 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:
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. |
@kojiishi By the way, a quite note about a comment you made in the google group post you linked to:
This isn't quite right. Historically, user-select was not inherited, nor was it non-inherited. It was unspecified. the Webkit implementation (which Blink shares) is inherited. The Gecko and the IE/Edge implementations are not. This isn't new, and the auto value has existed all along (even though it isn't useful in the webkit/blink side of the world). The "contain" value took advantage of the existence of this auto value, but "auto" wasn't created for it. |
Thanks for the history, and for the correction. Blink and WebKit do not support So may I understand you think it's possible but prefer to keep the current way to express per-value inheritance? Since my comment is from Blink community, it'd probably good to discuss at TPAC where some of them are available. cc @esprehn @shans |
Yeah lets discuss this at TPAC, I really don't want to introduce a new concept to CSS where specific values can control inheritance. user-select doesn't seem like it justifies increasing the complexity of the entire platform. |
Actually, my shorthand/longhand proposal above has different (and worse) behavior in some cases: |
But that's not what the proposal is. There is no inheritance, and there's just a property whose computed value depends on a property of the parent, and that's not a new concept in the platform. |
They do, just with the not terribly useful behavior of always making it compute to
As I said above, there is no actual per value inheritance. Only computed value that depends on the parent. Yes, the result is that in some situations, it kind of does the same as inheritance, and in others, it does not, so explaining the effects by saying "it behaves sort of like inheritance, except that...." sounds fine for teaching purposes, but there is no new concept being introduced, and I'd prefer that we used the precise terminology when discussing the mechanics or the proposal. As for whether it is possible to use the two properties (possibly with the shorthand), I did think so, but I've changed by mind (see #336 (comment)). If you have a contenteditable element (or an element that's editable for other reasons) that's a child of a user-select:none element, in all browsers:
In the dual property approach, the second point would not be true. The spec is written to be compatible with everybody's existing behavior in that respect, and that change would break this. I'd argue this is for the worse, and not web compatible. |
Just to clarify again, I'm ok either way since the impl concern on the performance is gone, thanks to Rossen and your advice on the conf call, but I didn't understand what you wrote and appreciate clarification:
This can be achieved by a UA stylesheet: [contenteditable] {
user-select-inside: text;
user-select-outside: contain;
} no? Is it only our assumption of the above UA stylesheet was different, or did I miss anything? |
Right, I was not assuming anything in the UA stylesheet. You could indeed mostly solve the problem this way, although you'd probably need to add I still find the original proposal cleaner, but since we can make something roughly equivalent with two properties, a shorthand, and some UA stylesheet additions, I suppose I wouldn't object if you can get other browser vendors on board. |
Chrome team discussed on this again and we concluded that the current spec is fine for us, so closing this. Thanks for the investigations and discussions. |
Thank you for the constructive feedback. In the end, even though we decided to keep the current spec as is, I think exploring the various other solutions was worth it. |
Marking as "Closed as Accepted" rather than "Rejected", because #3344, which is basically reopening this issue, was eventually Accepted. |
https://drafts.csswg.org/css-ui-4/#propdef-user-select
In this section, the spec says computed value is determined in a way rather than inheritance.
However, computed value is used for inheritance and user-select is not ineherited:
https://drafts.csswg.org/css-cascade/#value-stages
Is this really computed value, not used value?
The text was updated successfully, but these errors were encountered: