Layout with CSS frameworks, post Responsive Web Design.
If the suggestion is made to add a CSS framework to a project I’m working on, my first response is always to try to understand why we would do that. To be honest, no answer to this question has ever really convinced me. That said, the same question asked on a large scale throws up a lot of answers, and some valid reasons, such as speed and documentation.
A question: if you have chosen to use a CSS framework (Bootstrap, Foundation etc.) for your project, what were the main reasons for doing so?— Rachel Andrew (@rachelandrew) October 16, 2018
One of the other big reasons, and one that I’ve heard myself, is “we want a grid system”. I think a lot of people actually equate CSS frameworks such as Bootstrap and Foundation to a way of delivering layout. Ironically, I think the biggest shortcomings of CSS frameworks are those of layout. I say this for two reasons.
The nature of a framework is to distill and homogenise. While this might make sense for components, it has proven to be unsatisfactory for layout.
which one of the two possible websites are you currently designing? pic.twitter.com/ZD0uRGTqqm— Jon Gold (@jongold) February 2, 2016
Using the word “grid” to describe the layout systems of CSS frameworks, at least the traditional ones, is to over sell them. Layout here can be distilled down to: How many columns do you want, and how wide should they be? Layout in Bootstrap for example is essentially the
.col- class. Well, it’s not just
.col-, it is also
.col-xl-. Which brings me to my second reason.
Layout is where most of the responsibility for handling screen size resides. For the past decade this has meant working with the techniques of “Responsive Web Design”. These techniques being: flexible widths, flexible images, and media queries. The first two of these techniques can be handled by a framework, without the user having to think too much about them. Media queries on the other hand don’t really fit with the framework philosophy of hiding the workings behind a class; and so we get this situation where every class created needs multiple counterparts that represent a handful of media queries. As I’ve discussed before, this type of approach has to add complexity that is hard to reason about, and/or limit the scope of design choices. So, going back to Bootstrap as an example, layout is probably about as complex as the developers would like to make it, yet all that is being facilitated is the ability to have a different amount of columns at a select few ranges of screen size. It wouldn’t be fair though to say that this is solely a problem of the framework, to an extent this is part of the philosophy of mobile first and responsive web design. I do think however, that the act of distilling this philosophy down to a few classes exacerbates the issue.
Intrinsic web design
The good news perhaps, is that we appear to be in the middle of a paradigm shift. If this is the case, the shift will mark the end of “Responsive Web Design”, and the beginning of what Jen Simmons last year named “Intrinsic Web Design”. Intrinsic Web Design essentially encapsulates the new layout techniques that are facilitated by the similarly new additions to CSS -
display: flex and
display: grid. More specifically, letting the browser do a lot more figuring out of how to best use available space, based in part on the intrinsic nature of the content. One of the results of this is layouts that respond to screen size, without the use of media queries. This responsive Mondrian by Jen Simmons uses no media queries, for example.
It’s not purely the absence of media queries that is striking about the above example, the code is also strikingly simple. When thinking about this stuff through the lens a framework, my first thought was “people don’t need a framework for layout anymore”. For this reason I initially decided that layout would not be a part of the framework / component library I was building. As I started to make some test pages, having to write additional CSS to arrange the components made the process feel less useful than something like Bootstrap, where you can get a long way without writing any CSS at all. The point where you have to start writing additional CSS is actually where I feel the use of a framework starts to become more of a hindrance than a help. It is where the code starts to diverge and become difficult to keep track of. Part of what I wanted to test with my framework was how far you can get within the confines of that framework; so I decided that layout should be a part of it.
Fortunately, in the world of intrinsic web design, layout feels much more compatible with the framework way of working. I’m thinking again about the moderately abstract frameworks here, like Bootstrap and Foundation. I call them moderately abstract because the components are just abstract enough to be generic, but not so abstract that components need to be constructed, as would be the case with a (totally abstract) utility first framework. With moderately abstract frameworks, a component looks something like this:
<div class="card"> <div class="card-body"> <p>I'm a card.</p> </div> </div>
So perhaps a layout should look something like this:
<div class="sidebar"> <div class="sidebar-side"> <p>I'm a sidebar.</p> </div> <div class="sidebar-body"> <p>I'm the content.</p> </div> </div>
The abstraction and complexity here is about the same as that of the component above. This is now a viable approach with intrinsic sizing; without the need to explicitly describe breakpoints in the selectors. In theory, a few simple primitives like this could be used in combination to create a variety of page layouts. This is in fact beginning to be demonstrated by the excellent work being done by Heydon Pickering and Andy Bell in Every layout.
In its simplest form, the sidebar in the above example would be however wide it needs to be for the content within it. You may of course want to specify this width explicitly, which adds a slight complication for a framework. This could be addressed in a number of ways. In my framework the approach would be the same as for components, in that the component (or layout) is an instance generated from a template and configuration file. You might have one instance of the sidebar layout called
has-subnav, configured with a specific sidebar width, and another instance called
has-meta which is configured with a different width and perhaps switches the sidebar to the right.
Using layout from a framework like this wouldn’t be appropriate for every use case, but using a framework isn’t either. This way of packaging up layout feels to me in keeping with the general scope of a framework; and potentially offers more bang for your buck (versatility for your complexity).