Open fantasai opened 8 years ago
Filing also under Grid, because it needs to be handled in a way that also works with grid-template-rows/cols.
https://lists.w3.org/Archives/Public/www-style/2018Jan/0023.html is a related problem; we could solve it if HTML calculates an aspect-ratio
value to inject at the preshint level alongside width/height. We should file a follow-up issue with HTML once we've addressed this issue in CSS.
How about a simple ew relative unit added that is percentage of element width?
Then we can just height: 100ew;
to make something square or height: 56.25ew
for a 16:9 box?
Obviously with an addendum that ew is ignored on the width property. This way, it can apply to all elements as they already work?
This feature really is needed. It's a common use case to have to ensure a certain aspect ratio for each item, eg in Flexbox or Grid, through all viewport widths / element widths.
There are many results for just one hack https://www.google.com/search?q=flexbox+aspect+ratio+padding-top+100%25 and eg https://css-tricks.com/aspect-ratio-boxes/
We need a real solution.
@ewanm89 wrote
How about a simple ew relative unit added that is percentage of element width?
Then we can just height: 100ew; to make something square or height: 56.25ew for a 16:9 box?
I think I like it.
Another aspect ratio ticket: https://github.com/w3c/csswg-drafts/issues/1173
@fantasai wrote:
Filing also under Grid, because it needs to be handled in a way that also works with grid-template-rows/cols.
The Grid label unfortunately has been removed. I hope it will get added back.
We removed the label because it's not a blocker for Grid 2; it's a Sizing issue. We'll want to think about Grid when designing a solution, but in the meantime it's clogging up our view of what needs fixing for Grid. ^_^
While I would agree with the principle, the sizing issue has been something that should have been fixed decades ago. And it is just getting more and more desperate without a fix in sight.
Having an element width "ew" unit would be so useful ... I already use it via EQCSS. An example from one of my projects:
@element .page {
img[src$=".svg"] {
width: 30ew;
}
}
The nice thing is that if .page has a max-width, the effective ew value will stop growing after that max width. With vw the effective value would continue to grow with the viewport.
And it could be a nice way of specifying aspect ratios (as @ewanm89 wrote earlier), eg height: 100ew
in order to get a 1:1 ratio / a square.
width: 30ew;
This specific example of ew
unit confuses me. Are you setting the img to 30% of the width of the .page element? So the img ew
unit comes from the parents width? Or are you somehow wanting to set the width of the img to 30% of what the width of the img would compute to if left unset?
Regardless, I'd be more interested in a property or method (https://github.com/w3c/csswg-drafts/issues/820#issuecomment-268282394) that comes with constraints on display and box, cleanly interacting with min/max-height/width and values like min/max-content/min()/max()/etc... something to more cleanly accomplish this... http://jsbin.com/yuvaka/9/edit?html,output
This specific example of ew unit confuses me.
It's code from an actual project, and it works 😀
The more typical element query would look like this, for example:
@element .page and (max-width: 422px) {
/* Inside this block, the element-width unit "ew" is based on the .page element. */
}
Are you setting the img to 30% of the width of the .page element?
Yep, that's what this EQCSS-powered code does.
So the img ew unit comes from the parents width?
It comes from the .page element, which could be the parent of the image element, but it could also be a far higher ancestor for example.
The docs are at https://elementqueries.com/ -> "ew (element width)" "EW Units", and (with more info) at https://tomhodgins.github.io/element-queries-spec/element-queries.html#ew .
Some more instances of "ew" units in use: https://tobireif.com/demos/grid/view_demo_source/ -> search-in-page for all "ew;" . (The demo itself is at https://tobireif.com/demos/grid/ .)
Regardless, I'd be more interested in a property or method [aspect-ratio specific]
Having a property (or set of properties) specifically for aspect-ratio would be great!
The "ew" unit is a fundamental part of element queries / container queries, and it could also be used for ensuring any aspect ratio:
@element #foo {
#foo {
height: 100ew;
}
}
... but having one or more properties specifically for aspect-ratio would be even better (and I hope we'll get native element queries including element-width units in any case).
Are you setting the img to 30% of the width of the .page element?
Yep, that's what this EQCSS-powered code does.
That wouldn't be how an ew
unit works in real CSS though.
I think if ew
was used on the width
property it would equate to the same as if you used %
.
I'm glad the grid tag was removed. This is a unit that should be usable anywhere like the vw
unit, not just on grid items.
Imagine how great it would be to be able to write font-size: 20ew,
. Now you can have text that scales with the size of its container rather than the size of the viewport! (font-size: 20vw;
)
That wouldn't be how an ew unit works in real CSS though.
It could be spec'd to work just as in EQCSS.
I think if ew was used on the width property it would equate to the same as if you used %.
@element .select-any-element-here-not-necessarily-the-parent and (max-width: 422px) {
/*
Inside this block, the element-width unit "ew" is based on the selected element.
It can be any element.
*/
}
This is a later example from above:
@element #foo {
#foo {
height: 100ew;
}
}
This is a unit that should be usable anywhere like the vw unit, not just on grid items.
Yes, sure!
Perhaps you want to open a new ticket for the ew unit? (there's isn't one yet)
Imagine how great it would be to be able to write font-size: 20ew,. Now you can have text that scales with the size of its container rather than the size of the viewport! (font-size: 20vw;)
In
https://tobireif.com/demos/grid/
https://tobireif.com/demos/grid/view_demo_source/
there is for example font-size: 57ew;
.
But even better for that type of use case would be to be able to say "always fit this line of text in this container (by adjusting property foo eg font-size or letter-spacing), no matter what font is used".
This is a later example from above:
@element #foo { #foo { height: 100ew; } }
This is a unit that should be usable anywhere like the vw unit, not just on grid items.
Yes, sure!
Perhaps you want to open a new ticket for the ew unit? (there's isn't one yet)
Why open a new issue? This issue is about adding a way to define an aspect ratio. And the ew
unit is one possible solution for it, so it belongs in here.
What should be discussed separately is the @element
rule defining the element things like the ew
unit relate to.
Sebastian
Why open a new issue?
Because it's a potentially separate feature, and has many, many use cases beyond being one potential option for ensuring aspect ratios.
This issue is about adding a way to define an aspect ratio. And the ew unit is one possible solution for it, so it belongs in here.
Yes it sure can be discussed here! ... as far as it pertains to the use case of specifying aspect ratios.
And the ew unit has many other use cases so it would sure be sensible to open a separate ticket in addition to that.
This aspect ratio ticket here might well get closed as soon as there's a solution which doesn't involve or require "ew" units - then there'd be no ticket for all the use cases that the ew unit solves (eg specifying font-size based on an some element's with).
What should be discussed separately is the @element rule defining the element things like the ew unit relate to.
You wrote that the ew unit is one possible solution for it, so it belongs in here
. All parts and aspects of one possible aspect ratio solution eg
@element #foo {
#foo {
height: 100ew;
// eg plus minmax()
}
}
can be discussed here as long as it specifies an aspect ratio (and people are working on element queries anyways, see https://github.com/tomhodgins/cq-usecases , so there's no need for a new ticket for that).
This past week, we wrote a draft at: https://drafts.csswg.org/css-sizing-4/#ratios
This past week, we wrote a draft at: https://drafts.csswg.org/css-sizing-4/#ratios
From a quick look:
Very cool 👍
Regarding the options: option B "min-height: 1ar" is nicely descriptive, and it requires just one line (as opposed to option A).
https://twitter.com/Daniel_Tonon/status/1054337270151569408 brings up the desire to set an aspect ratio on the content box, set margins in one dimensions (say in block direction), and be able to assign margins in the other direction (inline) using from-ratio
in order to make a margin box that also keeps to the aspect ratio. Same for padding.... etc.
Actually there is one limitation in using from-ratio
compared to an ar
unit.
ar
is pretty much self contained.
from-ratio
on the other hand needs the aspect-ratio
property to be set which comes with a bunch of its own effects.
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.
Glad to see some action on this - I went through the idea of an aspect-ratio
property a while ago and specced out what I wanted from a developer's perspective, including when I'd expect width
, height
, and aspect-ratio
to take effect in cases where multiple are declared: https://tomhodgins.github.io/aspect-ratio-spec/aspect-ratio.html
Hope this helps!
The WICG has a group that worked on Aspect Ratio for a bit (5 issues): https://github.com/WICG/aspect-ratio.
It also points to this draft: https://jonathankingston.github.io/logical-sizing-properties/#propdef-aspect-ratio
I'm a WICG member the majority of issues in that repository are mine 🤣The dream spec I linked to here grew out of the discussion from that repository but is a little more fleshed out in terms of what the aspect-ratio
property should do, when it should apply etc
The CSS Working Group just discussed Aspect Ratio
.
Here's an interesting request: https://twitter.com/nhoizey/status/1054712116534489089
Fluid video (that has an aspect ratio, like 16x9), with fixed-height controls running along the length of the video directly underneath. I remember this being super common in the days of flash player for video. I haven't seen this since people switched away from Flash, but perhaps it's still common.
Something like this might be the solution:
.video {
width: 100%;
height: calc(.5625tr + 25px);
}
That syntax looks similar to the EW units discussed above. Here's a working demo mocked up using EQCSS where ew
takes the place of tr
from that last code example:
<div>
<nav></nav>
</div>
<style>
@element div {
:self {
background: lime;
height: calc(56.52ew + 25px);
}
:self nav {
height: 25px;
background: hotpink;
}
}
</style>
<script src=https://elementqueries.com/EQCSS.js></script>
Live Demo: https://codepen.io/tomhodgins/pen/bmmEVj
In issue #1173, I have suggested the following.
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 }
@jensimmons Very happy to hear this is being worked on! 🏅
As a developer, this is an issue we've run into multiple times. For example, getting a modal window to scale with a fixed ratio depending on how much content there is in it (with current CSS toolset the best one can do is for it to expand 100% in one axis before expanding in the other).
As for the options, I think option B (tr
unit) is better. I also like the suggestion by @Archibald2, of using h
and w
(it would fit in with other dynamic units, such as vw
and vh
).
Either of them (tr
or w/h
) would be a great addition to CSS! 💯
@Archibald2 I see developers already struggle with w
as an actual pixels 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.
On a side note, I wonder why both this issue and #1173 are still open. Is there any difference?
I haven't used srcset
or sizes
, but I don't know how vw
could possibly be confusing, after you figure out what a viewport is. Could the issues people are having be due to a poor specification of srcset
/sizes
rather than due to a bad size unit?
The issue is with the very close names w
and vw
. But they get used to it, fortunately.
But the point here for aspect ratio is that you suggest using w
in CSS for a dimension relative to an element's width, while it's already used in HTML (and I hope in the future in CSS) for the actual pixels width of an image.
@nhoizey I'm coming round to thinking it would be better to use percentage lengths as with vw and vh. So here's another option:
div {
min-height: 100%w;
}
article {
max-width: 150%h
}
Hopefully this isn't too dumb a question, but what is tr
? I see it and can only think of "table row".
Oh, never mind, it was a dumb question. Either the draft changed in the last day or so from ar
to tr
(it's "transfer ratio"), or I didn't read the draft thoroughly enough the first time!
@tremby it changed: https://github.com/w3c/csswg-drafts/issues/3225
With regard to the draft at https://drafts.csswg.org/css-sizing-4/#ratios, I think "Intrinsic Aspect Ratios" should be changed to "Specific Aspect Ratios". While an image for example has an intrinsic aspect ratio, my understanding is that proposed 'aspect-ratio' property will specify a fixed aspect ratio for an element.
Aspect ratio is a thing in video, and we shouldn't create new problems there. Encouraging the viewport to be a different aspect ratio to the content has an accessibility impact.
Just want to call out that there's a potential impact here on users of video, who might be confused by this. In video it is common for different aspect ratios to be used and to modify the size of the video element automatically based on the content being played.
If a video element is given a specific aspect ratio, and that does not match the aspect ratio of the video content being played, what should happen?
For example, video content aspect ratio is 16:9, video viewport is 4:3. Should the video get black bars top and bottom, or should the central 4:3 section be shown only, omitting the 12.5% on either side?
This is a big deal for subtitles and captions authored with specific positions in mind, if those positions are specified with respect to the video viewport. It is typical to position subtitles to avoid obscuring important action happening in the video, for example a person's face when they are talking, the ball in a sports game, etc. It is important to have a clear positioning model in this case.
At the very least, whatever the implementation does with the video in this case needs to be available to player js code so that it can try to get the positioning correct.
Apologies if this is not the right place to raise this question. It just seems that introducing aspect ratio to CSS may exacerbate this issue, or confuse users, even if it is already possible to set the size of a video element explicitly to whatever aspect ratio is needed. For example now, it is possible to set max-width: 100%;
alone on a video
element, and the height is resolved automatically based on the aspect ratio of the content.
@nigelmegitt set the height and width of the video using CSS to a square aspect ratio or something and see what happens.
It typically will display black bars but you can use object-fit to alter how the video is displayed.
@Dan503 thanks, it may well be that all we need here is an informative note directing readers who think they've found the answer to their video aspect ratio problems to the correct place, i.e. CSS Images.
This is a use-case that an aspect-ratio unit may be helpful in: https://stackoverflow.com/questions/49525893/css-aspect-ratio-set-width-of-child-element-based-on-dynamic-parent-height
Fluid video (that has an aspect ratio, like 16x9), with fixed-height controls running along the length of the video directly underneath. I remember this being super common in the days of flash player for video. I haven't seen this since people switched away from Flash, but perhaps it's still common.
@jensimmons I don't think it is still common indeed, but here is at least one example with LinkedIn Learning: https://www.linkedin.com/learning/photoshop-cc-2019-new-features/photoshop-20-will-change-how-you-work
Issue 4 in the spec asks:
aspect-ratio: attr(width px) / attr(height px);
[...] Can we just slip this
aspect-ratio
rule into the UA default style sheet for images, so that they have an aspect ratio while they load? This would avoid the need for extra reflows after loading.
This is an interesting idea for how to solve the same problem that the proposed intrinsicsize
attribute (on <img>
and <video>
) is attempting to solve. intrinsicsize
solves it at a different level, by setting/overriding the image's intrinsic size (or aspect ratio), rather than establishing a default extrinsic ratio for it.
So I guess first of all – I just want to cc some intrinsicsize
people who have thought through this problem – @tigt @ojanvafai @loonybear
Second – I have two questions about how the proposed rule may break existing content.
Specifying width
and height
as percentages was valid in HTML 4.01. Is there existing content that will break if those percentages are interpreted as px (I guess?) and fed into this rule?
Currently, in order to achieve fluid sizing without aspect-ratio distortion on an image with width
/height
, you have to "undo" the extrinsic size set in the cross axis by setting it to auto
:
<img width="300" height="200" style="width: 100%; height: auto;" />
<!-- without `height: auto` this would be locked to a height of 200px, even as the width was fluid/variable -->
I suppose this new default would obviate that: a UA default aspect-ratio
would trump the height=""
presentational hint, so we could just write
<img width="300" height="200" style="width: 100%;" />
and get a 3:2 fluid img (that was 3:2 even before the image loaded and an intrinsic size was known). Yay! But... is there any existing web content that relies on or expects the previous behavior? Maybe, uh, spacer gifs?
One could change the UA selector to be more like img:not([width*="%"], [height*="%"])
, but I don't know if all CSS engines would run that performantly enough for every page.
Can attr()
interpret as a CSS <length>
falling back to px
?
Maybe I didn't understand your question. But if width
and height
are already specified (either in pixel or percentage), intrinsicSize
does not change the aspect ratio for the layout, it will only override what naturalWidth
and naturalHeight
return.
<img intrinsicsize="300 x 200" style="width: 100%;" />
maybe? I will test it and get back to you.
long story short, if intrinsicSize
is not specified, nothing is changed (unless you turn on feature policy unsized-media
policy, which set the default intrinsicSize
to "300 x 150"); if intrinsicSize
is used it doesn't do anything more than overriding the value of the intrinsic size of the image.
@loonybear my fault for not really asking a question! I guess my first implicit question, which you answered, was "would there be any weird interactions between intrinsicsize
and this default aspect-ratio
rule?" (sounds like, no 🎉). My second question is, given what you understand about the problem space, are there any problems you forsee with the proposed UA default style? The intrinsicsize
explainer calls a solution built on width
and height
out for being “not really backwards compatible” – I've tried to think through some reasons why that might be, above, but I'm asking if you or @ojanvafai can be more specific about what was meant by this.
Maybe it would be weird to use height
and width
to set intrinsic sizes, but it's perfectly fine to re-use them globally to set extrinsic ratios. And, for the purposes of no-reflows-after-image-loading,
<img intrinsicsize="300x200" style="width: 100%;" />
and (in the presence of the proposed UA default style)
<img width="300" height="200" style="width: 100%;" />
are functionally equivalent – they're just two good ways to solve the same problem. In which case, great! (and sorry for all of the comments).
Just wanted to make sure folks know of...
Both for commenters to learn from and for those involved then to feel free to chime in.
aspect-ratio works on all replaced elements whereas intrinsicSize so far only works on HTMLImageElement and HTMLVideoElement. The intention is for it to work well with feature policy 'unsized-media' which deals with problems that cause layout instability (content jumping around on the web page).
But if aspect-ratio could cover all the cases we need intrinsicSize for (being able to determine the layout size before downloading the image), then I don't think there's a need for intrinsicSize.
So how would aspect-ratio achieve the case of:
<div style="width: 75vw">
<img src="my-image.jpg" aspect-ratio="4x3" style="max-width: 100%">
</div>
i.e. we want to set the image's width to min(width of container, intrinsic width of image). Is it possible for aspect-ratio to do so before downloading any image data.
Another question would be, how does it work with responsive images, how will the naturalWidth and naturalHeight be updated if an aspect-ratio is specified?
@eeeps So about your backwards-compat concerns in https://github.com/w3c/csswg-drafts/issues/333#issuecomment-438092951 ...
Specifying width and height as percentages was valid in HTML 4.01. Is there existing content that will break if those percentages are interpreted as px (I guess?) and fed into this rule?
I'm expecting this to be implemented in C++ rather than CSS, but in the case of CSS percentages would end up invalid here (invalidating the rule) and in C++ we would certainly want to do the same.
Currently, in order to achieve fluid sizing without aspect-ratio distortion on an image with width/height, you have to "undo" the extrinsic size set in the cross axis by setting it to auto:
Yes. I'm not proposing to change that: the width
and height
attributes would still map to the corresponding CSS properties. The proposal is simply that they would also map into an aspect-ratio
property.
The main concern wrt Web compat is someone putting in width
and height
attributes that don't correspond to the image's actual aspect ratio, and then also overriding those width
and height
attribute values with different width
and height
CSS values one of which is auto
.... I don't anticipate this being particularly common, but it could happen. :)
With a huge chance of side-tracking this thread (due to not really knowing where exactly to post this reply) or the risk of proposing something that got proposed before, here goes:
Glad to see the addition of aspect-ratio
being talked and discussed about, as the need is real (once wrote an extensive post on this myself).
Thinking further on this, this solution is somewhat limited: it only solves the aspect ratio problem, and nothing else outside of that.
A more broader solution – I think – could be the introduction of a val()
function, which could be used to solving the aspect-ratio
thing, but also other future things.
The val()
function would work like the var()
function (which reads the value of a custom property) but then for reading values from other properties. The val()
function also differs from var()
in such a way that it yields the computed value of the property. Recalculation would happen upon resize events and the like. Combine val()
it with calc()
and you're good to go.
In code, it would result in something like this:
.box {
width: 100%;
height: calc(val(width) * 16 / 9);
}
Of course it needs some more tweaking and thought: What if you want percentages (for use within rgba
for example)? Perhaps a second argument that defines the requested unit (say you want percentages or ems instead of pixels) could be added? Or a whole different function that converts units could be introduced (unit()
would be a nice one)? Or … — Things might easily get over-complicated, which is not really feasible I guess.
I know, it's a bit side-tracky this reply, but I do see a future for this kind of addition. Don't let this comment hinder the release of aspect-ratio
though, the sooner it lands the better! Maybe it could later be retrofitted as an underlying part of aspect-ratio
? Quite sure all the smart people involved will have a clear idea on this all, or will immediately see a lot of flaws in my brainfart above, as you've already pondered about it quite a lot.
Grid & Flexbox make the aspect ratio problem more urgent, since they're so much better at flexible sizing than previous layout models...
Jen Simmons wrote: