CSS calc: Turn Viewport Width Into a Number With Length Division
A badge meant to scale with the viewport uses 100vw divided by 1000, and the browser ignores the scale declaration. What does dividing by 1000px change?

- A length divided by a number remains a length. Two lengths divided by each other produce a number.
- Use that ratio for scale, or multiply it by an angle for rotation.
- Keep a default style and test the actual declaration with
@supports.
The denominator determines what type you get back
Suppose a decorative badge should scale with the viewport, reaching its normal size at 1000px. Dividing 100vw by 1000 leaves a length. Dividing it by 1000px produces the dimensionless ratio the scaling operation needs.
Firefox 158, released October 13, added typed arithmetic support. The important rule in MDN’s guide is that compatible types can cancel. The unit names can differ: vw and px both represent lengths.
| Expression | Result | Type |
|---|---|---|
calc(1000px / 2) | 500px | Length |
calc(1000px / 2px) | 500 | Number |
calc(100vw / 1px) | 1000 for a 1000 CSS-pixel viewport | Number |
The last expression represents a width measured in CSS pixels. It does not report the display’s physical pixel count. A different length in the denominator gives a ratio to that length instead.
Use one ratio for two different visual properties
This badge example uses a 1000px reference width. It keeps a neutral default, then enables the calculation only when the browser accepts length division in a scale declaration.
.badge {
scale: 1;
rotate: 0deg;
}
@supports (scale: calc(1px / 1px)) {
.badge {
--ratio: calc(100vw / 1000px);
scale: var(--ratio);
rotate: calc(var(--ratio) * 10deg);
}
} The scale property accepts a numeric factor. The rotate property needs an angle, supplied here by multiplying the ratio by 10deg. No JavaScript viewport measurement is needed for this relationship.
| Assumed viewport | Scale | Rotation |
|---|---|---|
| 500px | 0.5 | 5deg |
| 1000px | 1 | 10deg |
| 1500px | 1.5 | 15deg |
These are arithmetic results from the example. Choose the reference width and angle to match how much the decorative element should change.
A valid calculation can still produce the wrong type for width
width: calc(1000px / 2px) produces 500, not 500px. The CSS Values type-checking rules require the calculation’s final type to fit its destination. To turn this result into a length, use width: calc((1000px / 2px) * 1px).
If all you wanted was half a width, width: calc(1000px / 2) already does that. Canceling units earns its place when a length ratio needs to feed a different kind of property.
Test the expression, not just the existence of calc
Support for ordinary calc() arithmetic does not establish support for dividing two lengths. The example uses a declaration feature query for scale: calc(1px / 1px). If it fails, the default scale and rotation remain in effect.
Start with the output your property needs. Preserve the unit for a length; cancel compatible units for a ratio; multiply by an angle when rotation is the destination. That makes the expression easier to reason about before adding it to a responsive interface.