I'm working on a flexbox + calc() based grid system with gutters in SASS.
You define your grid via mixins like so:
.box {
@include column('1/3', $gutter: 20px);
}
Compiled this will be:
.box {
width: calc(99.999999% * 1/3 - 13.33333px);
}
I'm trying to find a way get rid of the classic .row containers.
In my mind this should be super simple with flexbox + calc() but I have this strange bug (or an error in my caculations?) which sometimes break the layout when multiple rows should be created.
As an example:
I want a grid with a 20px gutter between the columns.
The rest is best explained in code, so here's a pen:
http://codepen.io/NilsDannemann/pen/OMBVry?editors=1100
Why is the last example (1/8 - multi row) breaking?
Okay, heres whats happening: the Problem is not rooted in the flexbox space-between
property, but comes from flexbox' behavior in general.
Flexbox always sees the gutters as available space. So in the last example it combines them (7 * 20px = 140px) and concludes that there is enough space to fit another item (width after calc() = 107.5px) on the first row.
This is were the whole thing falls.
space-between
then does it's job as intended.
I think the only way around that is (as @Siguza pointed out) to add margins to fill the gutters. Then use an :nth-child selector to set the last margin of a row to 0.
In SASS this would look something like this:
.box {
@include column('1/8', $gutter: 20px);
margin-right: 20px;
&:nth-child(8n) {
margin-right: 0;
}
}
Now it becomes a SASS challenge:
How do I get the :nth-child
(whole number) from the passed fraction?
With some effort I have solved this. :-)
Heres the pen with the current SASS version of the grid:
http://codepen.io/NilsDannemann/pen/OMaOvX?editors=1100
Wow! This works great!
A multi-column grid with a completely clean DOM!
No .row
classes or .eigth
classes. Feel free to play around with the mixin (change the fraction or the gutter).
Heres the sad part though:
Try uneven grids like this:
.box1 {
@include column('2/8', $gutter: 20px);;
}
.box2 {
@include column('4/8', $gutter: 20px);;
}
.box3 {
@include column('2/8', $gutter: 20px);;
}
Now the :nth-child is wrong and the whole thing breaks. :-(
If we can solve this (without introducing another variable to the mixin) we would have one of the cleanest any intuitive grids I have seen to date. But this last problem is a tough one.
I'm not sure if it can be done at all.
Any SASS-Genius out there to help?
Flexbox is inherently a one dimensional layout model. Flex items within a flex container can be laid out either horizontally or vertically, but not both. If you want to lay out items in both dimensions, you'll need to nest a flex container inside another one.
One of the major drawbacks of using flexbox is performance issues. The use of flexbox can increase the page loading time if you have a larger project. You can compare the page loading time through Chrome development tools using the flexbox and the same pages constructed without using flexbox.
For 3 items per row, add on the flex items: flex-basis: 33.333333% You can also use the flex 's shorthand like the following: flex: 0 0 33.333333% => which also means flex-basis: 33.333333% .
The problem boils down to the definition of justify-content: space-between
.
8.2. Axis Alignment: the
justify-content
propertyThe
justify-content
property aligns flex items along the main axis of the current line of the flex container.space-between
Flex items are evenly distributed in the line.
source: https://www.w3.org/TR/css-flexbox-1/#justify-content-property
So, in your code, flex items will align per the rules of space-between
, even when they wrap.
Extra space will be distributed differently depending on how many flex items exist on the line.
In your example illustrating the problem, you have nine flex items on the first row, and seven flex items on the second row. The second row has more extra space to distribute. Hence, the gutters are wider.
There are a total of 16 flex items in that container. Add two more, and everything aligns perfectly.
Revised Codepen
A few more considerations:
Flexbox is not built to serve as a grid system. The W3C is developing the CSS Grid Layout Module for this purpose.
Instead of width
for defining the size of your flex items, consider using the flex
property, which will enable you to control the width, as well as the flex-grow
and flex-shrink
factors.
Although it doesn't seem to be causing a problem in the codepen, using line comment syntax (\\ comments
) is invalid in CSS and has the potential to break your code. It's safer to use the standard CSS commenting method (/* comments */
). More details here: https://stackoverflow.com/a/34799134/3597276
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With