-
Notifications
You must be signed in to change notification settings - Fork 708
[css-logical-1] [css-cascade-3] The all shorthand probably shouldn't set logical properties. #1898
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
The problem of making elem.style.paddingLeft = '10px';
elem.style.paddingInlineStart = '10px';
elem.style.all = 'initial'; people should be expecting that there is no padding anymore. However, if I guess the solution should be having the order defined in the way that, logical properties go before physical ones. This doesn't fix the issue that the two pieces of code having different behavior, but it at least provides a behavior compatible with pre-logical world, and can consistently reset all properties with |
Well, the problem you described is a non-issue in a pre-logical world too, fwiw, but I agree that whatever path we take here is going to make some behavior inconsistent (whether it's my example, or yours). |
I guess this is not just an issue with elem.style.writingMode = "horizontal-tb";
elem.style.marginTop = "1px";
elem.style.marginBlockStart = "2px";
elem.style.margin = "0px"; // top margin is still 2px :( |
You mean for any shorthand that sets physical properties with logical counterparts, right? And yeah, not even that, but just something like: elem.style.writingMode = "horizontal-tb";
elem.style.marginTop = "1px";
elem.style.marginBlockStart = "2px";
elem.style.marginTop = "0px"; // top margin is still 2px :( Given that (which is basically the problem Xidorn described before) is a more general problem with logical props themselves, I think we should make It may be worth trying to come up with a solution for that problem in a more general way, but it seems hard / impossible to me, because you don't know what physical property is actually represented by that property until computed value time. |
Note that, if you need to rely on the order of an iteration, you should not use for-in loops:
Instead, you should use something like Other than this, I think the result would always be as expected if you used |
Food for thought: what happens in this scenario? elem.style.marginTop = "1px";
elem.style.marginBlockStart = "2px";
elem.style.writingMode = "horizontal-tb"; // is top margin 1px or 2px now? |
If it starts with an empty style declaration block, then it is deterministic from the spec that, the top margin should be 2px, because elem {
margin-top: 1px;
margin-block-start: 2px;
writing-mode: horizontal-tb;
} I think this is clear in the spec, and it is not the problem here. |
Maybe... I somehow think the current behavior makes more sense than always appending the changed declaration... except when it interacts with shorthands and logical properties... Probably what we can do is:
With the first, we would have interoperable deterministic result, and with the second, the result should be less surprising when people try to set shorthand when some longhands have been there. |
But this wouldn't fix the following, would it? elem.style.marginTop = "1px";
elem.style.marginBlockStart = "2px";
elem.style.marginTop = "0px";
getComputedStyle(elem).marginTop; // "2px" :( A basic cascading rule is that the last declaration wins when there is a tie. So I really think that by default CSSOM should move the declaration to the end when you assign a value (but a method that preserves the order could be added). If this is not backwards-compatible, please add a note in the spec warning about this misbehavior, and recommend to use |
Not in WPT because w3c/csswg-drafts#1898 is not resolved yet. MozReview-Commit-ID: HRM7AcMcJVd
Not in WPT because w3c/csswg-drafts#1898 is not resolved yet. MozReview-Commit-ID: HRM7AcMcJVd --HG-- extra : source : d0896f475d15c65a5fe4afcf86c0e42713100952 extra : amend_source : 0be9c9b9aa7672e5e53020e28cff10d2c47e0fa6
Not in WPT because w3c/csswg-drafts#1898 is not resolved yet. MozReview-Commit-ID: HRM7AcMcJVd
I've retagged this as just a CSSOM issue, and marked it as a f2f issue, because it's kinda complicated. Retag the other specs if you disagree and think that there is something they should do. As far as I can tell, the problem is:
Right? So Xidorn and Oriol have suggestions:
(1) seems hard to do - you need to know the final computed value of writing-mode, direction, and maybe text-orientation to figure out the corresponding property, and those might be set by a completely different stylesheet. (2) seems to cleanly fit in with the Cascade machinery, tho there might be compat concerns. |
The order does matter. That's because set a CSS declaration value uses a "list of declarations", and lists are ordered. The algorithm also says "append", which implies there is an order. (Firefox and Chrome are compliant, but it seems Edge does not respect this insertion order). The problem is that the algorithm only appends the new declaration if there was no previous declaration of the same property. Otherwise, it only updates the value of the old one, without moving it to the end. Therefore, if you first set properties using Additionally, the resulting declarations of the following steps will be elem.style.marginTop = "1px"; // { margin-top: 1px }
elem.style.marginBlockStart = "2px"; // { margin-top: 1px; margin-block-start: 2px }
elem.style.marginTop = "0px"; // { margin-top: 0px; margin-block-start: 2px } so (assuming elem.style.marginTop = "1px"; // { margin-top: 1px }
elem.style.marginBlockStart = "2px"; // { margin-top: 1px; margin-block-start: 2px }
elem.style.marginTop = "0px"; // { margin-block-start: 2px; margin-top: 0px } |
Ah, thanks for the clarification! Doesn't change the conclusion much, but tweaks the details a bit. |
The Working Group just discussed
The full IRC log of that discussion<gregwhitworth> Topic: logical/physical property cascade and the .style API<astearns> github: https://github.com//issues/1898 <gregwhitworth> TabAtkins: someone pointed out that there are problems with the way logical properties are defined when trying to use the DOM APIs <gregwhitworth> TabAtkins: they get resolved in the normal order and then go through the cascade and we deal with the physical and logical based on ordering and writing mode <gregwhitworth> TabAtkins: when you set a property it gets appended to the list of properties in the style attribute <gregwhitworth> TabAtkins: and if you set one that's already there it just replaces it <gregwhitworth> TabAtkins: so this can cause it to be out of sync with what would happen in the cascade <gregwhitworth> TabAtkins: the proposal is to amend the CSSOM that if something is there it is always appended <gregwhitworth> TabAtkins: related to this <gregwhitworth> TabAtkins: we had an issue with !important and we resolved to append to make this work <gregwhitworth> dbaron: I'm happy to make that change <gregwhitworth> dbaron: we had a long discussion and resolved the opposite way <gregwhitworth> dbaron: a setter should append <gregwhitworth> dbaron: at the time implementations were inconsistent due to optimizations <gregwhitworth> dbaron: for existing properties in the fast path they would replace and others they would append <gregwhitworth> dbaron: one question, would having to do that mess up optimizations? <gregwhitworth> TabAtkins: when we discussed it internally we were fine making the change <gregwhitworth> dbaron: I found the minutes from 2013 but I'm looking for the other one <gregwhitworth> astearns: so I'm clear, the suggestion to append or remove and then append? <gregwhitworth> TabAtkins: those are equivelant <gregwhitworth> dbaron: I think it may turn out that it's not equivelant in the future <gregwhitworth> TabAtkins: we should figure out which one we want, it will need to have a note to determine this <gregwhitworth> dholbert: you could inspect the style attr and determine that way <gregwhitworth> TabAtkins: the current model limits to only one <gregwhitworth> astearns: I'm hearing two engines happy to change <gregwhitworth> astearns: any compat concerns? <gregwhitworth> dbaron: possibly <gregwhitworth> astearns: the compat issue would be limited to logical props shorthands? <gregwhitworth> TabAtkins: no <gregwhitworth> fantasai: it would only affect people looking at .style expecting a particular order <gregwhitworth> fantasai: which doesn't make much sense, so it's probably not very common <gregwhitworth> florian: I doubt it's common <gregwhitworth> Rossen: tools and editors might be doing this <gregwhitworth> TabAtkins: I'd be surprised if the editor was reading the style and writing to .style <gregwhitworth> Rossen: they could <gregwhitworth> astearns: The proposed resolution is to change CSSOM to append values via the .style API and add a note <gregwhitworth> TabAtkins: yeah, and try to figure that out in the future <dbaron> Things I found were https://lists.w3.org/Archives/Public/www-style/2013Sep/0469.html and https://lists.w3.org/Archives/Public/www-style/2013Oct/0007.html but I think there was further followup after the latter <gregwhitworth> astearns: any other opinions? objections? <gregwhitworth> RESOLVED <gregwhitworth> RESOLVED: Make it so that setters to the .style api are appended rather than put in place |
If old declarations are not removed and the element continuously receives new styles (e.g. simulating an animation using JS instead of CSS Animations), then the list of declarations may become huge. This will waste memory for no reason, won't it? |
I'm assuming that you'd remove other entries in the declaration block for the same property, which behavior-wise is identical to what happens during parsing (and remove + append). At least Firefox and Servo rely on this invariant for a single declaration block. Browser bugs:
|
I just realized that there's a gotcha, and it's that you can't optimize out redundant setters anymore, unless it's the last position on the declaration block. For example, all browsers I know of implement an optimization to avoid doing stuff in the case the property set had the same value. This is no longer applicable unless the property is at the end of the block, which isn't great... :( |
For the record: From #2269 (comment) which I think is basically the same issue as @emilio's comment above
|
…in place. This resolves w3c#1898.
...instead of replacing if the property is already set. This matches the spec[1] which was changed as a resolution from[2]. Intent thread: https://groups.google.com/a/chromium.org/d/msg/blink-dev/lzBoa1EAQpI/strfpNczAwAJ [1]: https://drafts.csswg.org/cssom/#set-a-css-declaration [2]: w3c/csswg-drafts#1898 Bug: 782407 Change-Id: I4b72c0207a4cf734fc2e415bd62c7863103ec309 Reviewed-on: https://chromium-review.googlesource.com/1054867 Commit-Queue: Emilio Cobos Álvarez <[email protected]> Reviewed-by: Rune Lillesveen <[email protected]> Cr-Commit-Position: refs/heads/master@{#560180}
Not in WPT because w3c/csswg-drafts#1898 is not resolved yet. MozReview-Commit-ID: HRM7AcMcJVd UltraBlame original commit: d0896f475d15c65a5fe4afcf86c0e42713100952
Not in WPT because w3c/csswg-drafts#1898 is not resolved yet. MozReview-Commit-ID: HRM7AcMcJVd UltraBlame original commit: d0896f475d15c65a5fe4afcf86c0e42713100952
Not in WPT because w3c/csswg-drafts#1898 is not resolved yet. MozReview-Commit-ID: HRM7AcMcJVd UltraBlame original commit: d0896f475d15c65a5fe4afcf86c0e42713100952
Or if it should, order of the expansion of
all
should be specified.From https://drafts.csswg.org/css-cascade-3/#all-shorthand:
This includes logical properties, and this is a problem because that means that it produces unexpected results when used from CSSOM (where the position a property declaration appears on matters).
In particular, we came across https://bugzilla.mozilla.org/show_bug.cgi?id=1410028, which happens because of the internal order the properties are reset.
In particular, it's not the same if
all
expands to:that if it expands the other way around.
i.e., this two pieces of code should be equivalent:
But they aren't in current browsers.
The text was updated successfully, but these errors were encountered: