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 · 36 comments

Comments

Projects
None yet
@fantasai
Copy link
Contributor

fantasai commented Apr 23, 2017

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~

@chharvey

This comment has been minimized.

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

chharvey commented Apr 26, 2017

@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

This comment has been minimized.

Copy link

MurakamiShinyu commented Apr 27, 2017

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

This comment has been minimized.

Copy link

bradkemper commented Apr 27, 2017

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

SebastianZ commented Apr 27, 2017

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

This comment has been minimized.

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

This comment has been minimized.

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:

  • padding-mode
  • border-width-mode
  • border-style-mode
  • border-color-mode
  • border-radius-mode (related: #491)
@MatsPalmgren

This comment has been minimized.

Copy link

MatsPalmgren commented Apr 27, 2017

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

This comment has been minimized.

Copy link

MurakamiShinyu commented Apr 28, 2017

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link

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 fantasai closed this in 1cc3fc2 Apr 30, 2017

@fantasai

This comment has been minimized.

Copy link
Contributor

fantasai commented Apr 30, 2017

Sorry; typo in commit message. :/

@fantasai fantasai reopened this Apr 30, 2017

@chharvey

This comment has been minimized.

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

This comment has been minimized.

Copy link

bradkemper commented May 22, 2017

Weird. My comment was posted to the wrong page

@bradkemper

This comment has been minimized.

Copy link

bradkemper commented Jun 9, 2017

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 changed the title [css-logical] Syntax for `margin`-like shorthands [css-logical] Flow-relative syntax for `margin`-like shorthands Jun 20, 2017

@jonjohnjohnson

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

fantasai commented Aug 17, 2018

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

This comment has been minimized.

Copy link
Contributor

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.

@chharvey

This comment has been minimized.

Copy link

chharvey commented Aug 18, 2018

Ooh, I like @fantasai’s idea of an at-rule.

p { margin: 1em 2em 3em 4em; } /* physical mapping */

@mode (flow-mode: relative) {
  /* everything in here is logical mapping */
  p {
    margin: 1em 2em 3em 4em;
  }
  @mode (flow-mode: physical) {
    /* everything in here is physical mapping */
    blockquote { margin: 1em 2em 3em 4em; }
  }
}
@jonjohnjohnson

This comment has been minimized.

Copy link

jonjohnjohnson commented Aug 18, 2018

I wouldn't be a huge fan of an at-rule solution when I'm already finding it cumbersome/unergonomic to get the most out of my stylesheets when we still haven't landed a leaner solution to conditionals -> #112

@rachelandrew

This comment has been minimized.

Copy link
Contributor

rachelandrew commented Aug 18, 2018

Having done a fair amount of work writing about flow relative CSS recently, I'm a fan of the per declaration !keyword approach to this, plus possibly some way to indicate that the entire stylesheet (or section of the stylesheet) follows flow rules (and the at-rule makes sense here to me).

@astearns

This comment has been minimized.

Copy link
Member

astearns commented Aug 20, 2018

@fantasai should this go on the weekly agenda, since we didn't get to it at the F2F meeting?

@fantasai

This comment has been minimized.

Copy link
Contributor

fantasai commented Aug 27, 2018

@astearns Targetting TPAC for this one. Rossen and I think it's better handled at an F2F, plus we'll have more i18n people available for the discussion there.

@c-smile

This comment has been minimized.

Copy link

c-smile commented Aug 27, 2018

Just in case, how this is made in Sciter:

  1. Sciter is not using logical properties.
  2. Instead I've added mapping property:
margin: 1em 1em 1em 2em;
mapping: left-to-right( margin );

that above is interpreted as

margin: 1em 2em 1em 1em;

left-to-right(...) function accepts list of following keywords: none , inherit, all, margin, padding, border, layout, alignment and image.

Practice shows that development is made almost always in LTR mode. And then RTL is added to existing design this way:

ul:dir(rtl) { mapping: left-to-right( margin ); }
@Loirooriol

This comment has been minimized.

Copy link
Collaborator

Loirooriol commented Oct 23, 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

The problem is that this could be used in stylesheets but not in CSSOM. I prefer a keyword specified as part of the value.

In fact I'm a bit concerned about the CSSOM implications of this thread, which haven't been discussed. Currently the margin shorthand only has the physical longhands, but with this feature margin would also map to the logical longhands.

CSSOM shorthand serialization says

If [...] shorthand cannot exactly represent the values of all the properties in list, return the empty string.

This means that margin could only be serialized if only the physical longhands are set and the logical ones are not (or viceversa). But this doesn't seem much intuitive to me:

element.style.margin = "1px 2px 3px 4px";
element.style.margin = "logical 5px 6px 7px 8px";
element.style.margin; // ""

the first line sets the physical ones, the second line the logical ones, and then the shorthand cannot represent a combination of both and serializes to the empty string. I would expect to get the most recently assigned value.

So maybe element.style.margin = "logical 5px 6px 7px 8px" should remove the previous declarations of the physical longhands? They will be overridden anyway (unless they are important). Or maybe the serialization algorithm should serialize shorthands with both logical and physical longhands if all the logical ones are set and have more precedence than the physical ones (if any), or viceversa.

@css-meeting-bot

This comment has been minimized.

Copy link
Member

css-meeting-bot commented Oct 23, 2018

The CSS Working Group just discussed Flow-relative syntax for 'margin'-like shorthands.

The full IRC log of that discussion <fantasai> Topic: Flow-relative syntax for 'margin'-like shorthands
<emilio> Github: https://github.com//issues/1282
<r12a> s/multiple languages as a single language/multiple languages for a single font/
<emilio> fantasai: currently css assign values in shorthands to the physical longhands
<emilio> fantasai: it seems useful to make logical shorthands similarly convenient, which is useful for i18n
<emilio> fantasai: but we don't have a proposal for which kind of syntax we want to have for this
<emilio> fantasai: one's relative keyword, other is a bang keyword, others is a different property
<astearns> !no
<emilio> fantasai: one of the main restrictions is try to keep it sufficiently easy to type
<dbaron> I would be pretty strongly against a ! syntax for something that's part of the property (i.e., not changing cascading).
<emilio> fantasai: nothing on the thread seems to have stuck
<emilio> fantasai: can we come up with some idea?
<emilio> fantasai: other proposals were like global mode switchs, etc...
<emilio> fantasai: we could do some or multiple
<emilio> fantasai: [enumerates other solutions from the thread]
<emilio> addison: one of the challenges is when you go to make a rtl page layout you need to edit your stylesheet to flip your margins, ideally it'd be default
<myles_> q+
<emilio> TabAtkins: Something in the value space is maybe the best, like keywords
<emilio> TabAtkins: I'd be against punctuation, no precedent and hard to google, plus not compatible with CSSOM
<emilio> TabAtkins: similarly for the bang
<emilio> TabAtkins: nor mode switches, dbaron argued against it, serialization is also harder that way
<emilio> q+
<r12a> q+
<emilio> fantasai: typing relative is too long
<astearns> ack myles_
<dbaron> +1 to tab saying it should be in the regular value space
<emilio> myles_: Will the bang keyword be applicable on every property
<emilio> *?
<iank_> q+
<emilio> fantasai: only to some
<astearns> +1 to dbaron's +1 on regular value space
<dbaron> q+
<emilio> myles_: so part of the grammar of the specific properties, right?
<emilio> fantasai: yes
<emilio> myles_: it'd be cool if it works with variables
<emilio> fantasai: that'd be terrifying
<astearns> ack emilio
<emilio> TabAtkins: you should be able to drop a whole relative margin value in a variable
<TabAtkins> TabAtkins: And you *cannot* put bang values into variables.
<myles_> emilio: expanding shorthand into mulitple lonahands dpeending on syntax, like overflow, is not something that any othe rproperty has righ tnow. So it's goig to require specifying how yous erialize when you have all of th e8 logical and physical margins. IF you want the solution that peoplw ill implement fast, the best option is different properties. Then, all the machinery is there already.
<myles_> fantasai: how do we come up with a systematic way of coming up with a new property that is consistent, short, easy
<myles_> emilio: yes
<myles_> TabAtkins: we do "margin-se"
<myles_> emilio: or "logical-margin"
<myles_> fantasai: it's way too long. some peopl will put all of their stylesheets all of the time, and will stop using physical properties. It needs to be ergonomic enough that it's possible
<dbaron> 'margins', 'paddings' :-P
<myles_> florian: will we push back against tab here about puctuation? ~padding ~margin?
<jensimmons> it might be faster to implement, but if we hate the choice 10 years from now, it’s not a good idea
<myles_> TabAtkins: if its property names, my objection is different. The only thing is that would not be an ident anymore.
<myles_> florian: can we fix it?
<myles_> TabAtkins: potentially but its a syntax change. It would be better for it to fit kn the syntax.
<myles_> florian: if somebody is using a property that uses idents, this would break.
<myles_> TabAtkins: we try to not change syntax
<myles_> florian: this may warrant an exception
<myles_> TabAtkins: yes. I think we can come up with a prefix in alphabumeric that's short
<emilio> astearns: do we have anything more on that?
<astearns> ack r12a
<emilio> r12a: I agree with that fantasai and TabAtkins that it needs to be easy to type, I'd suggest `lmargin`
<jensimmons> q+
<myles_> +1 to not using "relative"
<emilio> r12a: I think `logical` is a much better word than `relative`
<cbiesinger> +1 for not using relative
<astearns> ack iank_
<emilio> iank_: Any of the bang syntax will probably have very funky interactions with CSSOM
<TabAtkins> I think `l` as a prefix works okay. I think we can reasonably prefix any word with that.
<emilio> iank_: setProperty has a different argument for `!important` and such
<astearns> ack dbaron
<fantasai> I don't like prefixing with alphanumeric because it's less obvious what's going on and it won't sort correctly.
<TabAtkins> *post*fixing with `l`?
<fantasai> we use prefixes for the real name of the property, and prefix relationships are about shorthands
<fantasai> postfixing makes it look like a different longhand of the physical shorthand
<astearns> q?
<emilio> dbaron: So I think we all don't like the various bang things. I guess I'm not 100% convinced we want different property names, I think having it in the value would be slightly nicer even if we need to sort out a bunch of CSSOM issues, though it might depend on whether we find appropriate names for the properties
<astearns> ack jensimmons
<emilio> dbaron: different properties is probably faster
<cbiesinger> q+
<emilio> jensimmons: some of the things suggested where the good syntax is the old thing that nobody uses 10 years from now
<emilio> jensimmons: so even if might be more efficient or easier to implement we should peek a name that is a good name
<majidvp> q+
<emilio> heycam: I feel like all of the syntax proposed so far is going to be a bit different and awkward, so I'm not sure the goal of finding a clean word is feasible
<emilio> jensimmons: I think lmargin is a bit more awkward than relative on the value
<dbaron> I guess another option is using a delimiter within the 'margin' value like 1em / 2em / 3em / 4em.
<emilio> jensimmons: Some of them feels smoother than others
<r12a> q+
<rachelandrew> q+
<emilio> fantasai: can you give us your opinion on the different proposal?
<emilio> jensimmons: I think -new is better than a new name, and keyword is better than a bang, but I can look at the list as we goo
<astearns> ack fantasai
<emilio> jensimmons: how does it look in 10 years is something to look into
<TabAtkins> schmlinss
<myles_> jensimmons: sticking a random letter in front of iframe hasn't seemed to hinder its adoption, it seems most people colloquially speak of iframes instead of frames
<emilio> fantasai: prefixing breaks the sort order, margin-something feels like a longhand analogous to margin-left or such
<jensimmons> iMargin? lol
<emilio> fantasai: I'm a little skeptical about prefixing / suffixing has the issue of making it relate to properties it doesn't relate to
<dbaron> q+
<emilio> *seem to relate
<astearns> ack cbiesinger
<TabAtkins> Allowed postfix punctuators in ident syntax: - or _ ^_^
<TabAtkins> margin-, margin_
<myles_> margin: ➡️
<emilio> cbiesinger: I think lmargin and such are a huge concern, we have some other messy margin
<emilio> majidvp: I think mode switch is the easiest. Is the concern about serialization really a problem? When do you have the problem?
<jensimmons> imargin = international margin
<cbiesinger> @mode "logical"; at the top?
<fantasai> cbiesinger, yes that's one option
<emilio> florian: we have some of that problem with box-sizing and such
<fantasai> cbiesinger, the other is a block like @media
<cbiesinger> block seems worse to me
<fantasai> cbiesinger, yeah I agree
<emilio> dbaron: I think we consider it a design mistake
<fantasai> cbiesinger, if we have a mode switch we might want to have a way to put a specific declaration into the other mode, though
<astearns> ack r12a
<emilio> s/it/box-sizing
<astearns> ack majidvp
<fantasai> s/consider it/consider box-sizing/
<emilio> r12a: dbaron proposed separators instead, maybe we should consider that?
<cbiesinger> fantasai: maybe but your escape hatch is margin-left
<astearns> ack rachelandrew
<fantasai> s/fantasai:/fantasai,/
<emilio> rachelandrew: From the POV of teaching this a keyword means that you can look at your code and know what I'm using here, seems to infer the intent best
<emilio> dbaron: I suggested using separators, assuming we do want to move everyone to that, so that you can do something like `margin: 1em / 2em / 3em / 4em`
<emilio> dbaron: It's somewhat obscure so it makes the distinction less obvious, but if it becomes the way to do it it may not be a problem/
<jensimmons> What Rachel just said makes me think that `margin: 10px 5px 15px 25px relative;` is more of a “equal” to `margin` today… changing to a different property infers that it’s a different thing
<emilio> fantasai: we use slashes on some places already, so not sure we could switch everyhwere
<r12a> q+
<astearns> ack dbaron
<emilio> dbaron: it doesn't need to be a slash, there are probably a number of those we haven't used yet
<cbiesinger> +1 for dbaron's suggestion
<emilio> dbaron: the other reason it sort of makes sense to me is that the delimiter indicates a different relationship between the different values
<jensimmons> also, should we go the other way — to match Grid — …. ???? Crazy. but also....
<emilio> myles_: looks like if you don't use slashes code work and it'd look just wrong in RTL
<fantasai> yes, jensimmons, we will go the other way to match Grid
<astearns> ack r12a
<emilio> TabAtkins: Since the direction is different it at least sometimes will look wrong
<fantasai> Grid is using the direction we picked out for logical 4-value syntaxes in general, we just never solved this particular syntax issue to have them :)
<emilio> r12a: So you still have to deal with serialization and such
<emilio> dbaron: yeah, that was emilio's concern, we need to solve that if we handle margins
<fantasai> It's interesting to note that the grid-area shorthand already uses slashes (and is logical)
<emilio> emilio: You also need to handle compressing and serializing when you specify all the 8 margins
<emilio> dbaron: you could condense those to two occurences to the margin shorthand, but it's a bunch of CSSOM work
<rachelandrew> there is an example of individual properties here for padding: https://codepen.io/rachelandrew/pen/OQrorW
<emilio> dbaron: that's the 'this will take longer to get done'
<rachelandrew> from https://www.smashingmagazine.com/2018/03/understanding-logical-properties-values/
<emilio> emilio: note that you also need to figure out how that interacts with the other sub-shorthands like margin-block / margin-inline
<emilio> TabAtkins: yeah I think finding something using property names would be maybe the better idea
<Bert> q+
<emilio> fantasai: I think you still need a switch to change to physical in specific cases, and whatever solution we choose needs to be workable for that
<fantasai> myles_: Mode switch at the top of the file, many CSS authors don't know CSS that well and just copy-paste, so mode switches would end up being problematic for them
<astearns> ack Bert
<emilio> myles_: It's harder for authors to understand mode-switches, and they'll just get it wrong
<fantasai> Bert: Said earlier that it might be a problem if margin expands to different properties based on whether there's a keyword or not. Is that true? Wouldn't it expand to all of them all the time.
<emilio> fantasai: thanks, I had missed it :-)
<fantasai> florian: Depending on the values, they are propagated to different values, but always expand out to the same set of longhands (all of them)
<fantasai> dbaron: At the specified value it is, but at the computed value level, the two sets of properties compute the same values
<fantasai> dbaron: The way we've added logical properties, they are distinct properties at the specified value level nd they both exist in the object model
<fantasai> Bert: If you set margin-start, it goes to margin-start
<fantasai> Bert: If you set 'margin, does it also set margin-start or only go to margin-top
<fantasai> dbaron: We're rying to find a syntax that sets the margin-start property
<fantasai> Bert: Is it necessary?
<fantasai> florian: ...
<fantasai> florian: We don't have a logical shorthand. If we want logical to be the default way to write style sheets, we need that.
<fantasai> astearns: Short answer is no the shrothand doesn't expand to all 8
<fantasai> dbaron: Having the shorthand somehow set margin-top so that it sets the logical thing, could be doable, but would have some very confusing results
<fantasai> florian: I didn't understnad that
<fantasai> Bert: Problem is that the 'margin' property doesn't reset the logical margins. Can that be changed?
<fantasai> Bert: Like font resets font-size-adjust even tough it's not mentioned
<fantasai> fremy: I'm not sure why it doesn't set
<fantasai> fremy: These values would never be used
<fantasai> fremy: It doesn't matter if margin resets them or doesn't
<fantasai> fremy: If the orde rin which you reset them is such that you have the logical ones after the other ones its fine.
<fantasai> dbaron: That would be one solution to part of the object model issues.
<fantasai> dbaron: others around serialization
<fantasai> fremy: Somewhere we have to find principles of doing this, and need algorithm for this
<fantasai> fremy: I ddin't find it yet
<fantasai> dbaron: Might be in a GH issue somewhere
<fantasai> dbaron: probably don't want to dig too far into CSSOM issues right now
<fantasai> astearns: This was a good background on all solutions we could consider, but doesn't sound like we'll resolve today
<fantasai> TabAtkins: Sounds like we're interested in a declaration-based syntax
<TabAtkins> More specific than declaration-level. Property-name or value-level. (So not declaration glyphs, or ! values, etc.)
<florian> fantasai: I think whether or not we need a mode switch, we will have a syntax ???
<myles_> "use logical;"
<myles_> (instead of "use strict")
<emilio> lol
<florian> fantasai: the reason the shorthand resets 4 or 8 of the longhands is actually still an open issue
<florian> s/the reason/whether/
@Dan503

This comment has been minimized.

Copy link

Dan503 commented Oct 29, 2018

This is highly reminiscent of the box-sizing issue where most people by default want to go all in on a particular box sizing mode but want to be able to sometimes switch back to the other mode for things like 3rd party components.

The best practice for handling box-sizing at the moment is this:

*, *::before, *::after { box-sizing: inherit; }
html { box-sizing: border-box; }

People are pretty happy with that syntax and it pretty much solves all the box-sizing use cases.

So based on what we know about how people have implemented box-sizing, I think adding a box-mode: physical | relative; property is best and ensure that it inherits.

That way people can write a CSS reset like this:

html { box-mode: relative; }
.not-relative { box-mode: physical; }

If we expect relative margins and paddings and so on to become the new standard that everyone uses then we should take inspiration from how people use the box-sizing property because it has already walked that path.

Imagine if instead of the box-sizing property, we had to write this on practically every width and height setting:

.example {
  width: 100% !border-box;
  height: 100% !border-box;
}

That would be aweful, you would have hundreds of !border-box all throughout the style sheet.

That's why I think we should have a CSS property that can globally set this for us. Follow the path that box-sizing has already blazed for us. This time it should inherit though. This is so that we have an easy way to make old 3rd party components designed to work with physical margins not break in our new relative margin style sheets. Inheritance means that we wont have to resort to a *, *::before, *::after rule.

