Media queries that contain `calc()` creates erroneous validation error
See original GitHub issueDescription
Whenever the AMP validator comes across a media query containing an instance calc()
a validation error is thrown. Here’s an example in AMP Playground with the media query @media (min-width: calc(840px - 48px)) {}
:
That same media query is considered valid by the W3C CSS validator, however:

After doing some debugging I’ve pinpointed the issue to this block of code where it parses the media feature (in this case calc(840px - 48px)
):
As you can see it consumes the media feature until it reaches the end of the line or encounters a closing parenthesis, which means it would stop at the last dimension in the media feature (48px
). Right after the closing parenthesis is consumed and it does a check to see if it has reached the end of the media query:
In this case however the media query is not finished being parsed as the closing parenthesis of the media query has not been consumed, and therefore the validation error is raised:
Now going back to the parsing of the media feature, the CSS 3 Media Queries spec states:
Media features only accept single values: one keyword, one number, or a number with a unit identifier. (The only exceptions are the ‘aspect-ratio’ and ‘device-aspect-ratio’ media features.)
That may be misinterpreted as calc()
not being accepted as a media feature value, but according to the CSS 3 Values and Units spec it can be used wherever a number or dimension is allowed:
The
calc()
expression represents the result of the mathematical calculation it contains, using standard operator precedence rules. It can be used wherever<length>
,<frequency>
,<angle>
,<time>
,<percentage>
,<number>
, or<integer>
values are allowed.
Not related to the bug, but here are some browser bug issues related to calc()
and media queries for completeness:
https://bugs.chromium.org/p/chromium/issues/detail?id=421909 https://bugzilla.mozilla.org/show_bug.cgi?id=1256575
Reproduction Steps
-
Create a file called
test.html
with the following contents:<!doctype html> <html ⚡> <head> <meta charset="utf-8"> <link rel="canonical" href="self.html"> <meta name="viewport" content="width=device-width,minimum-scale=1"> <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript> <style amp-custom> @media (min-width: calc(840px - 48px)){} </style> <script async src="https://cdn.ampproject.org/v0.js"></script> </head> <body>Hello, AMP world.</body> </html>
-
Valiate the HTML file with the AMP JS validator:
amphtml-validator test.html
- See the following result:
test.html: PASS
test.html:9:4 CSS syntax error in tag 'style amp-custom' - malformed media query.
Relevant Logs
No response
Browser(s) Affected
No response
OS(s) Affected
No response
Device(s) Affected
No response
AMP Version Affected
2108132216000
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:5 (5 by maintainers)
@pierlon First let me start by saying thank you for writing such an incredibly well researched and described issue report.
@honeybadgerdontcare is right, this is only a warning but it’s still also a valid bug in the parsing routine. I think it should be very easy to fix though, especially given the analysis you’ve already done. I’ll take it on myself to try to resolve this relatively soon. I believe I was the original author who made the mistake of ignoring calc() in the media expression parsing and taking a shortcut here.
This is now fixed. You may or may not see it in tooling for up to an hour or so while the release goes live.