Skip to content
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-logical] Flow-relative syntax for margin-like shorthands #1282

Open
fantasai opened this issue Apr 23, 2017 · 76 comments
Open

[css-logical] Flow-relative syntax for margin-like shorthands #1282

fantasai opened this issue Apr 23, 2017 · 76 comments
Labels
css-logical-1 Current Work i18n-needs-resolution Issue the Internationalization Group has raised and looks for a response on. Needs Feedback/Review

Comments

@fantasai
Copy link
Collaborator

CSS currently assigns the values in the margin/padding/border shorthand to their physical longhands, i.e.

  margin: 1em 2em 3em 4em;

is equivalent to

  margin-top: 1em;
  margin-right: 2em;
  margin-bottom: 3em;
  margin-left: 4em;

I'm pretty sure we want some equivalent syntax for assigning into the logical longhands instead, but what should that be?

The current proposal is to put a keyword in front of the 4 values, like

  margin: relative 1em 2em 3em 4em;

Another possibility is to use a !keyword:

  margin: 1em 2em 3em 4em !relative;

or to create a new property in its place:

  margin-relative: 1em 2em 3em 4em;

or use some entirely as-yet-unused symbol or syntax.

And of course the exact keyword, if one is used, is up for debate as well; shorter would be better. People will be drawing up entire style sheets that use almost exclusively flow-relative properties, so this needs to be designed for comfort under frequent use.

Ideas welcome~

@fantasai fantasai added the css-logical-1 Current Work label Apr 23, 2017
@chharvey
Copy link

chharvey commented Apr 23, 2017

I agree with the current proposal, a keyword in front of the values. I personally like relative better than logical, because I don't think this spec really has anything to do with "Logic" per se… (the study of truth and argument forms).

A couple of points:

  1. the !relative keyword isn't already part of the standard CSS syntax and doesn't (and shouldn't) apply to all properties like the !important keyword does.
  2. adding a new property like margin-relative would have to set (or reset) its sub-properties, but sub-property names are usually extensions of the shorthand. So a margin-relative shorthand would imply its sub-properties are things like margin-relative-block-start, margin-relative-block-end, etc. There are exceptions, though, in the case of grid-gap setting grid-row-gap and grid-column-gap—property names that still make me mad!

@MurakamiShinyu
Copy link
Collaborator

MurakamiShinyu commented Apr 26, 2017

margins for logical shorthand -- is this bad idea?
I think plural word for shorthand makes sense, and columns is shorthand for column-* .

@chharvey
Copy link

@MurakamiShinyu — I see where you are going with this, but it could potentially become often confused with margin, which already exists. (Did they mean to put margins or was that a typo? Which one is relative again, I can't remember? etc etc…)

I think with a keyword such as relative prepended to the values, the code indicates very clearly and unambiguously what was intended—at the cost of just a few more bytes.

columns is okay because there is no column property, but in retrospect I would probably have preferred column for consistency.

@MurakamiShinyu
Copy link
Collaborator

I admit it's a crazy idea: 'margins' stands for "margin's writing-mode relative shorthand". But there is one advantage: 'margins' is easier to type than 'margin-relative' or 'margin: relative ...'. My concern is that people may feel troublesome to type a lot of 'relative' when css-logical-props becomes widely available.

@bradkemper
Copy link
Contributor

I like the idea of !keyword that could be added to any 4-value clockwise shorthand (and their 3-value, 2-value, and 1-value versions). How about just an unadorned !, to make it an even easier, quicker switch? So...

border-radius: 2em 1em 4em / 0.5em 3em !;

is equivalent to

border-block-start-inline-start-radius:  2em 0.5em;
border-block-start-inline-end-radius:    1em 3em;
border-block-end-inline-end-radius:      4em 0.5em;
border-block-end-inline-start-radius:    1em 3em;

Adding the ! to a 1-value version, like margin: 0 ! wouldn't have any noticeable effect, but should be allowed.

@cork
Copy link

cork commented Apr 27, 2017

Why not go the same route as for box-sizing? So something like margin-mode: relative;

Then when the support gets common you could just do:

* { margin-mode: relative; }

div {
  margin: 1em 2em 3em 4em;
}

#exception {
  margin-mode: physical;
  margin: 1em 2em 3em 4em;
}

@SebastianZ
Copy link
Contributor

Having a margin-mode property would go hand in hand with the current proposal of margin: relative 1em 2em 3em 4em;, i.e. be another longhand property for margin. The disadvantage of this is that its value infuences the handling of the other values, which might be unexpected.

I totally agree with @chharvey's comment that !relative (or ! for the same reason) and margin-relative have downsides.

Sebastian

@inoas
Copy link

inoas commented Apr 27, 2017

If I got the ticket right (because the opening post doesn't really explain):

I think I have already answered via twitter... but I am suggesting transpose again.
And from an author point of view I would not care it it was margin-transpose: val val val val or margin: val val val val transpose;

@chharvey
Copy link

chharvey commented Apr 27, 2017

@cork I do like your idea of margin-mode. That way the syntax of the margin property would not have to change. The syntax of margin-mode would be

syntax:    [ physical | relative ] | inherit | initial | unset

initial:   physical

inherited: true

One upside would be that you wouldn't have to change the margin property when you want to change the mode—taking advantage of the Cascade, resulting in more readable diff.

Alas, a recent change of the spec indicates a different order when relative values are used.

p {
  margin: 1px 2px 3px 4px;
  /* equivalent to standard order (top, right, bottom, left)
  margin-top:    1px;
  margin-right:  2px;
  margin-bottom: 3px;
  margin-left:   4px; */
}
p.relative {
  margin-mode: relative; /* <-- added */
  /* equivalent to new order:
  margin-block-start:  1px; `top`    in LTR-TB
  margin-inline-start: 2px; `left`   in LTR-TB
  margin-block-end:    3px; `bottom` in LTR-TB
  margin-inline-end:   4px; `right`  in LTR-TB */
}

So in the example above, by adding margin-mode: relative;, you would still have to add margin: 1px 4px 2px 3px; in the second ruleset to keep things the same.

Another downside: you would have to have corresponding "mode" properties for the following, which could be a bit much:

@MatsPalmgren
Copy link

I suspect margin-mode might be hard to implement - it's easier if you know at parse time how a property is supposed to be interpreted.

I like the !relative or ! proposal best so far. It would make it possible for multi-value properties to have both physical/logical values in the same declaration (if we want that). For example:
background-position: 10px, ! 20px, 30px, ! 40px;

I'm concerned though, that this might lead to new CSS properties being defined as physical-first and require ! for logical values. This would be unfortunate since logical values are superior in most cases. Perhaps ! could be interpreted as a general physical/logical switch though, so that for example grid-gap: ! 10px 20px; would set 10px on the longhand that corresponds to the vertical axis?

@MurakamiShinyu
Copy link
Collaborator

I like the idea of #1279: margin-block is shorthand for margin-block-start + margin-block-end, and margin-inline is shorthand for margin-inline-start + margin-inline-end.
These will be often more useful than single margin flow-relative shorthand, and I am ok with adding 'relative' keyword when the margin shorthand is needed. Or how about the following syntax:

  margin: [ block <'margin-block'> || inline <'margin-inline'> ]

e.g.

  margin: block 1em 3em inline 2em 4em;

@inoas
Copy link

inoas commented Apr 28, 2017

I have to raise my voice and say that short symbolic like a punctuation (!) mark are really not good practice IMHO. The gains in saved typing are minimal and the symbol does not transport its meaning. It pretty much feels regexpy and IMHO CSS should not be.

I'd favour extra logical properties. Aka margin and padding are absolute and margin-relative and padding-relative are not (dimensions for position and dimensions-relative or similar could be added later).

That is a very clear and easy interface for authors and there is no clash between old properties and new properties. Authors can also use margin and margin-relative independent of each other and thus are not breaking css parsing of older browsers!

So I really like @fantasai initial proposal.

@fantasai
Copy link
Collaborator Author

fantasai commented Apr 28, 2017

Wow, okay! Here's some responses:

  • I think it's pretty sure we are not doing a separate property to control interpretation of shorthands. First, as @MatsPalmgren mentions, this is harder to implement--we really want a switch that's syntactically part of the declaration and lets us handle this at parse time. Secondly, it creates an "action at a distance" effect, which is likely to result in confusion and errors as multiple parts of a stylesheet interact.
  • Agree that margin vs margins is going to be confusing and we shouldn't go that route. :) For languages that pluralize with s such as English, it's a mostly-unnoticeable morpheme and not something we ever want to be a distinguishing factor in any CSS syntax.
  • I agree with @inoas that using just ! alone is likely a bit too obscure (and also a bit too general, imho, as we use !keyword for other things like !important). However, I also agree with the concerns about !relative or relative or -relative potentially being too much of a typing burden; as I mentioned in the OP, we do expect this to become the default mode of assignment for many authors, so I'd say it's fair to trade a bit of obscurity for a bit of typing efficiency.
  • Wrt @MatsPalmgren’s comment about moving to flow-relative directions... new CSS models like Grid and Flexbox tend to use flow-relative directions to begin with, however for anything that's analogous to an existing CSS feature like margin or background-position, consistency is a more important consideration. Hence scroll-snap-margin is physical, even though we would have preferred it to be flow-relative.
  • transpose is not a bad name, the main downside is that it doesn't indicate what the mapping is! There's a distinct possibility that more mappings could be added in the future--Writing Modes already includes both flow-relative and line-relative mappings.
  • Fwiw, margin-block and margin-inline were resolved to add already, I just forgot to make the edits. :( I'll go do that now. ;)
  • Wrt interleaving keywords... one of the great things about the 4-value shorthand syntax is the way that it can use 1, 2, 3, or 4 values to assign to the four sides, and pairs things up in ways that both correspond to common use cases and yet also unroll syntactically in a consistent way. I think we want to keep those qualities; and also be consistent with Grid which already has a 4-value shorthand in grid-area.

@MurakamiShinyu
Copy link
Collaborator

MurakamiShinyu commented Apr 29, 2017

Agree with @fantasai. Now I feel original relative keyword or -relative suffix were better. However, I think the word relative also has obscurity. People may think the relative is related to position: relative, and may not notice that it is about "flow-relative-directional".
(For this reason I think logical keyword might be better then relative)

How about margin-bi (suffix -bi, stands for "block and inline")? I know this is exceptional in CSS property naming convention (avoid abbreviations and use complete words), but has the following advantages:

  • easy to type, only three additional characters to the original name
  • we have *-block and *-inline properties, and making the combined shorthand names using the first letters of "block" and "inline" will be easy to understand
  • "bi" indicates the order of values, block is first then inline, and convenient to remember the value syntax

and CSS already has abbreviations in some keywords, e.g., "rl" (for "right to left direction") in vertical-rl value of writing-mode, and using "bi" for "block and inline directions" will be not too bad.

@fantasai
Copy link
Collaborator Author

Sorry; typo in commit message. :/

@fantasai fantasai reopened this Apr 30, 2017
@chharvey
Copy link

chharvey commented May 7, 2017

If the keyword route is decided upon, can the syntax allow it to be at the beginning or end of the declaration? Inspired by box-shadow inset (that is, inset of the box-shadow, not the new inset positioning property).

So for margin it would be

relative? && [ <length> | <percentage> | auto ]{1,4}

@bradkemper
Copy link
Contributor

Weird. My comment was posted to the wrong page

@bradkemper
Copy link
Contributor

I really don't think we should have margin-* or *-margin as a property or !keyword for this. Because then you would need to do it for padding, border (and border-width, border-style, and border-color), border-radius, and many others. It should be a single !keyword that can be used for all (I agree that action-at-a-distance is bad for this).

If it is to be typed a lot (and really, that is the hope, that authors are considering bi-di and writing mode all the time), then it needs to be very short. I would say no more than 2-3 letters long. I still prefer an unadorned ! for that reason, even though it would more likely lead to authors adding it without understanding why.

@fantasai fantasai added i18n-tracker Group bringing to attention of Internationalization, or tracked by i18n but not needing response. Needs Feedback/Review labels Jun 20, 2017
@fantasai fantasai changed the title [css-logical] Syntax for margin-like shorthands [css-logical] Flow-relative syntax for margin-like shorthands Jun 20, 2017
@jonjohnjohnson
Copy link

jonjohnjohnson commented Apr 11, 2018

I know there are multiple arguments against having a separate property that controls interpretations of shorthands for reasons like implementation difficulty or "action at a distance", but isn't that akin to how box-sizing works? I know there have been discussions about properties like box-size (#820), so wouldn't something like box-mode: [ physical | relative ] be what we'd all get behind if this was part of the initial proposal for box shorthands?

I'd imagine anyone who wants to use logical features would be "all in", not needing to set individual "modes" and wanting something like box-mode to cascade/inherit and set interpretation for ALL shorthand box properties such as border-width,padding,margin,border-radius, background-position, etc...

@xfq
Copy link
Member

xfq commented May 13, 2018

@fantasai wrote:

I agree with @inoas that using just ! alone is likely a bit too obscure (and also a bit too general, imho, as we use !keyword for other things like !important). However, I also agree with the concerns about !relative or relative or -relative potentially being too much of a typing burden; as I mentioned in the OP, we do expect this to become the default mode of assignment for many authors, so I'd say it's fair to trade a bit of obscurity for a bit of typing efficiency.

Even if we expect this to become the default mode of assignment for many authors, I would still prefer clarity & readability to typing efficiency, because the latter can be mitigated by code completion and code snippets in authoring tools, and IMHO shouldn't be a major concern (comparing with readability & less surprise for authors who are not familiar with flow-relative properties) when designing a language like CSS.

@fantasai
Copy link
Collaborator Author

I agree strongly with @bradkemper’s comment: this needs to be generic enough that it doesn't get confused with property-specific value spaces, and it also needs to be convenient enough that authors using flow-relative syntaxes are not at a significant ergonomic disadvantage compared to authors using physical syntaxes.

Another option would be to have a longer per-declaration !keyword (for clarity) but also a higher-level syntax similar to @namespace (changing the default interpretation of an entire stylesheet) or @media (changing the default interpretation in a block). This would be the most convenient, at the cost of making it possibly confusing if someone is copy-pasting style rules out-of-context.

@fantasai
Copy link
Collaborator Author

fantasai commented Aug 17, 2018

A third option would be to have some other not-currently-used single punctuation character somewhere in the declaration, to indicate flow-relative mapping, e.g.

margin: 1em 2em 3em 4em; /* physical mapping */
~margin: 1em 2em 3em 4em; /* logical mapping, option A */
margin ~: 1em 2em 3em 4em; /* logical mapping, option B */
margin :~ 1em 2em 3em 4em; /* logical mapping, option C */

This is convenient to type and safe for out-of-context quoting, at the cost of being more obscure.

@Loirooriol
Copy link
Contributor

If you write, you can set the bang in .setProperty()

How would this work? Would there be a 4th argument?

element.style.setProperty("margin", "1px 2px 3px 4px"); // non-important, physical
element.style.setProperty("margin", "1px 2px 3px 4px", "important"); // important, physical
element.style.setProperty("margin", "1px 2px 3px 4px", "", "logical"); // non-important, logical
element.style.setProperty("margin", "1px 2px 3px 4px", "important", "logical"); // important, logical

Or conflate all flags into the 3rd argument like "", "logical", "important", "logical important"?

What about reading? I bet most scripts will just use getPropertyValue("margin") without checking getPropertyMappingLogic("margin") or whatever. So things may start breaking, causing authors to avoid setting properties logically, making this feature pointless.

What about computed styles? I don't think we want to track if the value comes from a logical or physical declaration, just like we don't track the priority (computed properties are considered non-important). So should they be considered physical or logical?

From the point of view of CSSOM, using different properties seems way less problematic.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-logical] Flow-relative syntax for `margin`-like shorthands.

The full IRC log of that discussion <TabAtkins> addison: This one we discussed last year at TPAC
<TabAtkins> addison: called flow-relative syntax for margin-like shorthands
<TabAtkins> addison: But really it's about providing support for directionality by changing left/right to start/end in various properties
<TabAtkins> addison: And allowing margin-like shorthands (the 4-direction props) to follow that
<TabAtkins> addison: We've been working with some CSSWG members on the steps necessary to do this in a generic fashion across CSS
<TabAtkins> addison: There've been some action items outstanding, I think florian has one to enumerate the various props
<TabAtkins> addison: So this is a check-in to see how progress is going, see if we can encourage progress
<TabAtkins> addison: And make sure the larger WG remains aware.
<florian> q?
<TabAtkins> florian: Sorry to report I haven't progressed my Action Item
<TabAtkins> florian: But now that I'm not a board<->AB laiason I ahve a lot more time and plan to make progress. Sorry for not doing it so far.
<TabAtkins> addison: The more global thing - we've been having monthly calls, with Floriana nd Elika repping CSS, and others of us repping i18n.
<TabAtkins> addison: It's been productive (if inconveniently timed) call, and we've been handling issues
<TabAtkins> addison: If anyone wants to participate, please ping me to get notified.
<TabAtkins> addison: We welcome participation.
<TabAtkins> astearns: Besides the florian AI, any other progress on this issue?
<TabAtkins> addison: Any other concerns? Otherwise we can move on.

@747
Copy link

747 commented Nov 2, 2023

Hi, I just came around to this thread from a link in the MDN reference on the logical shorthands. I would be very happy to see 4-value logical properties to be a thing too. After quickly skimming through this interesting discussion, I have one quite elementary question: has anybody proposed a property suffix like *-all (e.g. margin-all, padding-all...) for the logical counterpart?

Obviously I have never been involved in or conducted any deep scrutiny, but wondering if such a naming has whatever kind of known pros and cons.

@Loirooriol
Copy link
Contributor

It has been proposed to add logical shorthands, with names like margin-logical or margins. But the name isn't that important, the main concern against this approach is that it treats logical longhands as 2nd class citizens.

@747
Copy link

747 commented Nov 5, 2023

@Loirooriol Are you sure that the current verdict on the distinct property approach is "2nd class citizens regardless of name"? What I got from the latest log is that "let's try to have a name that doesn't look 2nd class citizen". (Otherwise, it'd sound like margin-block-start looks inferior to margin-top because it is longer... or is it?)

@github-project-automation github-project-automation bot moved this to Thursday Morning in TPAC 2023 agenda Aug 26, 2024
graouts added a commit to graouts/WebKit that referenced this issue Aug 30, 2024
…on test off from css/css-logical/animation-001.html as a dedicated tentative test

https://bugs.webkit.org/show_bug.cgi?id=278910
rdar://135006627

Reviewed by NOBODY (OOPS!).

Given the `logical` keyword for the `margin` shorthand, and other relative shorthands, is not stable yet,
as discussed in w3c/csswg-drafts#1282, we split off the test in
`css/css-logical/animation-001.html` that relies on this feature and make a new test file marked `.tentative`.

* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animation-001-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animation-001.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animations/logical-shorthand-relative-prioritization-by-number-of-components.tentative-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animations/logical-shorthand-relative-prioritization-by-number-of-components.tentative.html: Added.
webkit-commit-queue pushed a commit to graouts/WebKit that referenced this issue Aug 30, 2024
…on test off from css/css-logical/animation-001.html as a dedicated tentative test

https://bugs.webkit.org/show_bug.cgi?id=278910
rdar://135006627

Reviewed by Anne van Kesteren.

Given the `logical` keyword for the `margin` shorthand, and other relative shorthands, is not stable yet,
as discussed in w3c/csswg-drafts#1282, we split off the test in
`css/css-logical/animation-001.html` that relies on this feature and make a new test file marked `.tentative`.

* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animation-001-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animation-001.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animations/logical-shorthand-relative-prioritization-by-number-of-components.tentative-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-logical/animations/logical-shorthand-relative-prioritization-by-number-of-components.tentative.html: Added.

Canonical link: https://commits.webkit.org/282961@main
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-logical] Flow-relative syntax for `margin`-like shorthands.

The full IRC log of that discussion <TabAtkins> florian: my memory of where we're stuck is we had a few proposals for syntax to opt into the flipping, and we were planning to evaluate those on the basis of triaging all properties as being "physical/logical is irrelevant" or "matters, but can go either way". that action has been on me for a long time, and still is
<TabAtkins> florian: I *think* that's where we're stuck
<TabAtkins> addison: I think that's the next. can we get cycles, and will that resolve this issue.
<TabAtkins> florian: I think that step is necessary, whether it's sufficient is fuzzier
<TabAtkins> florian: step doesn't *have* to be done by me. think it's been on me for a year or more
<TabAtkins> addison: at least July '23, yeah
<TabAtkins> astearns: can you outline what the task will detail?
<TabAtkins> astearns: saying "here's what someone needs to do, i'll get to it when I can, but if anyone wants to help here's the steps"
<TabAtkins> florian: I can try
<TabAtkins> astearns: any other suggestions for kicking it off?
<TabAtkins> addison: I think that's core

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-logical-1 Current Work i18n-needs-resolution Issue the Internationalization Group has raised and looks for a response on. Needs Feedback/Review
Projects
Status: Thursday Morning
Development

No branches or pull requests