[css-grid] Stretching image grid items in both dimensions #523

Closed
MatsPalmgren opened this Issue Sep 22, 2016 · 52 comments

Projects

Needs Discussion in css-grid-1

@MatsPalmgren

I'm wondering about how we should stretch grid items that has
an intrinsic ratio, such as images. The Grid spec just refers to
css-align which says:
https://drafts.csswg.org/css-align-3/#justify-self-property
"the stretch keyword sets the box’s used size to the length necessary
to make its outer size as close to filling the alignment container
as possible while still respecting the constraints imposed by
min-height/min-width/max-height/max-width."

which I think means that having 'stretch' in both dimensions
will resize the image to fill the grid area without respecting
the image aspect ratio
. I think this is a rather unfortunate
default behavior for Grid.

Some background; this topic was discussed for flex items here:
https://lists.w3.org/Archives/Public/www-style/2012Oct/0781.html
where everyone seems to agree that respecting the ratio is desirable,
but for various flex layout specific reasons, this could not be
achieved and it was decided to ignore the ratio (IIUC).

As far as I can tell, those reasons do not apply to Grid, so I see
no reason why we can't respect the ratio when stretching grid items
in both dimensions.

I think web authors generally prefer to preserve aspect ratios,
so that's what I think we should do for grid items.

@mrego
Contributor
mrego commented Sep 22, 2016

We were discussing that yesterday at TPAC (@fantasai, @jensimmons and me).
The conclusion we got was that the image should stretch (grow or shrink) in both directions, so we don't respect the aspect ratio unless you manually set width (e.g. width: 100%) or use a different value for alignment (like "start").

@fantasai
Contributor

Well, actually manually setting the width won't cause the aspect ratio to be observed: it just sets the width in that dimension, and since the initial value of align-self is stretch, the other axis will continue to just stretch.

Squishing images seems a little odd, but as a starting point it's useful: the object-fit options are then only one step away, and the alignment options can be used to release the stretch in either or both axes easily.

@fantasai
Contributor

(Plus it's consistent with how blocks behave so not surprising at all.)

@MatsPalmgren
MatsPalmgren commented Sep 22, 2016 edited

@mrego I don't think that solution works, because setting width:100%
might cause the image height to overflow the grid area. So the author
needs to know upfront the relative ratio of each image vs its grid area
to know which dimension to stretch. This is very inconvenient.

My proposal doesn't have that problem.
(and if by chance an author wants a ratio-destroying stretch to fill
its area completely, they can simply use width:100%;height:100%)

@MatsPalmgren

@fantasai, I don't think object-fit:contain works either since
it works on the content box, not the margin box as we want for
grid items. So if you add padding/border/margin to the image it
will cause overflow. Besides, the rule becomes somewhat elaborate
and requiring that authors comes up with workarounds like that for
something that ought to be the default behavior is inconvenient.

@fantasai
Contributor
fantasai commented Sep 23, 2016 edited

Cover example, image proportionally sized and clipped to fit:

  img { object-fit: cover; }

Contain example, margin/border/padding fitted to grid slot and image proportionally sized into it:

  img { object-fit: contain; }

Contain example, margin/border/padding fitted to proportionally scaled-down image:

  img { justify-self: center; align-self: center; min-width: 100%; min-height: 100%; box-sizing: border-box }

Contain example with future syntax, margin/border/padding fitted to proportionally scaled-down image:

  img { foo-self: center; max-size: fill; }
@MatsPalmgren
MatsPalmgren commented Sep 25, 2016 edited

img { object-fit: cover; }

As you say, this leads to the image being clipped and is thus
not a solution to the problem at hand.

img { justify-self: center; align-self: center; min-width: 100%; min-height: 100%; box-sizing: border-box }

This leads to the image overflowing when the window is very wide
or very narrow. Thus it is not a solution to the problem at hand.
(also, having a margin doesn't seem to work?)
I've made a demo here:
https://people.mozilla.org/~mpalmgren/tests/grid/grid-align-center-min-width-demo.html
(Chrome has some problems when resizing this demo)

img { foo-self: center; max-size: fill; }

Suggesting magic future tech to solve this problem isn't serious.
Besides, it still requires that you write the above workaround rule to get
what ought to be the default behavior.

img { object-fit: contain; }

I've made a demo of object-fit:contain here:
https://people.mozilla.org/~mpalmgren/tests/grid/grid-object-fit-contain-demo.html
(Firefox has some problems with this demo at the moment)

I see the following problems:

  1. Like with most object-fit values, it makes the image scale down
    inside its content box. This leads to gaps between the image
    and the border. (Try resizing the window to be very wide or
    very narrow with the demo above.) This leads to ugly layout
    if you try to use a border, box-shadow, outline etc, since users
    expects such decorations to wrap the image.
  2. Since the image doesn't fill the content box, I suspect this
    also leads to other problems... like CSSOM reporting the "wrong"
    image size, the baseline not having any relation with the actual
    image position etc. Visual effects such as opacity, filter etc,
    also applies in the gaps, i.e. "outside" the image proper. I also
    suspect min/max/-width/-height will be awkward to use when
    the image doesn't fill its content box.
  3. It requires using object-fit which I suspect is a lesser known
    property.
  4. It requires adding a rule to get the behavior that really ought
    to be the default: it's preferable if layout preserves the intrinsic
    ratio by default (which some CSSWG members seem to agree
    with in the earlier discussion about flex items).

My proposal doesn't have any of the above problems and it provides
the desired behavior by default.

@dauwhe dauwhe added the css-grid-1 label Sep 26, 2016
@dbaron dbaron added the Agenda+ label Sep 27, 2016
@MatsPalmgren

To be clear, what I'm proposing is that spec says something like this
for the stretch/stretch case:

If the grid item has an intrinsic ratio, then resize the item in a ratio-preserving way
so that it fills its grid area in one axis without overflowing the other, while also
respecting its min/max size constraints.

@dbaron
Contributor
dbaron commented Sep 28, 2016

(It's possible you might want that rule to be conditional on the element having object-fit: fill.)

@cbiesinger

It seems that the proposed text is a bit underdefined in terms of how min and max sizes interact with the "ratio-preserving way". Also I'm not sure that the current definition of min sizes in grid actually allow you to preserve the aspect ratio if the image is too big in both axes and does not have a width or height explicitly specified on the image.

@MatsPalmgren

(It's possible you might want that rule to be conditional on the element having object-fit: fill.)

There are some pros and cons with that, but I don't have a preference.
Either way is fine with me.

@dbaron
Contributor
dbaron commented Oct 5, 2016

It seems that the proposed text is a bit underdefined in terms of how min and max sizes interact with the "ratio-preserving way".

Presumably using the rules in CSS2 section 10.4 that apply to this case.

@dbaron
Contributor
dbaron commented Oct 5, 2016

Just discussed in today's teleconference (I'll try to link minutes later). The conclusion is that we can change the mapping of align-content/justify-content: normal so that normal doesn't turn into stretch for replaced elements in grid.

@MatsPalmgren
MatsPalmgren commented Oct 5, 2016 edited

OK, so normal on images now means "stretch as much as possible (preserving the ratio) without overflowing the grid area" as I requested?

@MatsPalmgren
MatsPalmgren commented Oct 6, 2016 edited

I really like the proposed solution to make normal behave as "stretch-with-preserved-ratio"
for grid items that has an intrinsic ratio. Thanks!
https://lists.w3.org/Archives/Public/www-style/2016Oct/0068.html

Could you please clarify which behavior you want when the *-self value
is normal in one axis and stretch in the other?

I think it should fill the grid area in the axis that has stretch and resize the item in
the other axis according to the ratio, possibly overflowing the grid area in that axis.
Is that correct?

@astearns astearns removed the Agenda+ label Oct 11, 2016
@moz-v2v-gh moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Nov 5, 2016
@MatsPalmgren MatsPalmgren Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
… 'stretch' alignment for grid items with an intrinsic ratio. r=dholbert

w3c/csswg-drafts#523
49f3373
@xeonchen xeonchen pushed a commit to xeonchen/gecko that referenced this issue Nov 5, 2016
@MatsPalmgren MatsPalmgren Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
… 'stretch' alignment for grid items with an intrinsic ratio. r=dholbert

w3c/csswg-drafts#523
9afdc53
@dholbert
Contributor
dholbert commented Nov 8, 2016

Could you please clarify which behavior you want when the *-self value
is normal in one axis and stretch in the other?

I think it should fill the grid area in the axis that has stretch and resize the item in
the other axis according to the ratio, possibly overflowing the grid area in that axis.
Is that correct?

@fantasai / @tabatkins, I think this ^ is a question for you.

Mats' suggestion here makes sense to me, FWIW (and I can't come up with anything that's more sensible).

@KuoE0 KuoE0 pushed a commit to KuoE0/gecko-dev that referenced this issue Nov 10, 2016
@MatsPalmgren MatsPalmgren Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
… 'stretch' alignment for grid items with an intrinsic ratio. r=dholbert

w3c/csswg-drafts#523
dd1a9c6
@freesamael freesamael pushed a commit to freesamael/gecko-dev that referenced this issue Nov 15, 2016
@MatsPalmgren MatsPalmgren Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
… 'stretch' alignment for grid items with an intrinsic ratio. r=dholbert

w3c/csswg-drafts#523
aff3dc7
@fantasai fantasai added a commit that referenced this issue Nov 24, 2016
@fantasai fantasai [css-grid] Make grid items maintain intrinsic ratio in default case per
#523. (First cut, needs review, didn't address object-fit question.)
10aa992
@fantasai
Contributor

Checked in an attempt at fixing this per above discussion. :) Please let me know if anything is askew. I took Mats's suggestion for handling normal+stretch.

Wrt basing on object-fit... On the one hand, I think that would be very handy. On the other, no other layout mode responds to object-fit, so it might be confusing that Grid does. Note that the same effect can be had by specifying place-self: stretch in addition to object-fit: contain or whatever. I'm open to feedback on this issue, though, if anyone has a stronger opinion.

@fantasai
Contributor

Agenda+ for certification of edits and the details wrt normal+stretch / object-fit prior to publication. Looking for review from all three implementation teams, and anyone else who wants to take a look.

@fantasai
Contributor

Oh, just wanted to check that we're all understanding that stretch in one axis and center in another axis preserves the aspect ratio, right?

@MatsPalmgren

No, stretch stretches without preserving the ratio, normal stretches with preserved ratio.

I would summarize what we have implemented as:

  1. place-self:normal normal (default) - stretches the item with preserved intrinsic ratio to fill the grid area in one axis without overflowing the other
  2. place-self:stretch stretch - stretches the item to fill the grid area in both axis (the ratio is not preserved, unless the grid area happens to have the same ratio)
  3. Otherwise, if stretch is one of the values, stretching occurs to fill the grid area in that axis.
    If the value in the other axis is normal it is resized to preserve the ratio (may overflow in that axis)
  4. Otherwise, If normal is one of the values, stretching occurs to fill that axis, the other axis is resized to preserve the ratio (it may overflow in that axis)

IOW, the intrinsic ratio is preserved if at least one of the values is normal.

It gets more complicated when one or both axis also has min-/max-size constraints. I think we're following the CSS2 rules[1] there -- we're re-using the code that already implements that. The stretching occurs before applying those rules.
[1] the "Constraint Violations" table at the end of §10.4:
https://www.w3.org/TR/CSS22/visudet.html#propdef-max-width

Also, when the track max-sizing functions are definite, clamping the item to fit the grid area (per §6.6 in CSS Grid https://drafts.csswg.org/css-grid/#min-size-auto) also affects the above rules (the "may overflow..." above should not be allowed when clamping in that axis IMO, but let's sort out the clamping effect on this in #767)

Here's a couple of testcases to illustrate our stretching behavior (I intentionally
avoided any §6.6 clamping in these tests):
Testcase for growing an image to fill a larger grid area:
https://people-mozilla.org/~mpalmgren/tests/grid/grid-item-image-grow.html
Screenshot of Firefox rendering:
https://people-mozilla.org/~mpalmgren/tests/grid/grid-item-image-grow-firefox.png

Testcase for shrinking an image to fit a smaller grid area:
https://people-mozilla.org/~mpalmgren/tests/grid/grid-item-image-shrink.html
Screenshot of Firefox rendering:
https://people-mozilla.org/~mpalmgren/tests/grid/grid-item-image-shrink-firefox.png

(You need a Nightly build for these tests to display correctly: https://nightly.mozilla.org/ )

@fantasai
Contributor
fantasai commented Nov 27, 2016 edited

OK, so, what I want to point out is that from an authoring point of view, the intrinsic aspect ratio should be preserved unless there's specific instructions not to. Maintaining the intrinsic aspect ratio trumps preserving the intrinsic size in any single dimension. Always. Changing a dimension effectively modifies the user-perceived "intrinsic size" in the other. Internally, we can define terms however we want, but I'm pretty sure that as far as the author is concerned, anywhere that we are failing to do this is an error.

An alignment value of center is definitely not an instruction for auto sizing in that dimension to ignore the aspect ratio. Going back to when we did not have normal... the options for alignment were stretch | start | end | center. And if one axis was stretch and the other center then the aspect ratio would have to be preserved. Only if stretch were specified in both axes would the aspect ratio be ignored: the intention of all non-stretch values of the alignment properties is to do the automatic thing that best preserves the intended presentation of the content, and would use extra space for the specified alignment. Shrink-to-fit sizing, in general, preserves the aspect ratio and Grid + Alignment should behave no different for the values that trigger it.

To address your feedback that the default behavior should be to preserve the aspect ratio, we decided to add an independent behavior for normal so that the initial behavior would not be the skewed result of stretch stretch. So normal normal is defined to be like start start except that the larger dimension is treated as stretch to contain-fit the item within the grid area. This shouldn't, however, cause the aspect ratio to be ignored by the previously-existing value combinations that were intended to honor it.

p.s. Fwiw, I'm a little concerned that the new normal complicates the field of values for the alignment properties by adding yet another sizing value, in particular one that gives a useful behavior but doesn't allow the alignment values to act upon it.

@MatsPalmgren
MatsPalmgren commented Nov 29, 2016 edited

What you are suggesting is that stretch is identical to normal, except for the combination stretch/stretch which ignores the ratio.

That seems a lot less useful to authors, IMHO. As you can see in the testcase:
https://people-mozilla.org/~mpalmgren/tests/grid/grid-item-image-grow.html
making stretch ratio-destroying and normal ratio-preserving gives the author a lot more control over the resizing behavior. And since normal is the default, specifying center or whatever in one axis gives ratio-preserving resizing by default. It's only when the author explicitly specifies stretch that the resizing starts to be ratio-destroying.
Screenshot of Firefox rendering:
https://people-mozilla.org/~mpalmgren/tests/grid/grid-item-image-grow-firefox.png

I think your suggestion is a big mistake and I would like to hear what others think about this before changing our implementation. Web developers in particular.

@yisibl
yisibl commented Dec 1, 2016

I agree with @MatsPalmgren .

In any case, we should not rely on object-fit to solve the<img> aspect ratio problem, because the progress of the implementation of each browser is not the same, in the CSS Grid should have a default solution.

@yisibl
yisibl commented Dec 1, 2016 edited

I think this would be a regular use by developers, centering and preserving the aspect ratio(demo).

image

Equivalent to:

grid > img {
    width: 100%;
    max-height: 100%;
    object-fit: cover;  // or contain
}

And I was surprised to find that Chrome was not in the same height(line-height),inline-flex also has such a problem.

image

@rachelandrew
Contributor

"making stretch ratio-destroying and normal ratio-preserving gives the author a lot more control over the resizing behavior. And since normal is the default, specifying center or whatever in one axis gives ratio-preserving resizing by default. It's only when the author explicitly specifies stretch that the resizing starts to be ratio-destroying."

Yes, this makes sense to me having just re-read this discussion. As an author you don't expect the ratio of an image to be changed unless you specifically request that to happen.

I can see situations occurring where in development test data doesn't highlight the ratio destroying behaviour. However once the site is live and real data is added via a CMS etc. images start to look weirdly stretched. By making the default ratio preserving then in that scenario images might overflow a box or have unwanted gaps but I think that is closer to how authors expect things to behave.

@mrego
Contributor
mrego commented Dec 1, 2016

Just trying to clarify the issue, the part in which there is disagreement is in the difference between normal and stretch.

By default, everything is normal so aspect ratio will be always preserved in that case.

But for stretch there are 2 proposals:

  1. By @fantasai: It always preserves aspect ratio, unless it's set in both axis (align-self and justify-self).
  2. By @MatsPalmgren: It breaks aspect ratio, so it makes a difference between normal and stretch.

Example of both options

Note that if you use justify-self: normal, the behavior is going to be always 1).

Also see the difference in the example above, using the current implementation by Firefox that follows option 2):
Example of normal vs stretch

@rchrdnsh
rchrdnsh commented Dec 1, 2016

I think I support @fantasai's proposal, as I cannot think of any situation where I would want any default behavior to alter the dimensions of an image, unless I explicitly required this, using stretch on both the x and y axis.

As a side note, I would like the ability to choose a focal point on an image that would center the image if the viewport in changed in size in any way smaller than the original image, while preserving the image dimensions and cropping any aspect of the image that falls outside of the viewport. Not sure I'm explaining that too well, though. thegrid.io adversities that it does this, although i have not used it in practice yet.

But anyway, a +1 for @fantasai's suggestion :-)

@MatsPalmgren

I think I support @fantasai's proposal, as I cannot think of any situation where I would want any default behavior to alter the dimensions of an image...

It seems to me you have misunderstood this issue. The default value is normal which means preserving the image ratio is the default behavior, whether you want to stretch just one axis or both. What @fantasai is suggesting is to remove the possibility for you to stretch just one axis without preserving the ratio. I'm saying we should let authors do that when they explicitly ask for it by specifying (the non-default) stretch value. That gives maximum flexibility for authors to control the resizing.

@MatsPalmgren

As a reminder, the current CSSWG resolution is supporting my view on this:

so that is what we will ship in Gecko, unless there is a new CSSWG resolution on the matter that says otherwise.

@fantasai
Contributor
fantasai commented Dec 1, 2016 edited

The resolution was based on a discussion of the value specified in both dimensions.

Prior to the introduction of 'normal' as distinct from 'stretch', it seemed to me quite obvious that specifying "align-axis: center" would not cause distortion, but cause the vertical axis to trigger "shrink to fit" behavior (which preserves the aspect ratio) and use the extra space for centering. I don't see why introducing special behavior for 'normal' -- special behavior whose sole purpose was to solve the default distortion brought on by the 'stretch stretch' combined default, should cause previously-existing combinations to change behavior.

@fantasai
Contributor
fantasai commented Dec 1, 2016

I also want to remind everyone that the purpose of the alignment properties is to manage alignment, not sizing. Stretch is a bit of an anomaly, but it does fit within the description of "specify what to do with the extra space after sizing".

@MatsPalmgren

The resolution was based on a discussion of the value specified in both dimensions.

Fair enough, do you mind bringing it up again in a CSSWG meeting to discuss whether all values involving stretch and normal should be ratio-preserving, with the exception of place-self: stretch stretch? Or if we should give the author the option to control the resizing behavior: stretch for ratio-destroying, normal for ratio-preserving? I'd like to know what the groups' thoughts are explicitly for these cases. (and if the former, what alternatives you recommend to authors). Thanks.

Fwiw, note that Firefox has always implemented ratio-destroying resizing for stretch (even when only specified in one axis) and so does Chrome. I assumed the CSSWG were aware of that in the last discussion. So I raised this issue in that context with the assumption that it should stay ratio-destroying, i.e. "let's make normal ratio-preserving, and stretch stay ratio-destroying".

@fantasai
Contributor
fantasai commented Dec 2, 2016

Sure, I'll bring that up. It didn't even occur to me that the "shrink-to-fit" sizing of the non-stretchy alignment values would be interpreted as aspect-ratio-destroying. (The only reason that 'stretch stretch' distorts the image is because you specifically requested a size: in CSS we otherwise always preserve the aspect ratio on auto-sized images, if we can.)

Agenda+ to decide what happens if stretch or normalis combined with a positional value like start | center | end.

@fantasai fantasai added Agenda+ and removed Agenda+ labels Dec 2, 2016
@jensimmons

I like Mats proposal better.

The default is normal. I switch to stretch in the dimension where the image does not yet fill the space, and I get the result of breaking aspect ratio and having it stretch. If I want to 'fix' the aspect ratio, I can start telling the browser what I want it to do (likely with object-fit). If instead the aspect ratio was maintained, it wouldn't really be clear that the fix (to get the image to stretch to the size of the box) would be to apply stretch in the opposite dimension. That's a level of mastery unexpected. And I can't see being happy with overflow. Maybe I want the image to only stretch in one dimension — and when the grid cells change shape (responsive design), maybe I want the behavior in the other dimension to be different.

@astearns
Contributor

removing agenda+ because we discussed this on the last call and decided to keep the conversation going here.

@astearns astearns removed the Agenda+ label Dec 13, 2016
@fantasai
Contributor

Ok, so Tab and I discussed this today and came up with the following conclusions.

Things to consider:

  1. Authors expect images to maintain their aspect ratio by default.
  2. The effective “intrinsic size” of an image in a given dimension, from an author's point of view, is affected by any sizing constraints placed on it in the other axis. Nowhere in CSS is the original size of the image, independent of those constraints, the output of any automatic sizing algorithm.
  3. align-self and justify-self are defined to be alignment properties, not sizing properties.
  4. In any case, align-self and justify-self should always be able to perform their duty of assigning extra space in order to align the item within its container.

Reasoning:

  1. The previously-agreed solution of having normal do a stretch-while-preserving-aspect-ratio behavior violates classification #3 and requirement #4. (It introduces a different, non-trivial sizing behavior, and prevents the author from controlling the alignment in the axis that has leftover space.)
  2. In order to avoid these violations, normal must behave either exactly as stretch or exactly as start/end/center and not introduce a third sizing behavior. (It can however switch between the two based on some consideration.)

Proposal:

normal behaves as stretch for things without an aspect ratio, and as start for things with an aspect ratio.

  • This keeps the behavior straightforward to reason about, and maintains the aspect ratio as expected.
  • By default images will take their intrinsic size, which is their standard behavior in CSS. This can be further controlled with the sizing properties (width/height and their min/max counterparts) and object-fit as usual.
  • The common responsive-design pattern of giving a large image max-width: 100%; max-height: 100% will work as desired here - aspect ratio is maintained, and it doesn't overflow the grid area.
  • The resulting grid item can be aligned with the alignment properties as expected.

Related improvements that need to be made:

  1. Fix #794 to defer min-content/max-content sizing rules to match CSS2.1 results (as intended).
  2. Finish CSS Sizing 3 so that all of its values can be safely shipped.
  3. If possible, add a size shorthand to width/height to make it easier to specify various useful sizing behaviors such as max-size: fill, which would grant the desired sizing behavior expressed by Mats in this thread. (This is equivalent to the max-width: 100%; max-height: 100% paradigm, except it also works when margins/border/padding are specified.) #820
@fantasai fantasai added the Agenda+ label Dec 19, 2016
@MatsPalmgren

Is Chrome committed to making fill ratio-preserving? It appears -webkit-fill-available currently isn't. Testcase: https://bug1322780.bmoattachments.org/attachment.cgi?id=8820716

@fantasai
Contributor
fantasai commented Jan 4, 2017

@MatsPalmgren fill is not ratio-preserving, and shouldn't be. What's the confusion here?

@MatsPalmgren

Well, I wanted to know to be able to properly critique your current proposal to solve this issue.
(FYI, Firefox and Chrome do in fact try to ratio-preserve images with fill in most cases:
https://people-mozilla.org/~mpalmgren/tests/img-fill.html
Anyway, I guess that's a separate issue.)

It's still not clear to me what the suggested "workaround" is to get the desired behavior. I don't see how max-width:fill; max-height:fill can fix that alone. That only works if the image intrinsic size is larger than the grid area to begin with. How do you get the image to grow to fill the grid area if it's smaller? (in a ratio-preserving way)

@MatsPalmgren

So, to recap, the problem at hand is that stretching images in a ratio-preserving way would fill the grid area in only one axis but (likely) not the other and that an author might want to align (start/center/end) the image in the non-filled axis.

IMHO, this seems like an edge case and a fairly minor problem.

@fantasai's proposal to solve this problem is to not stretch images at all by default. This is a very drastic and invasive change to solve such a minor problem. I think that stretching all grid items to fill their grid area by default is a fundamental part of Grid layout and any proposed solution must preserve that. To single out images to not do that is inconsistent and unexpected.

Also, I think your reasoning is flawed:

  1. align-self and justify-self are defined to be alignment properties, not sizing properties.

Well, there is a stretch keyword that is designed to do sizing and we can't remove that because Flexbox has already shipped with it. (Note also that image flex items stretch non-ratio-preserving by default, which contradicts your points 1/2.)

I agree with:

  1. In any case, align-self andjustify-self should always be able to perform their duty of assigning extra space in order to align the item within its container.

Yes, this is the problem at hand. Let's solve that in a reasonable way without destroying Grid layout completely.

Here's my proposal to solve the align-the-non-filled-axis problem:
Alternative A:
Add new syntax to align/justify-self so you can write:
align-self: normal center
align-self: normal end
Alternative B:
Add new values to align/justify-self so you can write:
align-self: normal-center
align-self: normal-end

The drawback with A is that it is two keywords and thus can't be used with the place-* shorthands. B is slightly ugly, but works as a shorthand value.

I think this solution is much more in proportion to this relatively minor problem.

So, I'd like the CSSWG to reconsider my proposal that image grid items should stretch in a ratio-preserving way by default. Authors will expect all grid items to stretch by default, and as you agree, images are expected to preserve the ratio by default. The remaining alignment problem can be solved by adding some minor CSS Box Alignment feature as I suggested above (there are likely other Align solutions too).

@mrego
Contributor
mrego commented Jan 10, 2017

I also believe that this proposal has some issues:

  • Not stretching images by default when the rest of grid items stretch by default is strange.
    One option could be that normal is stretch like for the rest of items. This would break aspect-ratio but it's consistent with what already happens in Flexbox and the rest of grid items.

  • The proposed solution (max-size: 100%) only works for images bigger than the grid area, but not for stretching smaller images to fill the grid area. Maybe that's enough though.

@MatsPalmgren

@mrego Regarding Flexbox - see my original comment at the top. The CSSWG actually agreed at the time that it's undesirable to stretch images without preserving ratio, but there were some other issues in Flexbox that made it impossible to implement that. Those issues don't apply to Grid, which is why I think we can and should implement the optimal behavior here.

@MatsPalmgren

@fantasai I have already thoroughly debunked the myth that object-fit is a solution so I don't understand why you bring that up again: #523 (comment)
Please read that comment again carefully.

@astearns astearns removed the Agenda+ label Jan 24, 2017
@astearns
Contributor

Since we discussed this in Seattle I'm assuming it doesn't need to be on the agenda again so soon.

@fantasai
Contributor

The CSSWG discussed this issue again, and stands by the conclusion in #523 (comment) This ensures that the alignment properties do not devolve further into sizing controls, and that behavior in grid is consistent with behavior in block layout, etc. We will however add a contain value to the width and height properties to make sure that the use cases for fitting a grid cell are easily handled.

@MatsPalmgren Wrt #523 (comment) I listed object-fit alongside other things, because in some cases is does solve the problem.

@fantasai fantasai closed this Jan 24, 2017
@triple-underscore triple-underscore added a commit to triple-underscore/triple-underscore.github.io that referenced this issue Jan 25, 2017
@triple-underscore triple-underscore [css-grid][css-align] Address latest conclusions on w3c/csswg-drafts#523
 . w3c/csswg-drafts@f4ca22f

+[css-grid] Fix typos.
w3c/csswg-drafts@82de6db
071b0796aa0
d0e4c06
@MatsPalmgren

The CSSWG discussed this issue again, and stands by the conclusion in #523 (comment)

That's not what the CSWG actually decided according to the IRC log at https://log.csswg.org/irc.w3.org/css/2017-01-13/#e761792

Rossen: ok, any objections to resolve on option number #1: no change to the default sizing, non replace get stretched, replaced gets start and add new sizing keywords to address the issues 11:46:21 PST

@fantasai's proposal above says "things with an aspect ratio" should use start.
As I understand it, the CSSWG resolution is that replaced elements in general (including those without an intrinsic aspect ratio) should use start. Can someone who was at the meeting, and who is not fantasai, confirm that this is what the CSSWG resolved on please? (and if I misunderstood, please explain in detail what was actually decided)

@fantasai fantasai added the Agenda+ label Feb 1, 2017
@tabatkins
Member

We actually did mean "things with an aspect ratio" - this was very clear from the discussion in-person, but didn't make it into the minutes very well. (Not helped by our continued use of "replaced element" as the term.)

So we'll need the WG to amend the resolution to clarify that it was about things with an aspect ratio.

Additionally, we then need to verify what behavior we want for replaced elements without aspect ratios. In particular:

  1. An image with no intrinsic dimensions. I presume we want to stretch this.
  2. An image with one intrinsic dimension. We probably want to stretch the "free" axis, but do we stretch the intrinsic axis or leave it as specified and start-align it?
@MatsPalmgren

Fwiw, I agree that an intrinsic size should also make normal be treated as start in that dimension. I see no reason why <input> should stretch to fill its grid area by default now that images don't, for example.

@FremyCompany
Contributor
FremyCompany commented Feb 3, 2017 edited

Adding myself to the conversation since it seems we might change the spec again.

Also, here is a test case:

image image image
https://jsfiddle.net/1fd948nz/ (Edge, Chrome, Firefox)

@FremyCompany FremyCompany reopened this Feb 3, 2017
@FremyCompany
Contributor

Also variant https://jsfiddle.net/1fd948nz/1/
None of existing browsers would be the per-resolution expected behavior for those two tests, right?

@astearns
Contributor

We amended the Seattle resolution on the call today:
RESOLVED: The sentence beginning with "Items without an intrinsic ratio use," is what we as a WG wanted to use
and clarified what should happen for things without aspect ratios:
RESOLVED: replaced elements with only one intrinisic size are sized as start in that dimension and stretch in the other

@astearns astearns removed the Agenda+ label Feb 15, 2017
@tabatkins tabatkins added a commit that referenced this issue Feb 23, 2017
@tabatkins tabatkins [css-grid] Rephrase the grid item sizing rules to be readable, and pr…
…operly capture the resolutions in #523.
98893bc
@tabatkins tabatkins closed this Feb 23, 2017
@fantasai
Contributor

Initial draft of contain is now in https://drafts.csswg.org/css-sizing/#contain-fit-sizing ; comments welcome (though please not in this thread ;)

@triple-underscore triple-underscore added a commit to triple-underscore/triple-underscore.github.io that referenced this issue Feb 25, 2017
@triple-underscore triple-underscore [css-grid] w3c/csswg-drafts@98893bc Rephrase the grid item sizing rul…
…es to be readable, and properly capture the resolutions in w3c/csswg-drafts#523
2821c88
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment