Conditional multi-column sublists
Some designers are able to operate in that universe where anything goes,
where the practicalities of implementation don't exist. This can
actually be a good thing at the beginning of the creative process;
without this no-limit thinking, the design process might yield less
creativity. Then again, many designers are fantastic at working within
constraints. At some point, though, either designers are confronted with
constraints and must accommodate them, or this is implicitly tasked to
developers. The latter is often the case, unfortunately. This almost
always leads to a series of little development puzzles. "How might I
implement this?" We can do a lot with CSS, but sometimes we need a
little help from JavaScript. I consider myself a designer who codes,
which, to be clear, means "not a programmer". Lucky for me, I have
programmer friends, and I read a lot. So while working on a recent
project, I encountered a design comp that called for a few adjacent
lists of "filters" (read: tags or categories). Each list had a heading
above it. (Note that the following examples are not indicative of the
visual design. Note also that they no sense on narrow screens, where the
lists could simply flow vertically.)
Lists.
Being as creative as the designer in the sense that I didn't burden
myself with such practicalities as browser support (yet), I figured I
could mock this up with Flexbox. Each section containing a header and a
list becomes a flex item, and let's let those wrap if they need to wrap.
Easy enough. Lists with Flexbox
applied (CSS).
Lists with Flexbox applied
(output).
In the design, some lists were longer than others. Lists with many items
were to be split into multiple columns. Flexbox was taking care of the
necessary flexibility of the main lists, but what to do about the
sub/lists that are too long? And can we have any flexibility in
determining what "too long" means? A simple solution for splitting a
list into multiple columns is CSS Multi-Column Layout. Implementations
aren't totally consistent, and I wrote some time ago about
some
of those inconsistencies, but the very basics are pretty usable right
now as a progressive enhancement to normal content. Lack of multi-column
simply yields a one-column list. If one were to set a specific height to
the containing element, multi-column would do it's thing automatically.
But I didn't like the idea of setting a specific height on anything. A
more content-centric approach would be to determine how many items a
list may have before it was split into columns. I'm fairly sure that
determining the number of columns as a condition of the number of
children is not currently possible with CSS. So in this case, it's
JavaScript to the rescue. I needed a function that takes whatever
element I'm using as a list, plus a maximum number of list items per
column, as parameters. It should look at each list, count the number of
items in it, and if the maximum number of list items is exceeded, it
should add a class to that list. The class allows application of the
correct number of columns via CSS. Here's the function, after too many
iterations, a beer, and another pair of eyes:
Here is the function.
And here's the result: Here is
the result.
This is not completely bulletproof, but it does allow for some
flexibility ("let's allow 10 items per column instead of five"). This
was a fairly simple problem to solve (though I won't be competing in the
Array.prototype Olympics anytime soon). But I'd like to say this:
/designers and developers should think about these types of
implementation issues together, and that should happen during the
design process. Not afterward, when stakeholders have fallen in love
with the design comps. This would allow for consensus on the baseline
experience (stakeholders tend to see design comps as the baseline).
Quick mockups in browser-based tools such as JSBin (which I used for
this example) or CodePen could help solidify these types of design
decisions, and allow both designers and developers to experience these
decisions on actual devices and to design for contingencies as well.
Special thanks to Jake and
Heydon for being kind enough to
review my example.
Comments
denis dupont
what about maxLines = 1,2 ?
thanks Best regards Denis.
Stephen
@Denis: not sure I understand your question.