[ANN] Web-View Initial Release: Type-safe HTML and CSS

web-view is a library for type-safe HTML and CSS with intuitive layouts and composable styles. This is an idea I’ve been experimenting with for a few years, and I’m happy to finally release it! I’ve used this approach on multiple professional projects, and it is currently being used at the National Solar Observatory. It combines the best ideas of Tailwindcss and Elm-UI with Haskell.

myPage = col (gap 10) $ do
  el (bold . fontSize 32) "My page"
  button (border 1) "Click Me"

Instead of relying on CSS’s poor programming features, we can use normal Haskell functions to factor and reuse our app’s styles

header = bold
h1 = header . fontSize 32
h2 = header . fontSize 24
page = gap 10

myPage = col page $ do
  el h1 "My Page"
  ...

It has more features, including

Any and all questions or feedback welcome! The reasoning behind using utility classes for CSS is explained well here. Also, stay tuned in the coming weeks for the upcoming release of Hyperbole, a server-only interactive web-framework that leverages this library.

23 Likes

I’ve notice It doesn’t rely in lucid nor blaze-html nor clay to build html / css. Any reason for that or it was just simpler to build from scratch?

1 Like

I started to build on top of lucid and found it too difficult to think clearly about my data types during development. Lucid and blaze are building HTML as they go along, and I needed to think about building static data types that I later convert to HTML. I wanted to be free of constraints when brainstorming the most user-friendly syntax.

That said, now that it’s finalized, I’d love to switch to blaze under the hood. I’ll take a look tomorrow but it should be possible. We wouldn’t get much benefit from lucid since web-view completely replaces the syntax.

I remember looking at Clay years ago and deciding it didn’t work for what I was trying to do, but I don’t remember why. At a quick glance, Clay’s StyleM does look analogous to this library’s stylesheet representation. Would you think building on Clay would offer a higher-level escape hatch for users, better performance, or both?

3 Likes

You should at least offer a conversion function to the blaze Markup type besides renderText and renderByteString etc. so that web-view can be used alongside the many libraries that use this type for structured Html. If you do not want web-view to depend on blaze, offer it as a separate module web-view-blaze. The Raw constructor might be generalized to even embed blaze Markup into Content, so one can mix freely.

It appears that unlike blaze, web-view does not offer a function for each Html tag. Is this slated for further releases or is the approach to use raw a lot? From a type-safe Html library I would expect it to be a compile-time error when using a tag in a context where the standard does now allow it. But Html is a complicated standard, to that is a huge undertaking.

1 Like

I don’t have enough experience with neither html, css nor web programming to have an opinion :smile: I was just interested in the design decissions. Nevertheless, clay seems pretty complete and well documented, maybe It is a good match for your project too…

1 Like

Great ideas, thanks!

It’s definitely the plan to add more. It’s extremely easy to create new ones: h1 = tag "h1", so raw shouldn’t normally be necessary.

We want to work at one level of abstraction higher than HTML. For example, an anchor tag doesn’t work without an href. Any hyperlink function included in this lib should require a url as its first argument. Hyperbole, the web framework built on top of this which I’ll be releasing in the coming weeks, has a link function that expects a type-safe route as its first argument.

So the goal isn’t to create type-safety for the entire HTML spec, but rather to create practical type-safe functions that make web development easy. The layout functions and Tables are a good example of the approach I’m going for. Note how neither mirror the HTML spec, but are designed to be intuitive to use.

Any thoughts? Which tags/functions do you miss the most from the current set (besides a)?

3 Likes

I think you did well: You abstracted in a type-safe way the constructs that involve the most distinct tags/attributes and are therefore most tedious to write: Tables, forms and styling. In that respect one could regard the status quo as already quite feature-complete for the casual web developer. There may be always corner-cases where the provided abstractions do not fit, though.

1 Like

Very interesting. I love building web apps with Elm and elm-ui so I will definitely check your library out. Thanks for building it.

2 Likes

I know nothing about “front-end” development, so go easy on me.
QUESTION: will this library “work” with HTMX?

1 Like

Short answer: Yes! It was designed to work with HTMX.

Better answer: After using HTMX for a while, I realized some ways we could improve on HTMX by making some simplifying assumptions and leveraging Haskell’s type system. In the upcoming weeks I’ll be releasing an interactive server-only web framework called Hyperbole based on HTMX’s design principles but written especially for Haskell. It will integrate tightly with web-view

9 Likes