Not recognizing calc result as number, nor recognizing @property
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 250
- Forks
- 123
- PR merge metrics
- No merged PRs in 30d
Description
Below is an excerpt of css being implemented in a WordPress mechanism to generate css-only Low Quality Image Placeholders (https://github.com/WordPress/performance/pull/2550/changes), inspired by this article https://leanrada.com/notes/css-only-lqip/
@property --lqip {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
[style*="--lqip:"] {
--lqip-ca: mod(round(down, calc((var(--lqip) + 524288) / 262144)), 4);
--lqip-cb: mod(round(down, calc((var(--lqip) + 524288) / 65536)), 4);
--lqip-cc: mod(round(down, calc((var(--lqip) + 524288) / 16384)), 4);
--lqip-cd: mod(round(down, calc((var(--lqip) + 524288) / 4096)), 4);
--lqip-ce: mod(round(down, calc((var(--lqip) + 524288) / 1024)), 4);
--lqip-cf: mod(round(down, calc((var(--lqip) + 524288) / 256)), 4);
--lqip-ll: mod(round(down, calc((var(--lqip) + 524288) / 64)), 4);
--lqip-aaa: mod(round(down, calc((var(--lqip) + 524288) / 8)), 8);
}
W3C CSS Validator shows these errors
1 Unrecognized at-rule @property
8 [style*="--lqip:"] The types are incompatible ), 4)
9 [style*="--lqip:"] The types are incompatible ), 4)
10 [style*="--lqip:"] The types are incompatible ), 4)
11 [style*="--lqip:"] The types are incompatible ), 4)
12 [style*="--lqip:"] The types are incompatible ), 4)
13 [style*="--lqip:"] The types are incompatible ), 4)
14 [style*="--lqip:"] The types are incompatible ), 4)
15 [style*="--lqip:"] The types are incompatible ), 8)
15 [style*="--lqip:"] Parse Error
As noted in a code review comment there, this is what Claude Opus 5 said
Both tools are wrong, and about the same thing: the two‑argument
round(down, A)form where the rounding intervalBis omitted.What the spec says
css-values-4 §10.3:
The
round(<rounding-strategy>?, A, B?)function … If the type of A matches<number>, then B may be omitted, and defaults to 1. … In all other cases, omitting B is invalid.
--lqipis registered assyntax: "<number>"(lqip.css:12-16), soAis a<number>and omittingBis legal. The code is correct.Why the error points at
mod()instead ofround()Neither tool can establish a type for the
round()result, so it falls through tomod()'s "both arguments must be the same type" check against the literal4/8. That's also whylqip.css:27—mod(calc(var(--lqip) + 524288), 8), noround()— is clean in both tools while lines 19‑26 are not.The two tools fail for different reasons
I probed both with variants:
Expression PhpStorm W3C round(down, 5)ok error round(down, var(--lqip))ok — round(down, calc(var(--lqip) + 1))error error round(down, …, 1)(explicit interval)ok ok
- PhpStorm does implement the number default — it even reads your
@propertyto type a barevar(--lqip). It just loses the type when the argument is acalc()containing avar(). Dropping the redundantcalc()wrapper (round(down, (var(--lqip) + 524288) / 262144)) doesn't help.- W3C/Jigsaw doesn't implement the omitted-
Brule at all — evenround(down, 5)reports "The types are incompatible."Browsers disagree with both
In Chrome 152, with
--lqip: 192900, the omitted-interval and explicit-interval forms both compute--lqip-ca: 2, andCSS.supports('opacity', 'round(down, 0.5)')istrue.If you want the warnings gone
Adding the explicit
, 1to the eightround()calls is a semantic no-op that satisfies both tools. Verified on a copy: W3C goes from 9 errors to 1, PhpStorm to 0.--lqip-ca: mod(round(down, calc((var(--lqip) + 524288) / 262144), 1), 4);The remaining W3C error is
Unrecognized at-rule "@property"atlqip.css:12— a separate Jigsaw gap (it predates css-properties-values-api), and nothing you can or should work around.
So, there's two issues:
- not recognizing the calc as number
- Not recognizing @property
This resolves the calc/round error, but shouldn't be necessary (and isn't, in actual browsers)
--lqip-ca: mod(round(down, calc((var(--lqip) + 524288) / 262144), 1), 4);
--lqip-cb: mod(round(down, calc((var(--lqip) + 524288) / 65536), 1), 4);
--lqip-cc: mod(round(down, calc((var(--lqip) + 524288) / 16384), 1), 4);
--lqip-cd: mod(round(down, calc((var(--lqip) + 524288) / 4096), 1), 4);
--lqip-ce: mod(round(down, calc((var(--lqip) + 524288) / 1024), 1), 4);
--lqip-cf: mod(round(down, calc((var(--lqip) + 524288) / 256), 1), 4);
--lqip-ll: mod(round(down, calc((var(--lqip) + 524288) / 64), 1), 4);
--lqip-aaa: mod(round(down, calc((var(--lqip) + 524288) / 8), 1), 8);
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the supplied CSS in the validator, then trace how it parses @property and types calc(), round(), and mod(). Compare the results with the CSS Values specification and browser behavior. Done means valid @property declarations and number expressions validate without requiring an explicit rounding interval.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, java
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100