@Loirooriol

This comment has been minimized.

Copy link
Collaborator

Loirooriol commented Oct 29, 2018

People are pretty happy with that syntax and it pretty much solves all the box-sizing use cases.

I had problems with that when I added a border to an image, it shrank the image and made it blurry. Also, it's an ugly hack. I prefer a content-box box-sizing by default, and only opt in to border-box when I really want it.

I think adding a box-mode: physical | relative; property is best

I don't think this can really work. The difference is that box-sizing only affects layout, not the cascade.

The logical longhands are different and independent properties from the physical ones. When you have a shorthand, you need to know to which longhands it expands in order to set their specified values. But at that time you don't know the computed value of box-mode yet!

@jonjohnjohnson

This comment has been minimized.

Copy link

jonjohnjohnson commented Oct 30, 2018

Do we think that authors will want to mix physical and logical properties within the same document very often? If not, I'd be frustrated, stuck typing a keyword over and over on all box related shorthand properties for perpetuity.

@Loirooriol As for anything short of having some non-cascading "box mode" solution, why even spec this and have implementors go through the hassle? It wont be any different for authors who will just configure a preprocessor to add the keyword everywhere in shorthands or build out longhands as currently happens. Messier CSSOM, clunky keyword, and more to maintain at no real difference for authors, IMHO.

