clock menu more-arrow no yes

Filed under:

Gliss: constraint based layout for articles

There are two key problems with percent based grids: First, text within percent based grids expands downward as the page narrows while images shrink. The other problem is that typography has to constantly be managed as line-length changes at every browser width under the max width. Both these issues can be managed with extra breakpoints as the design degrades, but each breakpoint is a jarring snap to a new set of rules.

As a solution we can set up a series of cascading constraints. Each constraint is built on a grid but retains its dimensions until it gets overridden by another, stronger rule. This concept is not new: Apple uses a system of constraints for app layout, and a somewhat similar system was proposed to be a part of CSS in 1999. Today, the CSS properties min and max width are lower and upper constraints that we can use to create this system. As an example, if you want an image to be 500px wide you can set that as one constraint, but as the browser gets smaller you can give it a max-width of 100% to override the initial width. This way the image remains small enough to fit in the viewport. Min and max width are relatively simple on their own, but when paired with calc() we can build a more complex structure around element width and how they sit on a grid. Note that media queries aren’t required, we simply need to know which elements exist and their constraints. Media queries can and should still be used as the layout will likely degrade to a point where a grid is no longer useful. The result should be simpler code that works better in more places as awkward medium screen sizes can have elements flow into place instead of snapping to a new layout for that context. In its simplest form, it might look something like this:

figure {
  width: 20em;
  max-width: 50%;
  float: right;
}

As a result of using this system, each element within a layout can shrink independently from one another allowing the text and images to retain their width as the viewport gets smaller. When a lower constraint is hit, elements shrink to that new constraint when they reach it, instead of all elements snapping to a new grid when the design starts to break down. As a result of each element shrinking independently, fewer breakpoints are needed. This is because the balancing act of text and images scaling in different directions is largely avoided. The grid is no longer forcing text and media to change dimension as the screen gets smaller so these elements can be left in a state where they look their best. Typography is a big win here as the main column of text can be the optimal width for a majority of viewport sizes. This allows designers to focus on line length and paragraph color in a way that a traditional fluid grid wouldn’t allow due to percent widths changing in all contexts.

Gliss demo page
Visit demo page

This system is designed for the layout of articles. While this approach may be useful in other applications it is designed to solve specific problems of content displayed in articles. Constraint based layout systems have proven their worth in application layout but this approach does not go far enough to be useful for these use cases. This approach focuses on content width specifically and does not add constraints to position elements or maintain awareness of an element's context. Grid Style Sheets offers more robust constraint based solutions for these types of applications.

While this system solves a number of problems, it also presents new challenges. Elements are based on the grid but as they are between constraints they do not align to a grid. When shown with grid lines, this can be off-putting. Jason Santa Maria stated that it reminded him of tweening in animation where there are two keyframes and frames in-between were generated to transition between these frames. Similarly there are two grid states and these in-between states may appear confusing to someone who sees them out of context.

The code behind the approach

As stated before, this leverages the basic behaviors of the CSS width and max-width properties. There is a constraint width and that constraint can get overridden when another, stronger, constraint takes precedence max-width. This is commonly used on images within responsive sites. The harder part is finding values for these two constraints that align to a grid. The lower limit sits on a fluid grid while the upper limit is a fixed width based on the maximum width the element will be. Figuring out the fixed width for the larger grid is fairly straightforward as you can divide the max width of the content into parts. The lower constraint is slightly more tricky as fixed width gutters are used: calc() would have to do part of the work to subtract the gutters from the percent based columns. This proved to be more difficult than expected; after plotting out estimates for what these gutter values should be revealed, I discovered that a rational function in Sass would output the correct gutter values for calc().

A plot of estimated values overlaid on the graph of the final function

This math can be then consolidated into a mixin, grid($min,$max) where you more easily define the lower and upper constraints on a grid and align the elements with floats around text. As the viewport changes size, elements will encroach on the column of text until they hit the lower constraint. These equations can also be combined in calc() to calculate a margin on a constrained text column and added to that width so images can align to both the text and the edge of the content area.

Input:

._third {
  @include grid(6,4);
}

Output:

._third {
  width: 26rem;
  max-width: calc(50% + -0.5rem);
}

Ultimately, this is the marriage of two relatively simple ideas. People have floated fixed-width elements into columns of text before and people have used max-width as a constraint before. The differences between this approach and other approaches is subtle, but hopefully it is a useful tool to help simplify article layout code while allowing for more consistent and better looking design and typography across screen sizes.

Update: Gliss is a thing we're playing with. It is experimental and exploratory.