Flexbox and Sass Grid Tutorial: How to Streamline Responsive Design

Recently, I was challenged to create my own grid system and, since re-inventing the wheel is always useful as a learning experience, I went for it. I knew it would be an interesting challenge, but I was surprised by how easy it turned out to be!

In this experiment, we’ll look into Flexbox layouts and how they allow for graceful implementations of layouts without doing any crazy hacks. Also, if you’re not familiar with Sass, we’ll see how it works and use some handy Sass utilities. You might even learn something new about CSS grids like the one that is part of Bootstrap.

A Very Short Introduction of Sass and Flexbox

Sass is basically a tool that allows you to avoid some of CSS’s shortcomings, it’s a scripting language that gets interpreted to CSS. The syntax looks very familiar if you are already writing CSS styles but its toolbox includes variables, mixins for re-usability and if, for, each and while directives among others. One of the handiest things about Sass is that any valid CSS code is valid Sass, so you can progressively transform your code base.

This simple loop iterates from 1 to 3 and creates classes. The index of the iteration will be handily stored in $i. We can also do math and print the .a-numbered-class-X three times with different a different width each time. This code outputs:

As we can see, we can abstract a lot of the work you would have to do in CSS. In CSS, you’d have to copy and paste and modify manually, which is obviously more error prone and less elegant, If you haven’t tried it yet, don’t waste any more time!

Flexbox stands for Flexible Box, a CSS3 layout system that positions and distributes elements dynamically. It is a very powerful tool that allows for flexible layouts with minimal effort. For more details on how to learn Flexbox, check out Chris Coyier’s Complete Guide to Flexbox.

The Grid

Moving on to the grid itself, let’s start with its basic elements. They will be inspired by Bootstrap’s grid elements: Containers, Rows, and Columns, each contained within the former.

We’ll be using the BEM naming conventions for the classes’ names. BEM conventions are pretty simple to use and add a lot of information about the element and its context. Briefly put, you have:

Blocks, which “encapsulate a standalone entity that is meaningful on its own”: .block.

Elements, which are “parts of a block and have no standalone meaning” which are denoted by a the block name, two underscores and the element: .block__elem

Modifiers, like “Flags on blocks or elements,” which are represented with two dashes: .block .block--mod.

Containers

This is the outermost element of the grid, it will contain our row elements. There are two types of containers: .container and .container--fluid.

The behavior of .container is defined by being 100% of the width below a certain point, having a maximum fixed width above it and have equal margins left and right:

Things are starting to take shape, but this is no CSS grid yet. It’s missing…

Columns

Columns are where the content of the site lives. They define into how many parts the row is divided and how much they occupy. We’re going to do a twelve column layout. This means we can divide the row in one or up to twelve parts.

To start with, some basic math. When we want to have one column, its width should be of 100%. If we want twelve columns. Then each should occupy 8.333…% or 100/12 of the width.

With Flexbox, to distribute content in this manner, we can use flex-basis.

In order to divide in four columns, we now would add something like:

flex-basis: (100 / 4 ) * 1%;

This way, we can get the elements each to occupy 25% of the width—or whatever percentage we want.

Let’s make that more dynamic. Since we want this to reflect our possible classes, let’s call .col-1, a class for a column div that will have 8.333% of the width since twelve of them should fit before they have to wrap to a new line. The percentage will increment all throughout until .col-12, which will occupy 100%.

Screen Width-dependent Columns

We now want to be able to have an element that has a certain width on mobile but a different one on tablets and so on. We will use certain breakpoints dependent on the width of the window. Our UI will react on those breakpoints and adapt to an ideal layout catered to the screen sizes of different devices. We’ll name the breakpoints by size: small (sm), medium (md) and so on, .col-sm-12 will be an element that occupies 12 columns at least until the sm breakpoint.

Let’s rename the .col-* class .col-sm-*. Since our grid will be mobile first, we’ll be applying its properties to all screen sizes. For the ones that we need to behave differently with bigger screens, we’ll add the class: .col-md-*.

Imagine an element with .col-sm-12 and .col-md-4. The expected behavior will be that below the breakpoint “md” (medium) it will have 100% width and above it it will have 33.333%—a very common occurrence, since on mobile you might need to stack elements on top rather than next to each other when your width is much more limited.

For this, we’ll need to add a media query (an expression that contains code that will only execute above or below a certain width or on a specific device) at the breakpoint and create our md columns the like we did before for sm:

Our grid system is basically done! We have defined an .container__col-sm-* class that will be the default and we can modify its behavior on bigger screens with container__col-md-* and container__col-lg-*.

Notice how Bootstrap takes a more complete mobile-first approach than we initially discussed. The smallest window sizes have no suffix like sm or md, the reasoning being that the class equivalent to .container__col-X will not only be applied from a window width of 0 to 576px; if we don’t overwrite it explicitly, it will be that number of columns at every window size. Otherwise, we could add the class .container__col-sm-Y to make it a width of Y columns between the sm breakpoints.

Offsets

Offsets will add a margin left with regards to the previous column. A .container__col-offset-4 will add a margin-left: 33.333% on all screen sizes. .container__col-md-offset-4 will do the same but above the md breakpoint.

The implementation is now trivial; we add an -offset property on the same loop we create the classes, but instead of flex-bases, we write the property margin-left. We have to do an extra one for -offset-0 too, since we may want to clear out the margin on bigger screens:

As a side note, isn’t this one of the few good uses for !important? Notice that the element may have an arbitrarily greater specificity with a display: block rule, but we would still want to hide it below or a above the breakpoint. If you disagree with this approach, let me know in the comments!

About Author

Juan Manuel Varela

Juan is a very passionate front-end and back-end web developer whose specialty is making beautiful and responsive UX, focusing on usability and design. He has over a decade of experience in the field working independently, at startups and big companies/teams. He's worked on highly critical applications and under immense time pressure. He is a very friendly and communicative person who takes a lot of pride in his work.

Satz24 is the place for search your choice and add new data to the site,Here register user can share his/her thought with other and gain some extra knowledge / earn points / [ earn $ / Rs. ] and it help full for other people.