proportional fluid behavior / two dirty tricks

A few months back I talked about liquid row spacing, in that article I listed a series of viable options when implementing a responsive layout for row-aligned blocks. One thing not included in this list was the option to build proportional responsive blocks, blocks that would grow in height proportionate to their own width. There isn't a very clean way to do this in css, but of course that doesn't mean it can't be done at all. Here's how.

proportional responsive

There are a few scenarios where you'd prefer blocks to grow proportionally. Based on the extra vertical space this creates you could add extra content or redistribute your content for improved layouting. If you get passed the fact that you need to deal with handicapped media queries to get everything in order, this type of responsive behavior opens up some interesting possibilities.

For our example here we'll be building a list of 5 horizontal items. The list will need to fill the available space so each individual item is going to be 20% wide. The elements within the list will alternate between square proportions (1:1) and rectangle-sized proportions (2:1). A second list will demonstrate the result when each block has its own unique width.

method 1: proportional padding

/* html */ <section class="list"> <div class="atom"> <div class="inner"> <div class="content"> ... </div> </div> </div> <div class="atom">...</div> </section> /* css */ .atom {width:20%; position:relative;} .atom .inner {padding-bottom:100%;} .atom .inner .content {position:absolute; left:0; right:0; top:0; bottom:0;}

The first method is taken from Web Designer Wall and relies on proportional padding. The trick here is that vertical padding (top/bottom) of an element is based on the width of its parent. Exploiting this behavior, we could wrap the actual content of our block in a third container and span (pos:abs with all sides set to 0) it across the top parent (.atom) div.

A pretty neat solution, though it is quite container-heavy. Of course additional containers could always be added with javascript if needed, but it does create quite the nested dom-structure. Cross-browser support is dandy though, as it runs all the way down to IE7.

check the test page for proportional padding

method 2: proportional images

/* html */ <section class="list"> <div class="atom"> <img style="ratio1.gif" alt="" /> <div class="inner"> ... </div> </div> <div class="atom">...</div> </section> /* css */ .atom {width:20%; position:relative;} .atom img {display:block; width:100%;} .atom .inner {position:absolute; left:0; right:0; top:0; bottom:0;}

If you can't cope with the extra structural containers there is a second option, although it introduces a whole new level of resistance: spacer gifs. The only html element that is natively proportional in size is the image element, so if we place an image in the correct aspect ratio in each .atom and apply the same spanning trick as before, the result is again what we wanted. You save a structural element per sized block, but instead you gain a resource request for each new aspect ratio you want to support.

Once again, the images could be inserted using javascript, but the request load can't really be avoided. Browser support is once again pretty spectacular, as it also runs all the way down to IE7.

check the test page for proportional images

conclusion

Pretty it ain't, but both methods do work quite flawlessly. Coupled with smart media query planning this could make for some interesting interfaces, though I don't see it becoming popular very quickly because of the poor implementation quality and the practical challenges it introduces. So far we haven't really dealt with proportional containers before, though it would be nice to see people experiment with them.