"Can you create a component for this?" is a question we design system folk hear all the time. To the outside world, the design system team can be seen as a component factory whose sole purpose is to churn out chunks of UI code that they can plug into their product often without consideration of the "greater good". We're used to these requests and can navigate their long list of requirements, hone in on the root cause of their problem, and provide a solution that helps both our customers and the wider business.

It's safe to say ns-column was not your typical request for a component. In fact, nobody actually asked for it to be created... But it did start with a request: "We need a four-column layout so that customers can compare our products of desktop screens". This was a solid request for a change to Nucleus; customers wanted to be able to see the difference between the different services we offered and as a business, we wanted to make sure our propositions were clear and easy to understand.

Where we were

As it was - the magical switch from 1 column to 3.

We like to work as close to the product teams as we can: it helps us see how they are using nucleus and we build empathy for the challenges they face when they are building solutions to help our customers. Thanks to this relationship, we had a suspicion that there's a bit more to this request, there were murmurings of dissatisfaction with our layout options and a potentially a desire for more flexibility. But this was the first time someone had created a request ticket.

As it stood, we only had one method of creating multiple column layouts; a "triple" class that would show 1 column on mobile, 3 columns on desktop, with a magical switch between the two somewhere in the middle. Before we started to speak to the product teams about our assumption, we performed an analysis on how the triple was being used.

We found that our current layout options were helping to create some poor UI's, especially on tablet and desktop-sized screens. Some of the things we found were:

  • On tablet devices, our cards were displayed at the full width of the viewport even though they only contained 4/5 words - these could have been switched to 3 columns at a smaller breakpoint
  • 4 items forced into a three column layout and a single widowed item - adding the option of 4 columns would allow these to all be in a row
  • 2 columns worth of content being forced into a 3 column layout and not making full use of the screen available

From this research we concluded:

We are encouraging users of the design system to pick the right component to complement their content. But even when users pick the right component the layout options provided by Nucleus prevent the components from complementing the content they contain.

Opening a dialog with the product teams and setting requirements

By now it was clear to us that by adding some flexibility to our layout options we could help teams improve the way they present their content. But we also needed to find out what the teams thought.

We were also aware that adding more flexibility means more work for the product teams. Are the teams ok with this? By providing more flexibility, we increase the level of effort that it takes to create a product, rather than using a single triple class, that handled everything for them they would have to pick from more options to better suit their content and would have to check their layouts on multiple screen sizes and not just the smallest and largest.

We presented our findings to the product teams and asked them what they thought:

  • they were aware of the challenges we found on the website and were just using what we had without thinking there was anything we could do to fix it
  • they were already checking their pages on multiple screen sizes so any extra effort to improve things was minimal

And, as usual, when talking with product teams ideas flow, more requirements are jotted down, and it's inevitable that scope creep settles in... However, of all the ideas generated we all agreed to the following requirements:

Requirement 1: Only allow up to 4 columns on the largest screen

As we use mobile-first design, what's shown on larger screens should only be a rearrangement of what's on the page. We all felt that restricting it to four columns would encourage concise content and would prevent the temptation to go crazy with columns.

Requirement 2: Allow the teams to pick the number of columns and not let the design system pick for them

This is how the triple worked. Nobody liked the triple.

Requirement 3: Allow multiple columns within other components

The triple class could only be used in some components and there was a desire to set up multiple columned layouts within other components. E.g., within a tab and inside expanders/accordions.

Requirement 4: Multiple width columns

There are still parts of the British Gas website that are yet to be migrated over to Nucleus. One section of the website has a single column of links on the left and a double-width column containing an article on the right. Unless we had a way to provide this, then the upcoming migration task would be blocked.

Picking a solution

Initially, we considered using the 12 column grid (a classic pattern that's worth a google). This technique allows us to create multiple-width columns and comes with lots of flexibility. When working with a component library we've found that designers are more interested in the gaps between the components rather than how it aligns with the rest of the page - they expect that bit to come from the design system. The designer community liked being able to pick from many combinations of columns but worried that it might lead to some inconsistencies as it gave them too many options to pick from. From a technical side, we were also concerned that this technique would create redundant code e.g., we had no use case for someone wanting to make something only 1 column wide of a 12 column grid.

We also went back and forth on creating a number of CSS classes vs a component. Classes have the advantage that they are lightweight compared to a component, but they can be easily misused and pushed to work in "non-standard ways".

With the rate at which devices change in the market, we felt that a component would give us the power to keep up without the need to release a potential breaking change and force the product teams to change a number of classes and potentially refactor their app to support a new device.

ns-column FTW

The new ns-column component is a single flexible component that can be nested and can create many layouts. It allows teams to pick the number of columns they would like at any of our viewports, ensuring that layout changes are coordinated with the rest of the page, helping to build a cohesive experience.

Increase columns as the viewports get larger

The number of columns required can be defined for each of our viewports. In this example, we are switching from 1 column on mobile to 2 columns on tablet (hockeypitch) and then to 4 columns on desktop (rugbypitch).

Eg. Progressively increasing the columns for viewports.
<ns-column hockeypitch="2" rugbypitch="4">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</ns-column>

Columns of multiple widths

Multiple width columns can be created by passing a ratio into the viewport attribute. For example, passing in a value of 1:2 means that all even child elements have a width of 1, and all odd child elements have a width of 2.

Eg. Different width columns and ratios.
<ns-column hockeypitch="1:2" rugbypitch="1:3">
  <div></div>
  <div></div>
</ns-column>

Nesting

Not only can ns-column be nested in other components; it can also be nested inside itself to create more complex layouts.

Eg. Nesting columns for more complex layouts.
<ns-column rugbypitch="3:1">
  <ns-column hockeypitch="1:2">
    <div class="dark"></div>
    <div class="dark"></div>
  </ns-column>
  <ns-column hockeypitch="3" rugbypitch="1">
    <div class="light"></div>
    <div class="light"></div>
    <div class="light"></div>
  </ns-column>
</ns-column>

Further reading

Find out more about the ns-column component and see it in action: