You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-grid] Stretching image grid items in both dimensions #523
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.
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").
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.
@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%)
@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.
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.
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.
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.
It requires using object-fit which I suspect is a lesser known
property.
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.
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.
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.
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.
The CSS Working Group just discussed Stretching image grid items in both dimensions.
The full IRC log of that discussion
<dael> Topic: Stretching image grid items in both dimensions
<dael> Github Topic: https://github.com//issues/523#issuecomment-295075752
<dael> Rossen: I don't see fantasai yet.
<zcorpan> Github Topic: https://github.com//issues/523
<dael> Rossen: Anyone from Mozilla want to handle this? Or do we move on? Current tag is customer not satisfied.
<dael> TabAtkins: We should wait on fantasai because she might have more to the topic to explore.
The CSS Working Group just discussed Stretching image grid items in both dimensions, and agreed to the following resolutions:
RESOLVED: ticking with Seattle resolution: making the default instrinsic
The full IRC log of that discussion
<dael> Topic: Stretching image grid items in both dimensions
<TabAtkins> Yeah, I think that's probably the best error, zcorpan
<dael> Github topic: https://github.com//issues/523
<dael> fantasai: In seattle we had three options. One we wouldn't take b/c violates design guidelines. Other two we would have contain & intrinsic size behavior. You could opt into either. We picked intrinsic for the default. There's details in https://github.com//issues/523#issuecomment-295075752
<dael> fantasai: We closed that, but Mats disagrees with the resolution. All other issues on Grid are closed as of when we stopped accepting issues.
<dael> fantasai: This issue has a commentor disagreement so comes back to WG. Do we stick or do we change to contain sizing by default and opt-in for intrinsic via keyword-max-content or something like that.
<dael> Rossen: Opinions?
<dael> jensimmons: My opinion is I agree #3 should not be considered. I'd be okay with leave as-is, but I agree with Mats that as an author having the default be contain would be more handy and make more sense. We need both as an option and the tool to switch definitely. The default I'd lean contain.
<dael> TabAtkins: Reason why we didn't go for contain is it puts sizing control in this prop...
<dael> fantasai: TabAtkins we changed.
<dael> jensimmons: That was 3 which we agreed not to do
<dael> fantasai: Option was default is contian on all keywords, not jsut normal.
<tantek> do we have comments from anyone else who is actually implementing this besides Mats?
<tantek> reviews the issue
<dael> jensimmons: Ideally we would have tool to switch between, but the wayt he world works if we set default to contain we would get the switching tools quicker. Not certainly, but might.
<rachelandrew> I'm still keen on the resolution
<dael> Rossen: But forcing a less then optimal default as a forcing tool i sn't doing much good.
<tantek> long issue is long
<dael> jensimmons: Agreed. I still like contain as a default. That's a secondary non-heavy
<dael> TabAtkins: I'm concerned that when we have contain sizing....having different defaults based on layout of parent it makes the design confusing. It's better if we have consistancy.
<dael> jensimmons: [missed]
<Rossen> +1 to what Tab said
<dael> fantasai: Flexbox resizes to fit hte container. It does only do that with a single line. If you have wrapping it takes intrinisic
<dael> TabAtkins: It obeys constraint of flexbox and a bit of aspect ratio magic. The sizing is normal flexbox, not just images.
<dael> jensimmons: You can make the same arguments here.
<dael> TabAtkins: I disagree. Part of flex is doing this one thing. We're not adding a different way of sizing.
<dael> jensimmons: I think from author prospective there would be something similar to having default of flexbox where they are both text and image contained. If there's an image just left with intrinisic size it starts to overflow and that's not typically what authors want. Authors expect content to stay in grid cells.
<tantek> "won't spill outside" e.g. the [CSS is Awe]some problem
<dael> fantasai: Things that are smaller then grid size, contain will cause them to size up.
<dael> rachelandrew: I don't like the upscalling. I like the original resolution b/c i t's the most consistant and easier to explain. the upscalling will cause problems.
<tantek> didn't follow Rachel's comment
<gregwhitworth> +1 to TabAtkins rachelandrew
<dael> fantasai: Another thing to consider is grid is being deployed and we don't have a definition of contains that WG approved. Changing will c ause impl stress.
<dael> TabAtkins: Adding that, even if we had a contain definition, it's still transition stress because it's shipped without this. They're getting things to look well and then this change will break pages.
<dael> fantasai: I would say if it was significantly better thing to do it might be worth doing, but since we're debating and there's good for both sides, given the status we're at it makes sense to go with intrinsic a nd add the contain keyword. That would be my position.
<dael> TabAtkins: I agree.
<rachelandrew> +1 to fantasai
<dael> fantasai: I'm sympathetic, but it's not so clearly better that it's definitely the right answer.
<dael> TabAtkins: I would also threat it differently if it was obvious fix instead of possibly better.
<dael> Rossen: I'm seeing people favor option 1. Let's try for resolution.
<dael> Rossen: Unless jensimmons you feel there's something else you want to add.
<dael> jensimmons: I don't want to block it, but I think we need to define contain.
<dael> fantasai: We have a definition, we need comments. THere is a definition in sizing 4. Mostly waiting for dbaron and Mats there.
<dael> jensimmons: We should keep going forward on getting that done b/c it's desperately needed.
<dael> dbaron: Does option 1 match what impl ship today?
<dael> Rossen: I believe so.
<dael> tantek: It does.
<dael> s/tantek/ TabAtkins
<dael> jensimmons: I'm curious about that. I'm not sure what Mats impl and he did Gecko.
<dael> TabAtkins: I'd hope he's not impl something different. Even if he is, the other browsers aren't.
<dael> dbaron: I would disagree with TabAtkins' hope. But I don't know what he did.
<tantek> this issue feels like it has many aspects, are there at least some aspects we can converge on?
<dael> Rossen: Let's go back to this. Sincec Mats' isn't here I'd liket o call for consensus on #1. We'll continue working on contain.
<tantek> I'm having trouble keeping track of n resolutions over the past on this and n options
<dael> Rossen: Obj to sticking with Seattle resolution: making the default instrinsic?
<fantasai> testcase -
<jensimmons> we don’t have interop on https://jsfiddle.net/1fd948nz/1/ at the moment, fyi
<dael> RESOLVED: ticking with Seattle resolution: making the default instrinsic
Was just tech-editing someone's introduction to Grid Layout and noticed her description of the default alignment behavior for grid: it's stretching unless there's a specified size, in which case it's start. Having replaced elements behave as start by default matches this -- technically they don't have a “specified” size, but the intrinsic size stands in for that specified size, yielding consistent behavior for items that have a concrete size. I think this behavior makes sense and is understandable for authors.
Activity
mrego commentedon 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 commentedon Sep 22, 2016
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-fitoptions are then only one step away, and the alignment options can be used to release thestretchin either or both axes easily.fantasai commentedon Sep 22, 2016
(Plus it's consistent with how blocks behave so not surprising at all.)
MatsPalmgren commentedon Sep 22, 2016
@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 commentedon Sep 22, 2016
@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 commentedon Sep 23, 2016
Cover example, image proportionally sized and clipped to fit:
Contain example, margin/border/padding fitted to grid slot and image proportionally sized into it:
Contain example, margin/border/padding fitted to proportionally scaled-down image:
Contain example with future syntax, margin/border/padding fitted to proportionally scaled-down image:
MatsPalmgren commentedon Sep 25, 2016
As you say, this leads to the image being clipped and is thus
not a solution to the problem at hand.
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)
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.
I've made a demo of
object-fit:containhere: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:
object-fitvalues, it makes the image scale downinside 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,outlineetc, since usersexpects such decorations to wrap the image.
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,filteretc,also applies in the gaps, i.e. "outside" the image proper. I also
suspect
min/max/-width/-heightwill be awkward to use whenthe image doesn't fill its content box.
object-fitwhich I suspect is a lesser knownproperty.
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.
MatsPalmgren commentedon Sep 27, 2016
To be clear, what I'm proposing is that spec says something like this
for the stretch/stretch case:
dbaron commentedon Sep 28, 2016
(It's possible you might want that rule to be conditional on the element having
object-fit: fill.)cbiesinger commentedon Sep 28, 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". 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 commentedon Sep 30, 2016
There are some pros and cons with that, but I don't have a preference.
Either way is fine with me.
dbaron commentedon Oct 5, 2016
Presumably using the rules in CSS2 section 10.4 that apply to this case.
dbaron commentedon 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: normalso thatnormaldoesn't turn intostretchfor replaced elements in grid.72 remaining items
css-meeting-bot commentedon May 10, 2017
The CSS Working Group just discussed
Stretching image grid items in both dimensions.The full IRC log of that discussion
<dael> Topic: Stretching image grid items in both dimensions<dael> Github Topic: https://github.com//issues/523#issuecomment-295075752
<dael> Rossen: I don't see fantasai yet.
<zcorpan> Github Topic: https://github.com//issues/523
<dael> Rossen: Anyone from Mozilla want to handle this? Or do we move on? Current tag is customer not satisfied.
<dael> TabAtkins: We should wait on fantasai because she might have more to the topic to explore.
css-meeting-bot commentedon May 10, 2017
The CSS Working Group just discussed
Stretching image grid items in both dimensions, and agreed to the following resolutions:RESOLVED: ticking with Seattle resolution: making the default instrinsicThe full IRC log of that discussion
<dael> Topic: Stretching image grid items in both dimensions<TabAtkins> Yeah, I think that's probably the best error, zcorpan
<dael> Github topic: https://github.com//issues/523
<dael> fantasai: In seattle we had three options. One we wouldn't take b/c violates design guidelines. Other two we would have contain & intrinsic size behavior. You could opt into either. We picked intrinsic for the default. There's details in https://github.com//issues/523#issuecomment-295075752
<dael> fantasai: We closed that, but Mats disagrees with the resolution. All other issues on Grid are closed as of when we stopped accepting issues.
<dael> fantasai: This issue has a commentor disagreement so comes back to WG. Do we stick or do we change to contain sizing by default and opt-in for intrinsic via keyword-max-content or something like that.
<dael> Rossen: Opinions?
<dael> jensimmons: My opinion is I agree #3 should not be considered. I'd be okay with leave as-is, but I agree with Mats that as an author having the default be contain would be more handy and make more sense. We need both as an option and the tool to switch definitely. The default I'd lean contain.
<dael> TabAtkins: Reason why we didn't go for contain is it puts sizing control in this prop...
<dael> fantasai: TabAtkins we changed.
<dael> jensimmons: That was 3 which we agreed not to do
<dael> fantasai: Option was default is contian on all keywords, not jsut normal.
<tantek> do we have comments from anyone else who is actually implementing this besides Mats?
<tantek> reviews the issue
<dael> jensimmons: Ideally we would have tool to switch between, but the wayt he world works if we set default to contain we would get the switching tools quicker. Not certainly, but might.
<rachelandrew> I'm still keen on the resolution
<dael> Rossen: But forcing a less then optimal default as a forcing tool i sn't doing much good.
<tantek> long issue is long
<dael> jensimmons: Agreed. I still like contain as a default. That's a secondary non-heavy
<dael> TabAtkins: I'm concerned that when we have contain sizing....having different defaults based on layout of parent it makes the design confusing. It's better if we have consistancy.
<dael> jensimmons: [missed]
<Rossen> +1 to what Tab said
<dael> fantasai: Flexbox resizes to fit hte container. It does only do that with a single line. If you have wrapping it takes intrinisic
<dael> TabAtkins: It obeys constraint of flexbox and a bit of aspect ratio magic. The sizing is normal flexbox, not just images.
<dael> jensimmons: You can make the same arguments here.
<dael> TabAtkins: I disagree. Part of flex is doing this one thing. We're not adding a different way of sizing.
<dael> jensimmons: I think from author prospective there would be something similar to having default of flexbox where they are both text and image contained. If there's an image just left with intrinisic size it starts to overflow and that's not typically what authors want. Authors expect content to stay in grid cells.
<tantek> "won't spill outside" e.g. the [CSS is Awe]some problem
<dael> fantasai: Things that are smaller then grid size, contain will cause them to size up.
<dael> rachelandrew: I don't like the upscalling. I like the original resolution b/c i t's the most consistant and easier to explain. the upscalling will cause problems.
<tantek> didn't follow Rachel's comment
<gregwhitworth> +1 to TabAtkins rachelandrew
<dael> fantasai: Another thing to consider is grid is being deployed and we don't have a definition of contains that WG approved. Changing will c ause impl stress.
<dael> TabAtkins: Adding that, even if we had a contain definition, it's still transition stress because it's shipped without this. They're getting things to look well and then this change will break pages.
<dael> fantasai: I would say if it was significantly better thing to do it might be worth doing, but since we're debating and there's good for both sides, given the status we're at it makes sense to go with intrinsic a nd add the contain keyword. That would be my position.
<dael> TabAtkins: I agree.
<rachelandrew> +1 to fantasai
<dael> fantasai: I'm sympathetic, but it's not so clearly better that it's definitely the right answer.
<dael> TabAtkins: I would also threat it differently if it was obvious fix instead of possibly better.
<dael> Rossen: I'm seeing people favor option 1. Let's try for resolution.
<dael> Rossen: Unless jensimmons you feel there's something else you want to add.
<dael> jensimmons: I don't want to block it, but I think we need to define contain.
<dael> fantasai: We have a definition, we need comments. THere is a definition in sizing 4. Mostly waiting for dbaron and Mats there.
<dael> jensimmons: We should keep going forward on getting that done b/c it's desperately needed.
<dael> dbaron: Does option 1 match what impl ship today?
<dael> Rossen: I believe so.
<dael> tantek: It does.
<dael> s/tantek/ TabAtkins
<dael> jensimmons: I'm curious about that. I'm not sure what Mats impl and he did Gecko.
<dael> TabAtkins: I'd hope he's not impl something different. Even if he is, the other browsers aren't.
<dael> dbaron: I would disagree with TabAtkins' hope. But I don't know what he did.
<tantek> this issue feels like it has many aspects, are there at least some aspects we can converge on?
<dael> Rossen: Let's go back to this. Sincec Mats' isn't here I'd liket o call for consensus on #1. We'll continue working on contain.
<tantek> I'm having trouble keeping track of n resolutions over the past on this and n options
<dael> Rossen: Obj to sticking with Seattle resolution: making the default instrinsic?
<fantasai> testcase -
<jensimmons> we don’t have interop on https://jsfiddle.net/1fd948nz/1/ at the moment, fyi
<dael> RESOLVED: ticking with Seattle resolution: making the default instrinsic
atanassov commentedon May 10, 2017
Test case for the above discussion added by fantasai:
https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=5143
fantasai commentedon Dec 4, 2017
Was just tech-editing someone's introduction to Grid Layout and noticed her description of the default alignment behavior for grid: it's stretching unless there's a specified size, in which case it's start. Having replaced elements behave as start by default matches this -- technically they don't have a “specified” size, but the intrinsic size stands in for that specified size, yielding consistent behavior for items that have a concrete size. I think this behavior makes sense and is understandable for authors.
Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
Merge pull request #523 from cdoublev/pr-523
Merge pull request #523 from cdoublev/pr-523
Merge pull request #523 from cdoublev/pr-523
Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…
Bug 1218178 part 3 - [css-grid][css-align] Implement ratio-preserving…