Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-grid] aspect ratio units needed #1173

Open
jensimmons opened this issue Apr 5, 2017 · 35 comments
Open

[css-grid] aspect ratio units needed #1173

jensimmons opened this issue Apr 5, 2017 · 35 comments
Labels
css-grid-3 Masonry Layout

Comments

@jensimmons
Copy link
Contributor

I know there has been discussion of aspect ratio units in the past.

We need them. Badly.

Especially with CSS Grid.

Why? When? So — there are many usecases where an Author wants to maintain a specific aspect ratio in their Grid cells. They want every cell to be 4x3 or to be a square.

For example in order to make every cell a square, maybe the browser looks at both min-content dimensions (or both results of auto) — and keeps the longer of the two. Then makes the shorter of the two into the same length as the longer.

Or a similar thing to keep 4x3, or keep 16x9.

I have not had a chance to read the proposed specs. Or code up demos. I just know this comes up over and over and over. I just had yet another person ask me how to do this, and all I can say is "use viewport units and a ton of media queries". We need something better.

@keithjgrant
Copy link
Contributor

I agree. It’s do-able with existing CSS, but it’s a kludge: http://keithjgrant.com/posts/2017/03/aspect-ratios/

@keithjgrant
Copy link
Contributor

…as that post points out, overflow issues can get interesting. What do you do when the width is constrained, but the contents need more space than the aspect ratio would allow for? Should an aspect ratio rule be allowed to force the width wider?

@Crissov
Copy link
Contributor

Crissov commented Apr 6, 2017

Why would you want to solve this with units?

@frivoal
Copy link
Collaborator

frivoal commented Apr 6, 2017

There as some discussion of making the svg viewbox apply to css as well. w3c/fxtf-drafts#7

Depending on how it ends up working, you could maybe do things like this:

.grid-item {  view-box: 0 0 16 9; }

Then width: 160px; height: auto; would give you a height of 90px, and so on.

@fantasai
Copy link
Collaborator

I think this is technically a duplicate of #333?

@fantasai fantasai added css-values-4 Current Work and removed css-values-3 labels May 17, 2017
@fantasai
Copy link
Collaborator

After some discussion with @jensimmons, I think the best solution here is to have an aspect-ratio property for the general case. For Grid, we do need a special unit because grid cells don't have properties, but it can be restricted to grid-template syntax the way fr units are.

@fantasai fantasai added css-grid-2 Subgrid; Current Work and removed css-values-4 Current Work labels May 17, 2017
@rachelandrew
Copy link
Contributor

Here is a useful roundup of current aspect ratio attempts by authors.

https://www.bram.us/2017/06/16/aspect-ratios-in-css-are-a-hack/

@fantasai
Copy link
Collaborator

fantasai commented Nov 6, 2017

So, I was just thinking about this again and the problem is this: I have two columns of different widths (say 100px and 200px), and then one row indicating it wants an aspect ratio of 1:1. How tall is the row?

@tremby
Copy link

tremby commented Dec 15, 2017

@keithjgrant said

I agree. It’s do-able with existing CSS, but it’s a kludge: http://keithjgrant.com/posts/2017/03/aspect-ratios/

Unfortunately this doesn't work all the time. I am having it fail on me for example when I want my cell to be square or taller, and inside this cell I want a flex which fills the full height, for vertical spacing-out of its children. Firefox is happy but Chrome is not (100% height seems to mean nothing to it in this context), and I've had to fall back to the vertical padding hack, with an absolutely-positioned content container. But this way, the content can't grow the cell if it's too long.

@myakura myakura changed the title [css-units] aspect ratio units needed [css-grid] aspect ratio units needed Dec 15, 2017
@frivoal
Copy link
Collaborator

frivoal commented Feb 2, 2018

@fantasai @jensimmons @rachelandrew

So, I was just thinking about this again and the problem is this: I have two columns of different widths (say 100px and 200px), and then one row indicating it wants an aspect ratio of 1:1. How tall is the row?

I've been wondering about that too. How about saying that the aspect ratio of rows is calculated from the size of implicit columns (and vice versa) if they're sized to a <length-percentage> or to a <flex>, (i.e. something that always resolves to the same size, not auto, min-content, max-content...), or to auto otherwise?

Suggested syntax: allow <number> as a <track-size>, similarly to how we're using <number> for aspect ratio in gutters.

container {
  display: grid;
  grid-auto-columns: 1fr;
  grid-template-rows: repeat(3, minmax(1.0, auto));
}

You get 3 rows and n columns depending on content. All the columns are the same width, and the height of each row is at least the same as the width of the columns, or more if the content wouldn't fit, with each row growing individually. To get all rows to grow together, change to:

container {
  display: grid;
  grid-auto-columns: 1fr;
  grid-template-rows: repeat(3, minmax(1.0, 1fr));
}

If you want to fix the number of columns instead of rows, but keep the same aspect ratio logic:

container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-columns: 1fr;
  grid-auto-rows:  minmax(1.0, auto); /* or minmax(1.0, auto), depending */
}

@frivoal
Copy link
Collaborator

frivoal commented Feb 2, 2018

Alternatively, call it out explicitly

track-size = /* curent syntax*/ | aspect-ratio( <number>  <grid-line> [ / <grid-line> ]?)
container {
  display: grid;
  grid-template-columns: 100px 50px 300px;
  grid-auto-rows: aspect-ratio(1.0 1 / 3); /* 1 * (100px + 50px) = 150px */ 
}

@fantasai
Copy link
Collaborator

fantasai commented Feb 6, 2018

Looking back over @jensimmons' comments in #333, I'm going to suggest that we a) have an aspect-ratio property, as proposed earlier, to give individual items an aspect ratio, which can then be transferred to the grid track via auto sizing b) use ar units to mean a multiple of 1fr in the other axis. This seems like it would cover most cases, but it'd be good to hear from @jensimmons and @rachelandrew if there's other cases that are commonly needed.

@frivoal
Copy link
Collaborator

frivoal commented Feb 7, 2018

an aspect-ratio property, as proposed earlier, to give individual items an aspect ratio

Would that cover minimum aspect ratio as well? meaning that the element maintains the aspect ratio if it is underfilled, but that it does grow rather than overflow if there's too much content?

Assuming it solves that, I'm not necessarily opposed to the idea, but I think we should resume exploring w3c/fxtf-drafts#7 before we lock in on that, because it seemed that that approach could give us aspect ratio control (and more) as well.

use ar units to mean a multiple of 1fr in the other axis

That sounds reasonable. I wonder how it compares to the aspect-ratio() function I suggested in #1173 (comment) in various use cases. Your syntax is much simpler and probably hits the number 1 use case, mine allows for being explicit about what you want to calculate the ratio from. If that's not useful, then my syntax is overkill, but if that is, maybe it's worth it.

@tobireif
Copy link

Another aspect ratio ticket:
By @fantasai from July 20 2016: #333

In that ticket, @ewanm89 suggested this:

height: 100ew; to make something square

@tobireif
Copy link

(Where "ew" stands for element width percentage.)

@tabatkins tabatkins added css-grid-3 Masonry Layout and removed css-grid-2 Subgrid; Current Work labels Apr 30, 2018
@tobireif
Copy link

tobireif commented May 1, 2018

I hope this would apply to Flexbox as well (I recently needed always-square cells in Flexbox layout).

Should there be a Flexbox label in addition to the Grid label?

@tobireif
Copy link

tobireif commented May 4, 2018

I hope we'll soon get a solution, there even is a website generating a hack:
http://ratiobuddy.com/

@ewanm89
Copy link

ewanm89 commented May 4, 2018

yeah, old padding hack is fairly well known, and litters the code with extra divs while taking the content out of the page flow with a position absolute, very fair from a good solution.

@tobireif
Copy link

tobireif commented May 4, 2018

Some versions of the hack don't require a wrapper element

But they're all hacks.

Looking forward to having a nice native solution ...

@Dan503
Copy link

Dan503 commented Aug 22, 2018

If there is going to be an aspect-ratio property then there also needs to be min-aspect-ratio and max-aspect-ratio properties. I see myself using max-aspect-ratio ("max" meaning it can grow relatively taller but not wider) far more than I would use aspect-ratio.

There are min and max aspect ratios for media queries, they should be modeled after those values.

Without min and max versions it becomes difficult to manage text that doesn't fit inside the normal aspect ratio.

@tobireif
Copy link

If there is going to be an aspect-ratio property then there also needs to be min-aspect-ratio and max-aspect-ratio properties.

No need for more two properties, the min and max could be part of the value

Also perhaps both the aspect ratio and the min & max could be part of the value (as opposed to a new property).

Also see all "minmax" in the above comments.

@jensimmons
Copy link
Contributor Author

I wrote a bit about this on Twitter, and got a bunch of responses from web developers: https://twitter.com/jensimmons/status/1053004310840266752

There have been some blog posts written by developers, articulating their desires. Here are two:
https://blog.frankmtaylor.com/2018/07/20/when-properties-compete-how-css-sets-dimensions/
https://www.sarasoueidan.com/blog/svg-art-direction-using-viewbox/

I believe there's more in the Responsive Images Community Group / other Community Group discussions. I plan to read through that stuff to see what other needs might be articulated to make sure we are meeting them. And to look for words to possibly use when bike shedding names.

@Archibald2
Copy link

Instead of introducing the 'ar' unit which can relate height to width or relate width to height, code would be easier to read if 'w' is used for width and 'h' is used for height. So for example;

div {
  min-height: 1w;
}
article {
 max-width: 1.5h
}

@nhoizey
Copy link
Contributor

nhoizey commented Oct 23, 2018

Like I said in #333 (why are both still open?):

@Archibald2 I see developers already struggle with w as a CSS pixel based width descriptor in srcset and vw as a viewport relative width in sizes, so I'm not sure using w here would help them, even if one is in HTML and the other in CSS. I also still hope to get width descriptors (probably with w) in CSS Images Module Level 4.

@Dan503
Copy link

Dan503 commented Nov 1, 2018

To everyone saying that they want %w and %h units:

The new unit is being locked down to CSS Grid like the fr unit is.

%w and %h, though awesome and I really want them myself, opens up huge cans of worms like "I want to use %w and %h to set font size!" Which (though so totally would be awesome) is about the biggest can of worms you can possibly open!

The bigger the can of worms that gets opened the longer it takes for the new CSS to land in browsers.

As for those wondering why #333 is still open, they are different issues.

#333 is meant to be focused on adding a new aspect-ratio property that can be used more generically across CSS. This issue is focused on adding a CSS Grid only tr unit so that grid template rows and columns can be sized based on an length transfer rate.

It's not one or the other, they are planning on adding both features to CSS.

@Dan503
Copy link

Dan503 commented Nov 1, 2018

From #333 (comment):

If you wanted to add aspect-ratio sizing to padding/border/margin but didn't want the box itself to be sized using aspect-ratio, that would be much more difficult (maybe even impossible) to achieve using from-ratio. It would be easily achievable using an ar unit though.

Since padding, border, and margin are all attached to either a horizontal or vertical side, I'm wondering if the tr unit could be extended to those properties as well to solve this.

from-ratio requires the whole box to be sized into an aspect-ratio, a tr unit would not.

@Dan503
Copy link

Dan503 commented Nov 1, 2018

from-ratio requires the whole box to be sized into an aspect-ratio, a tr unit would not.

Although if there was a way to make aspect-ratio have no effect on the box itself using min-width, min-height, max-width and max-height then from-ratio would work just fine for this purpose and tr can remain restricted to CSS Grid.

@timuric
Copy link

timuric commented Feb 17, 2019

I would like to share another common use case that needs aspect ratio units.
There is a common problem with layout reflows when the layout is relying on the height of the image.
Probably we all have seen a jumping page over the slow network caused by the gradual loading of the images. The jumping layout have create unpleasant and disorienting effect and not to mention the UI freezes caused by the reflow. I believe having easy control of aspect ratio would help many developers create a more pleasant page loading experience.
But perhaps the need for aspect ratio control goes beyond css grid?

@valtlai
Copy link
Contributor

valtlai commented Feb 17, 2019

@timuric See intrinsicsize attribute.

Updated:

See WICG/intrinsicsize-attribute#16:

img {
   aspect-ratio: attr(width) / attr(height);
}

The spec: https://drafts.csswg.org/css-sizing-4/#ratios

@frivoal
Copy link
Collaborator

frivoal commented Jun 26, 2020

Given that we now have an aspect-ratio property, are we still exploring the idea of aspect ratio related units as well, or can we close this?

@Archibald2
Copy link

Given that we now have an aspect-ratio property, are we still exploring the idea of aspect ratio related units as well, or can we close this?

I agree to closing this.

@Dan503
Copy link

Dan503 commented Jun 26, 2020

The main argument I'm seeing in the thread is so that aspect ratio can be applied to CSS Grid templates.

I'm pretty sure using auto in the grid template and aspect-ratio on the grid cell elements would cover most use cases.

I can't really think of a scenario where I couldn't use aspect-ratio on the child cell to get the desired layout.

@rachelandrew
Copy link
Contributor

I wonder whether if we get into a position of being able to style grid areas in some way, this may come back as a requirement. At the moment you have to put an item in the track in order to style an area, but in future maybe not.

@Dan503
Copy link

Dan503 commented Jun 27, 2020

The other main scenario is wanting to style things based on the width/height of the element.

For example, it would be absolutely amazing if we could write this to create text that modifies in size based on the width of the element:

.responsive-text {
  font-size: clamp(1rem, 2%w, 5rem);
}

2%w being the exact same value as what width: 2%; would equate to.

2%h would be the exact same value as what height: 2%; would equate to.

That isn't "aspect-ratio" though so maybe needs a separate ticket, or maybe we just rename this one?

@dvoytenko
Copy link

@Dan503 I agree. The font-size relative to width or height feels like a pretty different ticket. This is somewhat reminiscent of the CSS container queries efforts. This problem does arise a lot in the aspect-ratio context, but not limited to it.

@fantasai fantasai added css-grid-3 Masonry Layout and removed css-grid-3 Masonry Layout css-sizing-4 labels Jul 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-grid-3 Masonry Layout
Projects
None yet
Development

No branches or pull requests