@jdsteinbach

This comment has been minimized.

Copy link

jdsteinbach commented Nov 3, 2018

Has a new CSS function been considered? This would allow the TRBL shorthand in any property to work (without duplicating all the property names that use the shorthand):

.example {
  margin: logical(1em 2em 20px);
  padding: logical(.5em 1em);
  border-width: logical(0 0 1px 1px);
}
@elad2412

This comment has been minimized.

Copy link

elad2412 commented Nov 30, 2018

I think let's make life easier!
First Idea(use some of the idea of @fantasai and @chharvey ):
add a new property that will declare the type of properties and will have inherit as default.
add now all the page will be according to the html definition.

flow-mode: physical /default value/ or logical;

html{
   flow-mode:physical; 
       /*or*/
   flow-mode:logical;
}

.box{
  /*will be according to the HTML flow-mode value*/
   margin:10px 5px 6px 3px;
  padding:5px 10px 2px 7px;
}

Second Idea:
If I understand if correctly writing-mode is kind of replacing direction.
We can assume if we use writing-mode we want to use all properties as logic properties.

html{
   writing-mode: value;  /*automatically logic properties will work*/
}
@Loirooriol

This comment has been minimized.

Copy link
Collaborator

Loirooriol commented Nov 30, 2018

The problem is that it's bad if you need to know whether the shorthand will expand into physical OR logical longhands at specified-value time, but this depends on the computed value of flow-mode (or writing-mode in your second idea, but this would be too hacky).

However, something similar to https://drafts.csswg.org/css-variables-1/#variables-in-shorthands could be done:

  • The shorthand expands into all physical AND logical longhands (the order does not matter)
  • The specified value of the longhands is set to a special, unobservable to authors "pending-logical-resolution value"
  • This value must then be cascaded as normal
  • At computed-value time, the shorthand must be parsed and the longhands must be given their appropriate values at that point according to the computed value of flow-mode.
  • Pending-logical-resolution values must be serialized as the empty string, if an API allows them to be observed.

It think this would more or less work, but it would be a breaking change:

element.style.margin = "1px 2px 3px 4px";
element.style.marginTop;

Currently it produces "1px", but would become "" because at specified-value time it's not known whether the 1px will be set to margin-top or margin-block-start.

So IMO it would be simpler and less problematic to decide between logical or physical via syntax instead of via the computed value of another property.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment