One opinion is that type safety should extend to styling as well. The libraries for
(a library similar to Redux and Elm) introduce type-safe CSS to PureScript. From the Pux docs:
CSS can and should be composed in a type-safe manner by using purescript-css and purescript-pux-css. Purescript-css provides a monad for specifying styles, and purescript-pux-css provides the css method for rendering to tuples, and a style attribute that takes CSS directly and returns an Attribute.
While type-safety seems neat, the library is pretty slugglish and in my opinion doesn’t offer more (but frequently less) than vanilla CSS. This is due to confirming each attribute’s naming (some follow React’s camelCase over hyhens), and creating some hacky solutions that mess with typeclasses in order to compile. For example, the
backgroundImage property has a different typeclass than the
backgroundColor property, which leads to limited styling of elements.
Still, once you get the hang of the syntax you can do some neat things, and have the comfort of type safety in the back of your mind. Below are a few components that show
purescript-css syntax and what you can do with simple CSS.
Box-Shadow Spread Radius
box-shadow property is commonly written with three parameters and a color. There is a little-known fourth length parameter for
box-shadow1 that makes the shadow larger or smaller. Because the
box-shadow property in
purescript-css only takes three Color values, we need to make our own function that can be applied with a fourth Color value. This will let us do a few cool things that don’t work out of the box with
pux-css, while also learning PureScript and CSS.
To start, add the fourth length parameter by importing the necessary attributes, either from the PureScript CSS repo or with
import CSS.Box at the top of your project file
Then, create a boxShadow function that takes a fourth parameter, rather than the existing three:
boxShadow :: forall a. Size a -> Size a -> Size a -> Size a -> Color -> CSS boxShadow w x y z c = prefixed (browsers <> fromString "box-shadow") (w ! x ! y ! z ! c)
Below is markup for the Pux view and a component using our new function. Each element takes two arrays: attributes and children. Once the boxShadow function is in place, you can do several different things.
For example, creating a shadow on a single side of a box:
resetButton = button [ style $ do backgroundColor (yellowgreen) boxShadow (0.0 # px) (5.0 # px) (4.0 # px) (-4.0 # px) (black) ] [ text "Reset"]
Or creating shadows “normally” on two adjacent sides:
resetButton = button [ style $ do backgroundColor (yellowgreen) boxShadow (3.0 # px) (3.0 # px) (6.0 # px) (-3.0 # px) (black) ] [ text "Reset"]
Next steps can includes figuring out how to pass a list of attributes (comma seperated in vanilla CSS) to
boxShadow to allow for shadows on oppsite sides, or multiple Glows, such as below:
Another component is one that relies on the
text-shadow property. This lets the user create a (somewhat corny) effect of glowing text due to a small shadow the same color of the text. Note that while in vanilla CSS, the
text-shadow property will inherit the color, but with PureScript the color must be explicitly stated.
import CSS.Text.Shadow (textShadow) resetButton = button [ style $ do fontSize (1.2 # em) fontWeight (weight 400.0) backgroundColor (rgb 34 0 51) textShadow (0.0 # px) (0.0 # px) (0.1 # em) (rgb 34 0 51) ] [ text "Reset"]
I originaly learned this material from Lea Verou’s CSS Secrets. It’s great and my go-to for CSS.
boxShadowin PureScript) ↩