# CSS Type Casting to Numeric: tan(atan2()) Scalars

CSS

ORG

, you cannot divide by length types;

calc(100vw / 5px

ORG

) does not work. It will eventually because it’s in the spec, and with enough support it may happen soon. But for now, no way to produce scalars based on size.

With, technically, one up-and-coming exception,

atan2

ORG

() .

atan2

ORG

() accepts

2

CARDINAL

params, effectively the slope, rise over run, y divided by x, atan2(height, width) and returns the angle from the bottom of the slope looking to the top.

Then, did you know? tan(atan2(height, width)) is the scalar <number> between the

two

CARDINAL

dimensions.

No, I did not know that; is that true?

That’s right… One could scale all kinds of dimensions, using simple trigonometry functions.

Really…?

If one were so inclined.

tan(atan2()) is just a scalar

No need to dive into normal trig things; pretty graphs, maps, and geometric art, etc.

Fundamentally, tan(atan2()) is just a scalar between

two

CARDINAL

dimensions.

For this article I’ll focus on identity scaling as a means to typecast into a numeric value but there are many ways to use this and compare any

two

CARDINAL

dimensions now.

Screensize

PERSON

One

CARDINAL

thing many people want is the ability to have the numeric pixel width (or height) of the viewport to find the aspect-ratio or do other calcs down the line.

I solved screensize in

100%

PERCENT

CSS previously with a binary search using The CPU Hack but I realized

today

DATE

it’s so much easier and faster with tan(atan2()) :

What is the numeric pixel value of

100vw

LOC

?

should be as easy as

:root { –px-width : tan (

atan2

ORG

(

100vw

LOC

, 1px )); } Enter fullscreen mode

Exit

PRODUCT

fullscreen mode

but

atan2

ORG

is super buggy in browsers right now. (mixing vw and px was intended to work)

Chrome

PERSON

returns

100

CARDINAL

in this case, which is strange/undesirable. Firefox returns

0

CARDINAL

in this case because of the mixed units failing. If both are vw or both are px ,

Firefox

ORG

correctly returns

100

CARDINAL

.

Safari

ORG

seems to always return

0

CARDINAL

from tan(atan2(Y, X)) for any Y and any X . With or without units, mixed or matching. (edit: Unless you wrap it in calc())

So for now we

first

ORDINAL

need

100vw

LOC

as

NNNpx

ORG

, which is easy in CSS because that’s what happens automatically if you register a var as <length> then set it to a value like –100vw:

100vw

PRODUCT

@property –100vw { syntax : "<length>" ; initial-value : 0px ; inherits : false ; } Enter fullscreen mode

Exit

PRODUCT

fullscreen mode

Now this works in

Chrome

ORG

exactly as hoped:

:root { –100vw :

100vw

LOC

; –px-width : tan ( atan2 ( var ( –100vw ), 1px )); } Enter fullscreen mode

Exit

PRODUCT

fullscreen mode

–px-width is the width of the screen as a, usually integer, number

here it is live including one for

100vh

PERSON

too:

get font-size and more

You can use this same idea for any container query units, calc sizes containing mixed units, find out the px size of rem, anything you want. Just register a length, set its value, and convert to numeric px with tan(atan2()) .

Easy peasy! Potentially super useful.

Works with <time> too

:root::after { –ms : tan (

atan2

ORG

( 12s + 1ms , 1ms )); counter-reset :

val var ( –ms

PERSON

); content : "Numeric ms value of

12s

CARDINAL

+ 1ms is: " counter ( val ); /* counter prints

12001

CARDINAL

*/ } Enter fullscreen mode

Exit

PRODUCT

fullscreen mode

That’s all numeric typecasting identity scalars, and it’s fun to think about all the ways you can mix calcs now, but there’s even more cool stuff tan-atan2 can-a-can-do, perhaps for a future article ~

The Trig (update)

The trig behind this isn’t necessary to know to use it, but I had a couple questions come up in private about it:

tan( angle ) is a function that takes an angle then produces a result that’s equal to "opposite over adjacent" – the height divided by the width of a right triangle:

atan( ratio ) is a function that takes the value of height divided by width and returns the angle; the inverse of tan() .

atan2

PERSON

( Y, X ) is a programming language’s adaptation of

atan

ORG

() that takes the height (Y) and width (X) as separate arguments instead of dividing them before passing, then returns the same thing

atan

ORG

would have.

So what this trick is doing is kind of silly in most worlds (and probably why nobody pointed it out sooner) because we’re using

two

CARDINAL

trig functions instead of division that calc() implementations can’t do yet.

atan2

PERSON

( Height,

Width

PERSON

) = angle from the picture above tan( angle ) =

Height / Width

PERSON

from the picture above tan( atan2( Height,

Width

PERSON

) ) =

Height / Width

ORG

@property –MyFullInlineSize { syntax : "<length>" ; initial-value : 0px ; inherits : false ; } @property –MyEm { syntax : "<length>" ; initial-value : 0px ; inherits : false ; } div .in-a-container { –MyFullInlineSize :

100

CARDINAL

cqi ; –MyEm : 1em ; –MyNumEmsWide : tan ( atan2 ( var ( –MyFullInlineSize ), var ( –MyEm ) )); –MyNumPxWide : tan ( atan2 ( var ( –MyFullInlineSize ), 1px )); } Enter fullscreen mode

Exit

PRODUCT

fullscreen mode

The End

If you think this is useful, fun, or interesting, it’s the kind of thing I do in my free time! So please do consider following me around the web:

PropJockey.io CodePen DEV Blog GitHub Mastodon

and

𝕏@Jane0ri

ORG

👽💜

//

Jane Ori

PERSON

PS: I’ve been laid off recently and am looking for a job!

https://linkedin.com/in/JaneOri

Over

13 years

DATE

of full stack (mostly JS) engineering work and consulting, ready for the right opportunity!