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

[media-queries][css-sizing] Support <number> (and therefore calc) as a <ratio> #3757

Closed
AmeliaBR opened this issue Mar 25, 2019 · 24 comments
Closed

Comments

@AmeliaBR
Copy link
Contributor

The new aspect-ratio property in css-sizing-4 re-uses the <ratio> data type defined for the aspect-ratio media query, which currently only excepts rational fractions defined as <integer> / <integer>.

For flexibility, I propose extending the <ratio> type to support:

  • a single <number> value (so that you could specify aspect-ratio: 1.5 instead of aspect-ratio: 3/2)

  • maybe, an arbitrary numerical fraction (aspect-ratio: 3.3/2.2)

  • maybe, a fraction of lengths (aspect-ratio: 1ch/1em)

The "maybes" are because — for the property, if not the media query — they could be replaced with calc() functions if (a) a single number value (the result of the math expression) is accepted as a ratio, and (b) for length fractions, calc division of values with units is actually implemented.

@jonjohnjohnson
Copy link

@AmeliaBR Quick question, maybe you can infer from the spec text better than I, before I open up a separate ticket... I see mention of inline-size and block-size and writing modes in relation to Example 3 specifically. But should I assume aspect-ratio will simply be physical mapping x/y, then hopefully receives the eventual Flow-Relative Keyword for logical mapping?

@AmeliaBR
Copy link
Contributor Author

@jonjohnjohnson That's actually a really good question — mind opening a separate issue?

@jensimmons
Copy link
Contributor

Before we decide anything, please read this page about aspect ratios: https://en.wikipedia.org/wiki/Aspect_ratio_(image)

It's common to express an aspect ratio as a ratio — for example 16/9 is expressed as 1.77:1. Or shortened to 1.77. I'd rather we don't invent new web-only ways to express something.

@AmeliaBR
Copy link
Contributor Author

AmeliaBR commented Jun 5, 2019

@jensimmons So, you're saying that a single number with decimals is sensible, in addition to the ratio of integers, but everything else is just complicating things without benefit? (and, as I noted in the first comment, can be replaced with calc, anyway)

@tabatkins
Copy link
Member

I agree that we should widen the grammar to <number> / <number>; restricting it to <integer> doesn't match common practice and doesn't actually help us with anything.

Given that, I don't think we need to provide a single-number pattern; 1.77 / 1 seems fine?

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Aspect Ratios, and agreed to the following:

  • RESOLVED: change <integer> to <number> in the aspect-ratio
  • RESOLVED: allow <number> and <number>/<number> both for <aspect-ratio>
The full IRC log of that discussion <fantasai> Topic: Aspect Ratios
<fremy> ScribeNick: fremy
<astearns> github: https://github.com//issues/3757
<fremy> AmeliaBR: currently for the aspect-ratio media query we define a ratio type (integer slash integer)
<fremy> AmeliaBR: we are thinking about using the same type for the aspect-ratio property
<fremy> AmeliaBR: I think we should support decimal in addition to the fraction
<fremy> AmeliaBR: so <int>/<int> or <number>
<heycam> q+
<fremy> jensimmons: I can see how this looks like a fraction, but I don't think of it this way
<chris> its a rational number, not a fraction
<fremy> jensimmons: interested people can look at the history of aspect ratio in the film industry
<fremy> jensimmons: there is both 16/9 or 16:9 or 1.77
<fremy> jensimmons: I don't see us wanting to have 1.77:1
<fremy> jensimmons: that is confusing
<fremy> myles_: is it bad that when you actually divide these numbers you get non-round numbers?
<TabAtkins> q+
<chris> https://www.mathsisfun.com/rational-numbers.html
<fremy> AmeliaBR: yes, this is why we prefer the "fraction-looking" expression
<fremy> myles_: so we don't want to convert to a number, right?
<fremy> jensimmons: no, we would keep the other representation
<chris> q+
<fantasai> myles: I don't want to have a 1px gap because of people's mental rounding errors
<astearns> ack heycam
<fremy> AmeliaBR: but when authors have numbers they computed themselves in some other way, we don't want to force them to use a fraction
<fremy> heycam: so, if you want to use css variables, you would want to use calc() right?
<fremy> myles_: native api often expose numerator and denominator as distinct in those cases
<fremy> chris: come on folks, are we really discussing this?
<astearns> q?
<fremy> chris: this is a rational number, we can allow that and other forms of numbers, this is very common outside of css
<astearns> ack TabAtkins
<chris> The ancient greek mathematician Pythagoras believed that all numbers were rational, but one of his students Hippasus proved (using geometry, it is thought) that you could not write the square root of 2 as a fraction, and so it was irrational.
<chris> q-
<fremy> TabAtkins: I think I agree that accepting all numbers is reasonable, for the calc() cases
<leaverou> q+
<chris> But followers of Pythagoras could not accept the existence of irrational numbers, and it is said that Hippasus was drowned at sea as a punishment from the gods
<fremy> TabAtkins: but I don't think we need to add just plain <number> because it's ambiguous
<AmeliaBR> q?
<jensimmons> q+
<dbaron> Tab's proposal (do just change <integer>/<integer> to <number>/<number>) sounds good to me
<astearns> ack leaverou
<florian> q?
<fremy> leaverou: I don't understand why there is an ambiguity?
<fremy> leaverou: can't we do both? why do we want to pick one?
<fremy> TabAtkins: ok, there is no ambiguity, but it makes the syntax more complex, I appreciate consistent things
<TabAtkins> s/it's ambiguous/it's nice to have a single consistent syntax pattern/
<fremy> TabAtkins: but you are are, it's not ambiguous
<fremy> AmeliaBR: well we will get questions anyway, some will wonder why you have to write 1.5/1 instead of just 1.5 but ok that's doable
<astearns> ack jensimmons
<fremy> jensimmons: calc() and variables, can someone explain how that would work now and with the proposals?
<leaverou> s/I don't understand why there is an ambiguity?/I don't understand why we can't do both. There is no syntactical ambiguity./
<fremy> TabAtkins: today, if you use calc, it would get weird results, because we only allow integers, so they would be rounded
<fremy> TabAtkins: so it works in theory, but it's not very practical
<fremy> TabAtkins: the proposal would allow to have any number, so you can compute using a ratio of two variables
<AmeliaBR> s/well we will/we can wait until we have more authors using this, and then see if/
<fremy> jensimmons: that sounds reasonable, but there is a very common case with just a number, I don't see why not adding that as well
<fremy> astearns: and that seems common, so I'd plus on that
<florian> q?
<fremy> TabAtkins: I would prefer not to add syntax when it doesn't add much, but if there is strong demand for this, I could get convinced
<fremy> astearns: so, can we resolve to change <int> to <number> for aspect ratio values?
<fremy> RESOLVED: change <integer> to <number> in the aspect-ratio
<fremy> TabAtkins: for the second part, what do implementers think?
<fremy> dbaron: I think that I cross-multiplied to avoid rounding, but I'm not sure
<fremy> dbaron: I considered it because otherwise it's a bit scary if people might try an equality and rounding is risky then
<chris> people comparing two floats for equality need to learn why that is never a good idea
<fremy> dbaron: but code has been rewritten since then anyway
<fremy> dbaron: so I don't know
<fremy> myles_: is that relevant though?
<fremy> TabAtkins: maybe not, but I was curious
<myles_> s/is that relevant though?//
<fremy> astearns: I think we should try to keep the syntax simple, and revisit if we get requests
<emilio> https://searchfox.org/mozilla-central/rev/153172de0c5bfca31ef861bd8fc0995f44cada6a/servo/components/style/media_queries/media_feature_expression.rs#31
<fremy> hober: but priority of consituency indicates that we should favor allowing to drop the slash one
<fremy> astearns: also, looking at the example emilio pasted in irc, the slash one looks dumb, so I changed my mind a bit
<fremy> jensimmons: also, I don't buy the complexity of having two syntaxes
<emilio> s/emilio/AmeliaBR :)
<myles_> <number> | <number> / <number>
<fremy> astearns: ok, so let's try to resolve to allow <number> and <number>/<number> both
<AmeliaBR> s/AmeliaBR/flackr/
<fremy> dbaron: well, that constraints syntax a bit, but I'm fine with it
<dbaron> s/constraints/constrains/
<jensimmons> this is really good. And it’s good to do it now.
<fremy> RESOLVED: allow <number> and <number>/<number> both for <aspect-ratio>

