-
Notifications
You must be signed in to change notification settings - Fork 675
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
[css-text-3] Don't mince words about aliasing/shorthands with word-wrap #866
Comments
For reference, here's a link to where Firefox implemented this property as an alias (rather than a shorthand). I think we could just as easily implement it as a shorthand if it were clearly specced as such, though I agree with @Manishearth that an alias seems strictly simpler & more appropriate for legacy stuff (if aliases are a speccable concept). |
I'd also note that the normal rules for shorthands would produce a third result that is both (a) undesirable and (b) neither the Firefox nor the Chrome result, i.e., serializing the above rule to: This is by the same principle that: document.body.style.borderLeftColor = "green";
document.body.style.borderLeftWidth = "medium";
document.body.style.borderLeftStyle = "dotted";
console.log(document.body.getAttribute('style')); produces:
in both Firefox and Chrome. I think that also suggests that we need to specify the concept of aliases. |
FWIW, the spec-text for
https://www.w3.org/TR/2012/WD-css3-text-20120119/#overflow-wrap The language was changed to its current form ("as an alternate name...as if it were a shorthand") in this commit in 2012: 0532714 |
(For the record, I filed https://bugs.chromium.org/p/chromium/issues/detail?id=679068 and https://bugs.webkit.org/show_bug.cgi?id=166782 on the odd Blink/WebKit behavior here. It doesn't seem like they're actually treating it as a shorthand -- they're doing some special alternate form of aliasing, distinct from their regular legacy-alias behavior.) |
cc @miketaylr since the compat spec references this concept of aliasing without defining it (and we should take input from them if we start building the exact definition) |
The wording is unintentionally loose, but the intent was to make it a shorthand. If we want to keep that, we should update the phrasing to:
Some of the reasoning for that is documented here: https://wiki.csswg.org/ideas/aliasing TL;DR: we had a reasonably extensive discussion about how aliasing should work when "aliasing" break-before and page-break-before, and figured that shorthands were a good way to do that: well defined (including the OM) without needing to introduce any new concept, generally well behaved, deals well with the case when the legacy prop and the new prop don't have the exact same set of values. I still think the idea has merit to it, but if implementations generally agree on a different aliasing mechanism, we should spec it and use that. Spec-fiction doesn't help anyone. Maybe we can keep exceptions and use shorthands when the legacy prop and the new prop accept different values. |
This doesn't actually seem to be what Chromium does for the few properties where they (ab)use shorthands to do aliasing. Sample (live jsfiddle version):
This testcase produces So, they do the Right Thing here, even though it's the opposite of normal shorthand behavior. (I wonder if that's due to a special-case codepath for shorthands that are only shorthands of a single property, maybe?) |
The Working Group just discussed
The full IRC log of that discussion<fantasai> Topic: aliasing mechanism<fantasai> github: https://github.com//issues/866 <dael_> fantasai: Couple places in text with an alias like overflow-wrapa nd word-wrap and the way their aliased is not how they're impl. <dael_> fantasai: Previously resolved that when we do alais we treat as shorthand as other prop. Moz has different mech. If we're changing I need a resolution on what to change to. <dael_> florian: I think it's not just Moz. In general aliasing in a browser doesn't work as a shorthand. <dael_> emilio: How to observe? <dael_> florian: By browser engineers complaining. What is the different behavior? <dael_> emilio: [missed] <fantasai> dbaron's comment on observable difference - https://github.com//issues/866#issuecomment-271028230 <dael_> dbaron: One difference might be when serializing declaration you try and serialize to a shorthand first and you don't want to do that here. <dael_> dbaron: You want that for real shorthands <dael_> emilio: But not aliases. <dael_> dbaron: Example if you have a declaration that says border-meduim on each direction we'll use border:medium. Same rule is that if someone decalred overflow-wrap:inherit we'd serialize to word-wrap. <dael_> abCSSOM wording has preferred order where shorthands are above longhands, but prefixed are below all of them. <fantasai> https://www.w3.org/TR/css-break-3/#page-break-properties <astearns> s/abCSSOM/TabAtkins: CSSOM/ <dael_> fantasai: Tricker is page break aliases. Those ones the page-break which is old will express all the values of the longhand which is where we're moving <dael_> dbaron: There are also things that aren't supposed to work for shorthands. We might have changed some of those things to work. <dael_> emilio: Spec says generally that getPRopertyValue works for shorthand but in getComputedStyle only properties are actual long hands but if there's properties for shorthands also expose them there. getPropertyValue font is supposed to work. <dael_> emilio: Both work in webkit and block, but getComputedStyle.font isn't supposed to work per spec. <dael_> emilio: Edge and FF don't impl any shorthand in getComputedStyle <dael_> dbaron: WE do some. <dael_> emilio: blink and webkit support both. <dael_> dbaron: Other question is what is the actual mech we use. <dael_> dbaron: In old style system at the point we converted a string to an internal css property ID we also did the alias mapping so every time you had an input that's a string that was asking something about a property we would convert it. <dael_> emilio: Now I think we preserve a bit longer to control aliases. BUt not much longer. Once they're in the declaration block. <fantasai> s/aliases/aliases vis prefs/ <dael_> fremy: WE only have "realId"s that are HTML. If we have -webkit-something and if the same as a prefix it's the same thing. <fantasai> s/property ID/property ID where we also did lowercasing and such/ <dael_> astearns: I'm a bit confused. dbaron you started saying it's not like a shorthand because when you serialize the property turns into alias. <dael_> dbaron: The thing that's not the alias is turned long hand. <dael_> emilio: Supposed to serialize the short hand. If you have foo per spec it should be -webkit-foo. <dael_> dbaron: If it's word-wrap and overflow-wrap it's supposed to switch. <dael_> TabAtkins: It's alphasbetical. <dael_> emilio: one is long hand. <dael_> TabAtkins: Yes, if they're both shorthands. <dael_> florian: If word-wrap is defined to be a shorthand you'll serialize tot he thing that's supposed to be the shorthand <dael_> frWhen you spec the alias it's the same thing. <dael_> astearns: Instead of defining alias as a shorthand we define alias as a separate thing and define what browsers are doing <dael_> myIes: If you say .font does what you spoke about work? Would the alias and the original exist there? <dael_> emilio: Yeah. <dael_> myles: It's not just turning strings into an ID. You also do this other thing. <dael_> florian: What about properties that take values? <dael_> emilio: Same Whenever you parse a property ID if you receive like the alias you once you process it it's the same as if you got the longhand <dael_> florian: If you serialize the transition property <dael_> dbaron: Transition property property. <TabAtkins> s/transition property/transition-property/ <dael_> florian: If you serialize the transition property property which takes property names you do not preserve the name. <dael_> dbaron: In old gecko we did not preserve it. <dael_> florian: And a shorthand you do preserve? <dael_> dbaron: Yes. <dael_> florian: That's one reason I pushed for shorthand originally. <dael_> dbaron: We could still spec the other way for alias <dael_> florian: Initial reason for shorthands was double. One we looked for in page-break has a different set of values. <dbaron> you have to say "transition-property property" because otherwise "transition-property" might be heard as "transition property" <dael_> emilio: Parsing rules. That's what we used to have for box-transform. We impl it as a shorthand and special cased serialization. <dael_> florian: In general I think we can do the simple thing. <dael_> fremy: For the transition property property we keep the ID as it is. If you can't match to a property in the end it doesn't work for us. <dael_> emilio: We preserve the ID...I agree it's not relevent. <dael_> fremy: We're not preserving it as a shorthand. <dael_> myles: So mechanism for alias is not shorthands. <dael_> florian: I'd like to resolve in general and separately for page-break and friends. <dael_> emilio: Can't change parsing rules? <dael_> florian: No. <dael_> astearns: Seems to me like we could define what aliases are in Cascade in general and when we have an alias that needs mapping we define that in it's own spec. <dael_> fremy: Example some webkit-flex properties are different. <dael_> florian: WE define separately then? If values are the same we don't do anything. <dael_> emilio: In FF we don't have any special case. I don't have context for page-break but how is it supposed to work with page-break:foo and then break:foo <dael_> florian: Let me pull spec up. <dael_> florian: page-break: before|always maps to break-before:page <fantasai> s/page-break: before|/page-break-before:/ <dael_> fremy: They're not aliases. <dael_> florian: If we define aliasing mech it won't work here. <dael_> emilio: Page break properties, how should they work with aliases <dael_> florian: They're supposed to be shorthands. <dael_> emilio: Why are we covering? <dael_> myles: There are shorthands and aliases and they're different <dael_> dbaron: Page-break still needs to be a shorthand. <dael_> astearns: But that's nto relevent <dael_> florian: They're defined as these are aliases and you do them as shorthands. We hav to change that <fantasai> Another aliasing case is https://www.w3.org/TR/css-writing-modes-3/#glyph-orientation <dael_> astearns: We have to change where we say alias in all our specs <dael_> myles: Where values aren't the same. <dael_> florian: We had resolved on their the same. <dael_> myles: was a bad resolution. <dael_> emilio: What's expected to happen when you seilaize page-break:always It's defined to map to break:before-page What's expected serializeation of page-break:always in .style.pagebreak <dael_> emilio: Is it break:before-page? break-before:always? <dael_> fremy: It's not an alias. It's a webkit thing so it's an alias. <fantasai> s/It's a webkit thing/Alias is a webkit thing/ <dael_> florian: Let's delete alias from that paragraph and leave the rest as is. Let's define alias somewhere. <dael_> emilio: If we define this is a shorthand then break-before:left will be page break. It's weird because page-break is legacy <dael_> myles: define in other direction? <dael_> fantasai: Can't because break-before has values that page-break:before can't. <dael_> emilio: Page mpas to page <dael_> florian: Thing on the left are everything you have things on the right are more values. <dael_> emilio: We can special case that. <dael_> fremy: Can have concept of legacy property that's serialized at the bottom. <dael_> emilio: Then you have shorthands where you have to create special cases. <dael_> fantasai: You'd have alist of properties where you're looking for a shorthand and you never look at those. <dael_> fantasai: Right now when you try to serialize you have a list of declarations and if it corrisponds to a shorthand you serlialize as the shorthand. And we're saying when you check eliminate the legacy <dael_> astearns: Serveral to resolve. First is we should define what an alias is in CSS Cascade <dael_> astearns: Obj? <dael_> RESOLVED: we should define what an alias is in CSS Cascade <dael_> astearns: In pure alias cases where we don't want shorthand behavior we need to change to the definition written in the previous resolution. <dael_> florian: Yes. <dael_> astearns: We will use this definition where it's appropriate. <dael_> RESOLVED: We will make the required edits for the definition resolved previously <dael_> astearns: Prop: We create a new legacy shorthand concept in Cascade L4 for those things that we have legacy shorthands that should never be serialized <dael_> astearns: Or is this a type of short hand. <dael_> emilio: There's a tricky thing because only place for this kind of shorthand is when the new thing superceeds the old. Is there a case where they don't map? <dael_> fantasai: glyph-orieintation which takes a keyword and a degree and those map to keywords in text-orientation. <dael_> emilio: Okay. That's fine as long as you can map. <dael_> astearns: That can be it's own section or subsection <dael_> astearns: Obj? <dael_> RESOLVED: We create a new legacy shorthand concept in Cascade L4 for those things that we have legacy shorthands that should never be serialized <dael_> emilio: Then someone needs to edit. <dael_> fantasai: TabAtkins and I can <dael_> florian: Do we need to resolve on a list? <dael_> emilio: If they have same syntax you're fine otherwise use legacy. <dael_> astearns: Let's do what we resolved and look at the fallout from that. Better to have them take time and find places it doesn't work. <dael_> florian: Principle stated is if they take same values it's alias otherwise it's legacy. <dael_> emilio: They're different things. <dael_> astearns: florian is asking that we resolve to put thing in one bucket or the other and if we find problems we bring that to the group. <dael_> astearns: Prop: everything that's currently defined as an alias needs to use new legacy definition or is a legacy shorthand <dael_> RESOLVED: everything that's currently defined as an alias needs to use new legacy definition or is a legacy shorthand <dael_> fantasai: If you're using aliasing mech what does that mean...you'll always serialize as the new thing and we don't have objects in OM rep that? <dael_> emilio: We do. <dael_> fantasai: WE should spec that <dael_> myles: if you set the old object you should be able to read that from the new object <dael_> fantasai: So this also applies to style. <dael_> emilio: Yes. <dael_> fantasai: Anywhere name is exposed. Okay. <dael_> fantasai: I think that's it. <dael_> fantasai: If you type in word-wrap:break-word and reserialize that you get overflow-wrap:break-word That's okay? <dael_> many: yes |
word-wrap was previously defined as its own property in CSSProperties.json5, but with the same behavior as overflow-wrap. However, this meant that word-wrap showed up alongside word-wrap in cssText. This patch converts word-wrap to be an alias of overflow-wrap, as this will prevent the issue of both properties showing up in cssText and matches the resolution in w3c/csswg-drafts#866. Bug: 679068 Change-Id: I3d415eb1cde9a92dffa2a045ba5fa8b015eeb2d7
word-wrap was previously defined as its own property in CSSProperties.json5, but with the same behavior as overflow-wrap. However, this meant that word-wrap showed up alongside word-wrap in cssText. This patch converts word-wrap to be an alias of overflow-wrap, as this will prevent the issue of both properties showing up in cssText and matches the resolution in w3c/csswg-drafts#866. Bug: 679068 Change-Id: I3d415eb1cde9a92dffa2a045ba5fa8b015eeb2d7
Did anyone volunteer to write the text for the concept of an alias? Asking as I'm updating Chromium's behavior here, and wondered if it would make it into the spec soon. |
Not as far as I can tell. I'm happy to update definitions to link to it once it's written, but someone with detailed knowledge of how it is implemented should write it down first. |
word-wrap was previously defined as its own property in CSSProperties.json5, but with the same behavior as overflow-wrap. However, this meant that word-wrap showed up alongside word-wrap in cssText. This patch converts word-wrap to be an alias of overflow-wrap, as this will prevent the issue of both properties showing up in cssText and matches the resolution in w3c/csswg-drafts#866. Bug: 679068 Change-Id: I3d415eb1cde9a92dffa2a045ba5fa8b015eeb2d7 Reviewed-on: https://chromium-review.googlesource.com/1073677 Reviewed-by: Philip Jägenstedt <[email protected]> Reviewed-by: Rune Lillesveen <[email protected]> Commit-Queue: Chris Nardi <[email protected]> Cr-Commit-Position: refs/heads/master@{#565331}
word-wrap was previously defined as its own property in CSSProperties.json5, but with the same behavior as overflow-wrap. However, this meant that word-wrap showed up alongside word-wrap in cssText. This patch converts word-wrap to be an alias of overflow-wrap, as this will prevent the issue of both properties showing up in cssText and matches the resolution in w3c/csswg-drafts#866. Bug: 679068 Change-Id: I3d415eb1cde9a92dffa2a045ba5fa8b015eeb2d7 Reviewed-on: https://chromium-review.googlesource.com/1073677 Reviewed-by: Philip Jägenstedt <[email protected]> Reviewed-by: Rune Lillesveen <[email protected]> Commit-Queue: Chris Nardi <[email protected]> Cr-Commit-Position: refs/heads/master@{#565331}
word-wrap was previously defined as its own property in CSSProperties.json5, but with the same behavior as overflow-wrap. However, this meant that word-wrap showed up alongside word-wrap in cssText. This patch converts word-wrap to be an alias of overflow-wrap, as this will prevent the issue of both properties showing up in cssText and matches the resolution in w3c/csswg-drafts#866. Bug: 679068 Change-Id: I3d415eb1cde9a92dffa2a045ba5fa8b015eeb2d7 Reviewed-on: https://chromium-review.googlesource.com/1073677 Reviewed-by: Philip Jägenstedt <[email protected]> Reviewed-by: Rune Lillesveen <[email protected]> Commit-Queue: Chris Nardi <[email protected]> Cr-Commit-Position: refs/heads/master@{#565331}
Defined the CSS side of things at https://drafts.csswg.org/css-cascade-4/#aliasing. We think that's sufficient detail for Cascade; the remaining detail for how legacy shorthands work needs to show up in CSSOM, specifically in https://drafts.csswg.org/cssom/#serializing-css-values (or more precisely, probably in the definition of "preferred order"). |
That looks like a good start. However:
|
Hm, indeed. We should make that clear.
That's precisely the "remaining detail" that "needs to show up in CSSOM" I was talking about. No need for Cascade to list what needs to be changed in OM when OM can just change. |
…w-wrap, a=testonly Automatic update from web-platform-testsConvert word-wrap to an alias of overflow-wrap word-wrap was previously defined as its own property in CSSProperties.json5, but with the same behavior as overflow-wrap. However, this meant that word-wrap showed up alongside word-wrap in cssText. This patch converts word-wrap to be an alias of overflow-wrap, as this will prevent the issue of both properties showing up in cssText and matches the resolution in w3c/csswg-drafts#866. Bug: 679068 Change-Id: I3d415eb1cde9a92dffa2a045ba5fa8b015eeb2d7 Reviewed-on: https://chromium-review.googlesource.com/1073677 Reviewed-by: Philip Jägenstedt <[email protected]> Reviewed-by: Rune Lillesveen <[email protected]> Commit-Queue: Chris Nardi <[email protected]> Cr-Commit-Position: refs/heads/master@{#565331} -- wpt-commits: 71aca0a171ce75d1acfc43e1e523f709612addb8 wpt-pr: 11282
…w-wrap, a=testonly Automatic update from web-platform-testsConvert word-wrap to an alias of overflow-wrap word-wrap was previously defined as its own property in CSSProperties.json5, but with the same behavior as overflow-wrap. However, this meant that word-wrap showed up alongside word-wrap in cssText. This patch converts word-wrap to be an alias of overflow-wrap, as this will prevent the issue of both properties showing up in cssText and matches the resolution in w3c/csswg-drafts#866. Bug: 679068 Change-Id: I3d415eb1cde9a92dffa2a045ba5fa8b015eeb2d7 Reviewed-on: https://chromium-review.googlesource.com/1073677 Reviewed-by: Philip Jägenstedt <[email protected]> Reviewed-by: Rune Lillesveen <[email protected]> Commit-Queue: Chris Nardi <[email protected]> Cr-Commit-Position: refs/heads/master@{#565331} -- wpt-commits: 71aca0a171ce75d1acfc43e1e523f709612addb8 wpt-pr: 11282
It is clear. The spec says
Whatever is supposed to happen with a property "foo" inputted as "FOO", exactly the same happens between "new" and "old". If it is unclear what happens for case-mapping in some situation, then it is also unclear for aliasing; but once it is fixed for case-mapping it will be fixed for aliasing also. |
Forgot, need to keep Needs Edits on for css-text/css-break/etc. |
opened #3109 for the cssom part. |
We have a test for that: https://github.com/web-platform-tests/wpt/blob/master/css/css-text/overflow-wrap/word-wrap-alias.html, removing the label saying we need tests. |
https://drafts.csswg.org/css-text-3/#propdef-word-wrap
The spec says:
The "as if it were a shorthand" is a bit hand-wavy, especially since "as an alternate name" can mean something else.
In particular, we have two different ways of "aliasing" properties. One is by making them shorthands of the aliasee. The other is by making them redirect to the other property at parse time.
The difference crops up when doing things like serializing property declaration blocks. For example, the following CSS:
when serialized via
document.styleSheets[0].cssRules[0].cssText
in Firefox produces"#foo { overflow-wrap: break-word; align-items: baseline; }"
, whereas in Chrome/Safari it produces"#foo { word-wrap: break-word; overflow-wrap: break-word; align-items: baseline; }"
. This means that Firefox implements it as a "redirect alias", but Chrome/Safari implement it as a shorthand alias. All of them handle-webkit-align-items
as a "redirect alias".Browsers already use "redirect aliases" consistently for aliasing legacy prefixed properties. This concept of an alias is not defined in the spec, but is consistently implemented in browsers as something akin to:
If
foo
is an alias for propertybar
:foo
, treat it as if it were the name you encountered was of propertybar
foo
that under the hood work with propertybar
foo
(including during serialization of a declaration block)The compat spec uses this concept of "aliasing", but does not define it.
We should either explicitly spec
word-wrap
to be a shorthand, or define this other concept of property alias in the spec and use it here (and also use it in the compat spec). I personally prefer the latter solution since aliasing is currently unspecced but imo shouldn't be, and because this is the only case where a shorthand is used for aliasing.cc @dholbert @dbaron @fantasai
The text was updated successfully, but these errors were encountered: