sebastiaanvisser / clay

A CSS preprocessor as embedded Haskell.
Other
360 stars 73 forks source link

Add support for `aspect-ratio` CSS property. #266

Open chungyc opened 1 month ago

chungyc commented 1 month ago

This adds an aspectRatio function for generating the aspect-ratio CSS property and an AspectRatio type to represent aspect ratios. To make the ratios feel more like Data.Ratio ratios, this defines a % operator on two Integers generating an AspectRatio. So we could do things like this:

aspectRatio (16%9)
aspectRatio auto

To allow for properties such as aspect-ratio: auto 4/3, we use a withFallback function to generate an AspectRatio:

aspectRatio $ auto `withFallback` (16%9)

It is not legal to do something like aspect-ratio: auto auto. While it would have been nice if we could have enforced this with types, this is hard, so it is enforced as a runtime error instead.

The original plan in https://github.com/sebastiaanvisser/clay/issues/259 was based on a type class. This worked correctly, but not nicely, because types could not be inferred completely. For example, if we did

aspectRatio (16%9)

the compiler would not know what type aspectRatio should accept yet. And it can't infer that 16%9 should be Rational or Ratio Int because it doesn't know whether 16 or 9 are Integers or Ints. We could resolve the deadlock by enabling type defaulting, but lots of code disable it (e.g., when turning on -Wall -Werror). So we would often have to do something like

aspectRatio (16%9 :: Rational)
aspectRatio (auto :: Value)
aspectRatio (auto :: Value, 16%9 :: Rational)

which seemed cumbersome, so I gave up on the approach based on a type class.

Generated Haddock documentation can be seen in clay-haddock.tar.gz. The examples in the documentation may seem odd, but they're written this way so that they can correctly be evaluated in case doctest is used one day to test the examples.

Resolves https://github.com/sebastiaanvisser/clay/issues/259.