Functional Web Layouts

Posted on 2014-10-10

Watching Strange Loop 2014 conference videos I was reminded about Elm, a functional reactive programming language for the web. One of my favorite features is the functional graphics. You can say things like flow up [item1, item2, item3] and they will appear vertically stacked in reverse order! The creator said in a talk that, being a traditionally server-side guy, while working on a layout issue he asked himself

"Why is this so... BAD?"

Functional programming has re-use and componentization at heart and that's something that web page layouts can really use right about now. Elm's way of doing layout is nice, but the DOM is generated by JS and AFAIK doesn't have a built-in way of doing responsiveness. However, I don't want to write about Elm.

A better web-design language

I want a way to declaratively scaffold my layout. I want to be able to say something along the lines of (insufficiently specific pseudo-code)

page = sticky_header(myHeader, 
           sticky_footer(three_columns(col1,col2,col3), myFooter))

Obviously... complex layouts can't be one-liners. Or can they? If you have a layout that you like and you want to reproduce it, then we really shouldn't have to strip the markup and styles out of a previous project in order to re-use it. When you write library functions, you can include them in a next project as a modular component (in most languages). If you have a web page component and you want to re-use, Bower doesn't really cover all of it. At least, it's not as straight-forward as writing a single import line. WebComponents bring you all the way there, but there are things about custom elements that I don't like and go against some of what I'm suggesting.

  1. sandboxed CSS stops you from fully customizing appearance
  2. sandboxed JS discourages re-use of functions and may balloon your code size from all the dependent libraries
  3. polyfills for older browsers aren't a perfect solution

However, if these do not bother you, then "yes", these will do the trick and I believe, down the line, WebComponents will be the dominant life-form on the web. Polymer provides some nice layout components to get you started. The unfortunately named Mozilla Brick has some too. On a sidenote: I hope there will be a way to (intentionally) affect styles of elements inside of shadow-DOM. Using a special CSS selector is the simplest solution I can think of.

Another solution I considered and dismissed is GSS. Grid Style Sheets have JavaScript doing the layout, which isn't ideal when it comes to supporting low-end devices. That and, despite how expressive it is, when it comes to layout, it's not addressing the reusability problem.

Functional responsive layouts

I want to express layout ideas in a composable way. Responsiveness is a challenge, because I find it difficult to think of a way to declare a responsive layout in a simple way that doesn't boil down to specifying a rule for each screen/media-query. In any system where we can define the structure of the DOM, we can't freely re-structure it with a second declaration without adding JS functions to manipulate it. This is because true source order independence and and hieraarchical independence are a thing. This is a big challenge in RWD. With current techhnology, restructuring the DOM gets you FOUC'd and you need resize event-handlers that could adversely affect performance. So, in order to work with the current state of browsers and HTML/CSS in a way that doesn't rely on DOM manipulation, the structure of the document would have to remain constant and only the flow vary by screen type. E.g.

page = respond [item1, item2, item3]
    @min-width: 200em 
        flow right full-height [20em, fluid, 20em]
    @max-width: 199.999em
        flow down full-width [default, default, 20em]

In this example, which is hopefully self-explanatory, the items are listed once because they are the same for each rule. While the media queries each have their own flow definition. I'm not sure if I would have come up with this syntax/example if I wasn't inspired by Flexbox.

Flexbox

Even though many sites still aim to target < IE10, it is not completely unthinkable to use Flexbox. Because of its expressiveness you can achieve many of the familiar layouts with only a single list of DOM elements. It reduces the need for nesting your content blocks into utility-DIV's. Unnecessary DIV's can make it harder to be responsive without manipulating the DOM. However, in many cases it's not required to use Flexbox to achieve certain layout variations. For example this sticky footer solution have only a single extra DIV, which can be ignored when reflowing. However, when would you want is a sticky footer to not be a sticky footer anymore?

Now what?

Maybe there already is something like this and I just don't know it yet. In the sea of UI markup languages, I don't see one that converts to HTML other than GWT's UiBinder, which doesn't abstract away layout. If there IS something, then nothing happens next. If I can't find anything that generates HTML+CSS for layout from a layout-description, then I want to find out...

  1. which layout components are so common that they should be one-liners?
  2. what CSS techniques exist to achieve these layouts and what HTML structure is required?
  3. is it possible to freely switch between layout types with only CSS changes?
  4. what syntax can we use to declare these responsive layouts?
  5. can this all be done without making each website look the same?