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!
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.
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 |
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.
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.
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!
This documentation is incomplete, as the project is work in progress.
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.
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!
I'm hoping to implement some related useful functionality in the future, including but not limited to:
justify-content
and align-items
I'm not sure if they'll ever happen, but I'm very open to hearing other possibilities.