Sushi Roll

PostCSS plugin for flexbox-based layouts

Source code on GitHub

What is it?

Sushi Roll is a PostCSS plugin which creates fixed or fluid flexbox-based layouts with a single line of CSS.

Set the sushi-roll property on a container to define the widths of its children.

Check out the examples below!

Installation & Usage

To install Sushi Roll, run:

$ npm install -D sushi-roll

Then include it in your PostCSS plugin chain, like you would any other plugin. There are currently no options to configure.

If you're new to PostCSS but want to try Sushi Roll, install postcss-cli and try it like this:

$ npm install -g postcss-cli
$ npm install sushi-roll
$ postcss --local-plugins -u sushi-roll -o output.css input.css

For maximum compatibility, use some sort of Flexbugs fixing plugin for PostCSS, I'm not sure which one is the best to be honest. PostCSS Flexbugs Fixes seems good.

Cheat sheet

If you are already familiar with flexbox, the following says it all:

sushi-roll flex-basis flex-grow flex-shrink
100px 100px 0 1
>auto auto 1 0
~20% 20% 1 1
=5em 5em 0 0

Documentation

In all of these examples, the HTML is:

<ul id="example-1">
  <li></li>
  <li></li>
  ...
</ul>

Unless otherwise stated, the number of li child elements is equal to the number of values passed to sushi-roll.

I've applied some simple styling to the examples in addition to the sushi-roll property. Sushi Roll only handles flexbox-related CSS properties, unless otherwise stated.

Basic layout

sushi-roll: 100px, 25%, 15em;

We have a ul with three li elements, just as described in the beginning of the documentation. We apply the above sushi-roll property to the ul element, which puts the three li elements in a row.

Note that Sushi Roll works with all kinds of elements, not just list elements.

sushi-roll: 100px;

If you pass just one value to sushi-roll, that value will apply to all child elements, regardless of how many there are. In this case 100px applies to all three boxes.

sushi-roll: 50%;

In this case, we have three li elements that all wish to take up 50 percent of the container width. They can't fit! But since they're all happy to give away space to their neighbors, they share the width equally among themselves.

This is the default behavior. None of the boxes will grow past their requested sizes, regardless of their content, but they will shrink to fit into the container if needed.

Prefixes and box behaviors

sushi-roll: 300px;

By default, a box will never exceed the width you give it. However, if the container gets full, it will start "giving away" space to other boxes, trying not to overflow the container. This can be seen in the example above, where none of the boxes actually fit, but share the avaiable space.

sushi-roll: =300px, 300px, 300px;

If you prefix a value with =, as in =300px, the box will refuse to give away space. It'd rather overflow the container. It is still not greedy though and will not take more space than it requested.

sushi-roll: >100px, >100px, 100px;

To make the box greedy, use the > prefix. In the example above, all three boxes fit within the container, but two of them are greedy, sharing whatever the last box didn't take.

sushi-roll: >100px, 100px, ~100px;

The last prefix is ~, as in ~100px. This makes the box a bit of a nihilist, in that it doesn't really care either way. It'll ask for 100 pixels, but if there's only so much space, it'll gladly take less. But if there's any left-overs, it will be there!

I couldn't really think of a great example for ~, please do come up with one for me!

Work in progress

This documentation is incomplete, as the project is work in progress.

Tips & Information

About box-sizing

In Sushi Roll, every child element gets box-sizing: border-box applied to it. This makes it much easier to work with paddings and borders without worrying about the surrounding layout.

Output size

If you're worried about output size, use a CSS minifying step in your build process. If it's still too heavy after that, send me a pull request with your solution to the problem and we'll both be happy!

Ideas for the Future

I'm hoping to implement some related useful functionality in the future, including but not limited to:

I'm not sure if they'll ever happen, but I'm very open to hearing other possibilities.