@jonjohnjohnson
Copy link

I'd be remiss to not bring up @jensimmons comment about calc'n on top of aspect ratio behavior on the grid related issue...

Fluid video (that has an aspect ratio, like 16x9), with fixed-height controls running along the length of the video directly underneath.

.video {
 width: 100%;
 height: calc(.5625tr + 25px);
}

#333 (comment)

Could it be possible to support this somehow with calc() in the aspect-ratio property? The only way I imagine this behavior would be covered, albeit using extra elements, is if box-sizing being set to content-box, then offset the ratio size by using padding/border with a descendant was positioned accordingly?

@tabatkins
Copy link
Member

Yes, using a-r on the content box, then using padding/border to get the extra space, is the only way (currently) to do that. We should probably track that case tho (an aspect ratio, plus/minus some extra space in either or both axises) as another issue.

@emilio
Copy link
Collaborator

emilio commented Aug 12, 2019

How should this serialize? The current proposed patch for the feature in Firefox serializes 1.77 as 1.77 / 1.

I think we should omit the / 1 part if the denominator is one. That is technically a breaking change, since if you wrote (aspect-ratio: 2 / 1), you'd get (aspect-ratio: 2) rather than the historic (aspect-ratio: 2 / 1), but I think we should be able to get away with it. Thoughts?

@emilio emilio added the Agenda+ label Aug 12, 2019
@emilio
Copy link
Collaborator

emilio commented Aug 12, 2019

(Proposed patch is at https://bugzilla.mozilla.org/show_bug.cgi?id=1565562).

@emilio
Copy link
Collaborator

emilio commented Aug 12, 2019

Also, how should ranges here work? Right now we're enforcing positive-integers at parse time, but doing positive numbers seems against common behavior of having open ranges.

@AmeliaBR
Copy link
Contributor Author

AmeliaBR commented Aug 12, 2019

Yes, if we allow arbitrary decimal numbers (0.0000000001) than we need to allow 0 for consistency with the rest of CSS. There's some wording about handling zero in the width/height media queries that might be relevant here.

For serialization, I think backwards compatibility is worth maintaining. So is keeping numeric precision: we shouldn't turn an exact 2/3 into an imprecise decimal. So, either keep the value as specified (fraction or number) or always insert the redundant /1 if the specified value was a single number.

@fantasai
Copy link
Collaborator

+1 to @AmeliaBR's comment. We do have a principle to serialize to the not-shortest representation when the shortest one is less backwards-compatible, and this would be such a case.

@emilio
Copy link
Collaborator

emilio commented Aug 24, 2019

What do we want to do with stuff like 0/0 and such?

@AmeliaBR
Copy link
Contributor Author

What do we want to do with stuff like 0/0 and such?

We have a separate discussion about that in #3768 when it comes to calc, and decided to serialize as is. So, I guess the same could apply here.

@carlosame
Copy link

Unless I'm missing something, the new syntax would allow ratios composed by calc() values like aspect-ratio: calc(...) / calc(...), is that right?

Why not do that with just a single calc() and leave ratios as integers?

carlosame added a commit to css4j/css4j that referenced this issue Aug 25, 2019
@emilio
Copy link
Collaborator

emilio commented Aug 27, 2019

That is right. But you already can do aspect-ratio: calc(..) / calc(..) as long as they end up resolving to an integer, right? So that wouldn't be backwards compatible.

@carlosame
Copy link

But you already can do aspect-ratio: calc(..) / calc(..) as long as they end up resolving to an integer, right?

Not in my implementation, and I guess that was a bug then...

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Support <number> (and therefore calc) as a <ratio>.

The full IRC log of that discussion <dael> Topic: Support <number> (and therefore calc) as a <ratio>
<dael> github: https://github.com//issues/3757
<dael> emilio: A contributed impl this in FF. Couple issues related to thing we didn't resolve on. Resolved ot allow syntax as <number> but not on serialize, if you can do two negative numbers. Regular aspect ratio we only allow positive int
<dael> [audio problems with emilio ]
<dael> Rossen_: While we wait on emilio to reconnect...
<dael> AmeliaBR: I can fill in
<emilio> thanks AmeliaBR!
<dael> AmeliaBR: Resolution we had previously was to loosely allow any number over a number or a single number as valid syntax
<dael> AmeliaBR: Simple q of serialization we've got backwords compat on people expecting int/int Anything spec that was should continue to serialize that way
<dael> AmeliaBR: Options from there are remember if it is spec with a / and keep that or always serialize with a / and add /1 if it's single number
<dael> AmeliaBR: As emilio points out there are other questions about how much do we simplify, if you've got -int/-int does it simplify or clamp. /0 is valid according to syntax, how to deal
<dael> AmeliaBR: One option is treat like calc but in serialization we add in the /1. Can lose numeric precesion in some fractions
<dael> AmeliaBR: If you 1/3 to get 0.6667/1 that would be a problem.
<dael> AmeliaBR: If we're not simplifying int fractions what to do with arbitrary numbers. Keep as two separate? Lean to keep 2 as separate and if isn't spec insert a 1. Simpliest approach and least likely to surprise
<AmeliaBR> s/If you 1/If you specify 2/
<dael> fantasai: SHouldn't reduce everything to over 1. HAve principle we serialize to most backwards compat and shortest, not just shortest. The older form serialization will need both numbers. Shouldn't simplify fractions down.
<dael> fantasai: Could do 9/3 to 3/1 but don't see a benefit to doing that
<dael> jensimmons: For clarity, is this visible to authors or is this in the caluclation when you get to computed
<dael> fantasai: For gCS
<dael> AmeliaBR: Effects both reading back value from dom, simple serialization,a nd serialization from gCS
<dael> fantasai: Important to notevalues from gCS need to roundtrip without loss. Simplifying 1/3 to 0.667 isn't in keeping with those principles. Not appropriate to do here.
<dael> AmeliaBR: We do it with calc, though
<dael> AmeliaBR: Worth mentioning for backwards compat the syntax is currently only in MQ. Not sure how much people are reading back values, but I'm sure someone is somewhere.
<dael> Rossen_: Couple minutes overtime. I don't believe we can resolve on this. Again, I invite folks to engage on GH and we'll pick up next week
<dael> Rossen_: Sorry we couldn't make any resolutions today, let's hope it's different next week. Thank you all for calling and we'll chat next week. It's APAC time zone.
<emilio> *:(
<emilio> Sounds good, thanks Rossen_ for all the chairing work :)
<Rossen_> trackbot, end meeting

@AmeliaBR
Copy link
Contributor Author

AmeliaBR commented Aug 28, 2019

My current proposal, after the discussion on the call:

  • For simplification (e.g., reducing calc to a single value), treat each <number> as independent.
  • If only one number was specified, treat the second number as 1.
  • Then serialize as <number1>/<number2>.

This is all consistent with how the aspect-ratio is currently serialized (demo, Chrome and Firefox tested).

For dealing with zeros, I think we just accept them & use them in a way consistent with other standard computer math rules, as we've defined elsewhere for calc and comparator functions:

  • An aspect ratio of 0/n in a media query will be less than any possible aspect-ratio of the display.
  • An aspect ratio of n/0 (for positive n) will be greater than any display.
  • 0/0 will always be invalid and never match anything.
  • For use in the aspect-ratio property, these will either result in values of zero being calculated (e.g., when calculating height from a defined width using an aspect ratio of 0/n, you get a height of 0) or with invalid results (e.g., infinite height) that cause the width/height calculations to fallback to whatever is the next step in the layout algorithm.

For negative numbers, I'm OK with either option:

  • Force both numbers in the faction to be non-negative,so the syntax for <ratio> becomes <number [0,∞]> [ / <number [0,∞]> ]?; or
  • Allow negative numbers, and if the final aspect ratio is negative (i.e., if one or the other number is negative, but not both), that is clamped to zero in practice because width, height, and the display aspect ratio can never have negative values.

@fantasai
Copy link
Collaborator

Negative numbers are not allowed in <ratio>, see https://www.w3.org/TR/mediaqueries-4/#aspect-ratio
The rules for calc() will clamp negative values accordingly.

@AmeliaBR
Copy link
Contributor Author

Negative numbers are not allowed in

That's the existing syntax, the question is whether to keep that when switching to <number>. This is important when using calc values: do the results of the calc values get clamped to be no less than 0 before or after you do the division? E.g., is something that computes to calc(-10) / calc(-5) a valid ratio equal to 2/1, or is it an invalid 0/0 ?

I added a few more tests to my CodePen, currently calc expressions that evaluate to negative values seem to be clamped to 0 then discarded because 0 is also invalid?

@carlosame
Copy link

I'd appreciate a comment about how precision would affect the matching of media queries when numbers with decimals are used. Consider a viewport or page with a 4/3 ratio, and the following media feature tests:

max-aspect-ratio: 4/3
max-aspect-ratio: calc(4/3)
max-aspect-ratio: 1.3333

My current code would match the first two, but not the third. What if more decimals were added to it?

Perhaps that is specified in a more general way elsewhere, but could not find it.

@css-meeting-bot
Copy link
Member

css-meeting-bot commented Oct 2, 2019

The CSS Working Group just discussed Support <number> (and therefore calc) as a <ratio>, and agreed to the following:

  • RESOLVED: Accept proposal in favor of serializing with the division sign
The full IRC log of that discussion <dael> Topic: Support <number> (and therefore calc) as a <ratio>
<dael> github: https://github.com//issues/3757
<dael> AmeliaBR: Finishing a discussion that was time clamp in Aug. Issue is about serialization issues.
<dael> AmeliaBR: Aspect ratio is unique and this applies to MQ and property- defined where division is part of syntax not jsut part of calc. Brought questions on how to serialize
<dael> AmeliaBR: Proposal I had was we trat numerator and denominator as sep/ components of the value. Each simplified as independent. If one is omitted the other becomes a default 1
<dael> AmeliaBR: Only issue I found since last discussion is right now both values required to be positive. Calc expressions that resolve to -value/-value you clamp them so it's 0/0 instead of negatives canceling. Might be worth doing clamping at used value as this is non-intuitive
<dael> TabAtkins: Allowing individual numbers to be calcs is consiquence to CSS syntax. All numbers can be calcs
<dael> TabAtkins: Agree negatives not worth allowing. I don't see why two negatives should pop out. Even if they would cancel doesn't seem worthwhile.
<dael> TabAtkins: Anything with single calc?
<dael> AmeliaBR: Single calc is same as single number. I prop for serialization that's your numerator and insert the missing denominator as a 1
<dael> jen: Agree but don't see practical case for negative over negative so if that's difficult I'm for disallowing
<dael> AmeliaBR: Proposal as in my comment for Aug 28: Always serialalie as number/number where the numbers might be calc expressions
<dael> heycam: Against principle of shortest simplification, but fine for me. As long as we write that in spec
<dael> fantasai: Is shortest most backwards compat serialization
<dael> heycam: Is it a thing with this prop?
<dael> AmeliaBR: Yes with the MQ. Keep prop consistent with MQ
<fantasai> regardless, should indeed be made explicit :)
<dael> smfr: What about proposal to use units?
<dael> AmeliaBR: Agreed not to do that, but can do it by putting it inside a calc
<dael> smfr: Okay
<dael> Rossen_: Other comments? It's not perfect but sounds like best we can do
<dael> Rossen_: Objections to resolve in favor of serializing with the calc expression?
<dael> RESOLVED: Accept proposal in favor of serializing with the calc expression
<AmeliaBR> (that should really be "with the division", not a `calc()`!)

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

No branches or pull requests

10 participants