Item-Grids: Lists and Grids of fixed-size items

TLDR: Doing the layout of item lists could be done more efficiently under a new layout model.

 

Why am I writing this mail ?

As some may know, one of the areas I’ve been working on in CSS has been the case of so-called infinitely scrollable lists. The issue is that, given the fact CSS layout is often “exhaustive” (aka: adding one element requires a lot of things to be recomputed), long list of elements often carry a large modification cost which makes scrolling jaggy in case of modification.

 

Recently, I considered a second case where this situation happen: 2d grids of tiles in Windows 8 apps, and many websites using an item-grid layout. For this kind of layout, Microsoft used some  JavaScript-based layout because the native CSS ones didn’t provide sufficiently good performances.

 

Quite a long time ago, I proposed “display: viewport” to solve this kind of problems. I still believe this is a good solution, and it was partially revived as Tab Atkins’s “Containment” proposal, but this only cover a certain portion of the problem, not the general item-grid problem, which can benefit from more optimizations.

 

In this mail, I describe a new, efficient layout system that covers the needs of those two use cases.

 

 

When can we use item-grid layouts?

 

My proposal applies when the following conditions are met:

 

-          Items have a known minimum size in at least one direction.

-          There’s a known minimum spacing between items in all directions.

 

Example in the case of a 1D list:

 

-          The items have a known minimum width of 100%

-          The items have a content-dependent height

-          The vertical spacing between items is 20px

-          The container has a known width

-          The container has a known height and is y-scrollable, or no known height

 

#list {

   

   display: item-grid;

   

   width: 100%;

   height: auto;

   

   item-width: 100%;

   item-height: auto;

   item-spacing: 20px;

   

}

 

Example in the case of a 2D grid:

 

-          Items have a known minimum width of 250px

-          Items have a known height of 500px

-          The vertical & horizontal spacing between items is 20px

-          The container has a known height

-          The container has a known width and is x-scrollable, or no known width

 

#list {

   

   display: item-grid;

   

   width: 100%; 

   height: 80vh;

   overflow-x: scroll;

   

   item-width: min(250px);

   item-height: 500px;

   item-spacing: 20px 20px;

   

}

 

 

How does item-grid layouts work?

For now, let’s suppose that the number of columns is fixed (the width of the container was known, and the writing mode is an usual one) : all the other cases are somehow a dual version of this one. 

 

Column-based layout:

The height of each item is computed (if items have a known height, this is easy because all will be stretched to fit and the item-height can be used, but if the item-height is auto, we need to layout the item given its width to extract its height). Each item is then added to the column whose height is currently the smallest (ties are resolved by column index).

 

Cases when the layout do not need to be computed:

Actually, because items are always positioned top-down, the UA can restrict himself to the layout of items before a certain threshold past the scrolling line. This is guaranteed by the fact each item is isolated in a box (i.e. absolute and fixed elements are absolute relative to their element box, floats have no effect outside the very same box, etc…) like if every item was in a “display: viewport” element or implemented some of the containment’s restrictions.

 

Content reordering or updates are contained:

Additionally, each item is clipped at its size plus half of the horizontal and vertical spacing on each side. The reason for this is that it allows to double-buffer the grid, and reuse portions of the previous rendering to render items that didn’t change since the previous render. For this reason, adding or removing elements in the list incur a very small cost, because all the other elements do not have to be repainted (except if sibling selectors require style updates to be performed), only the modified elements and the final ‘compositing’ have to be done again, where elements occupy their final location.

 

Summary:

I included a photo of a document I wrote today with a few schemas: 

https://skydrive.live.com/redir?resid=201F3835D49587FE!14543 <https://skydrive.live.com/redir?resid=201F3835D49587FE!14543&authkey=!APho4hyOsl9cyRM&v=3&ithint=photo%2c.jpg> &authkey=!APho4hyOsl9cyRM&v=3&ithint=photo%2c.jpg

 

 

Why is this a better model than just a grid?

Because it only allows a subset of the pure grid functionalities, you can be sure that by using it, you remain in the conditions of optimizability. It’s also easier because the number of columns can be computed automatically using an algorithm we regularly apply manually to create appropriate media-queries break points. Finally, it’s easier because columns are known to be independent to each other (there’s no vertical syncing of the rows lines). It also balances the content between columns in a very efficient way.

 

It is also better because it just solves the item-grid/item-list use case, while pure grids seem more appropriate when the cells have different sizes and content types, or cases where more custom constraints need to be applied, like those for which we created named lines.

 

 

I understand that working on a new layout model probably isn’t the priority right now for the CSS WG, but I believe the idea is worth having a look at. What do you think?

-François

Received on Friday, 6 December 2013 23:33:37 UTC