On Building My Own CSS Framework - Flexbox Layout

css Apr 16, 2021

On my previous blog post, I shared my intent of making my own CSS framework and also started working on the names for different SCSS files. Today, I am going to focus on other areas of building my CSS framework...I will work on Layouts and other stuff. Come along

My CSS framework will be Flexbox based. I won't use Floats or CSS Grids. In general, I will have a combination of two columns, three columns and four columns in styling my layout. In two columns, a container will have equally divided columns with each having a width of 50%. The same applies for three columns (33.33% each) and four columns (25% each)

I decided to go with only four columns because those are the most that you're going to use most of the time. And even when you don't want to use only those you can easily configure your own flex-basis with the width of your choice.

Layout Classes Applied to the Flex Container

The first thing on laying out our elements is to make sure our container has a display property of flex. It's optional though. If you don't want a flex container you can leave it out.

//This class should be used in a container which we want to display flex

.display-flex { display: flex}
Display Flex in Flex Container

Center Elements Vertically in Flexbox

If you want to center elements in a flexbox container, here is what we will do. We're going to align all our items to center by putting a class "flex-center-v" to the container. Aligning items to center make them vertically aligned inside the container. Also you should know, it's hard to tell if they're centered vertically if your items or container doesn't have a height. You can try by just assigning the height to one of the items. And in that case, the flex container will also take the heights of the highest element.

Center Elements Vertically in Flexbox Container
.flex-center-v { align-items: center}

Center Elements Horizontally in Flexbox

We can also center our elements horizontally, and we do that by using a class "flex-center-h" and that means center elements horizontally.

.flex-center-h { justify-content: center}

Center Elements Vertically and Horizontally in Flexbox

Now, even sweeter and what will come so handy is to center the elements in both ways, horizontally and vertically, and here we gonna use the class "flex-center-both" meaning it should center in both directions.

.flex-center-both { 
	align-items: center;
    justify-content: center;
}

While we're still centering our items, I would like to introduce another handy class, this class will combine a few properties and values, first it will set any container to flex and after setting it to flex it should align all items inside both vertically and horizontally. This class is "display-flex-center-both" and it takes the following form:

.display-flex-center-both {
	display: flex;
    align-items: center;
    justify-content:center;
}

But what if you don't want to center the element? You may want to put them at the start (top) or the end (bottom). Here is what you should do. To align all the elements at the very top we will use the class "flex-start" and to align them at the bottom we will use "flex-end"

.flex-start { align-items: flex-start}

.flex-end { align-items: flex-end }
Flex Start and Flex End

And last but not least, if we want our elements to stretch and have the same height as the tallest element, we use "flex-stretch". This is also a default behaviour, so you don't need to set it.

.flex-stretch { align-items: stretch}
Flex Stretch

Spacing Elements in Flexbox Container

The property, justify-content gives us more power to work with flex-items. We have already seen how we can center elements horizontally using "justify-content: center". This property also allows us to space the elements instead of stacking them all at the center. And they take the following shapes;

We can put space between contents by assigning this class "flex-space-between"

.flex-space-between {justify-content: space-between;}

Or we can put space between all the items by assigning the class "flex-space-around"

.flex-space-around { justify-content: space-around; }

Or sometimes we can space them using a new property that was added to Fkexbox layout and that property is gap. Gap works just like margins by putting a gap between elements. So here we are going to use the class "flex-gap-"

.flex-gap-5 { gap: 5px;}

.flex-gap-10 { gap: 10px; }

.flex-gap-15 { gap: 15px; }

.flex-gap-20 { gap: 20px; }

.flex-gap-30 { gap: 30px; }

And while we are here in spacing elements, let's add one more class that will be used when making our navigations. Normally in navigation we have a logo and a main navigation as part of our top/main header element. So to simplify the process of putting the logo to the left and the main nav to the right, let's use the class "display-flex-space-between" and this should put the space between our logo and our main nav.

.display-flex-space-between {
	display: flex;
    align-items: center; /*in case the logo has a high height, all items will be centered vertically */
    justify-content: space-between
}

Layout Classes Applied to the Flex Items

When we want to ovarride the alignment set by the flex container, we can use a property called "align-self" to an individual flex-item.

So let's say we want to align just one element either to the top, center, or bottom. We use the following classes:

.flex-self-start { align-self: flex-start}

.flex-self-stretch { align-self: stretch }

.

Changing the Order of Flex Items

Sometimes you may need to change the order of your flex items for whatever reason. Maybe you want the last one to be the first and vice versa, flexbox layout allows us to do that. The default value for all elements in a flex container is zero (0). So if we want to change the order of those items, we need to specify a number greater than or less than zero. Elements with order less than zero become the first ones, and the ones greater than zero becomes the last ones

.flex-order-0 { order: 0}

.flex-order-1 { order: 1}

.flex-order-neg-1 { order: -1}

The Flex Property to Size Items

When we want to size flex items with a specific width, we wont use the width property when dealing with Flex Items, instead we use flex-bases

Flex Basis - 50% width column

This class will be donated by flex-50, meaning it's a flex item with a width of 50% or a half of the container width.

//A column (flex item) with 50% width

.flex-50 { flex-basis: 50% }
50% width flex item

33.33% width column

This class will be donated by flex-33, meaning it's a flex item with a width of 33% or a third of the container width.

//A column (flex item) with 33.33% width

.flex-33 { flex-basis: 33.33% }
33.33% width flex item

25% width column

This class will be donated by flex-25, meaning it's a flex item with a width of 25% or a quarter of the container width.

//A column (flex item) with 25% width

.flex-25 { flex-basis: 25% }
25% width flex item

Note About Flex Width ( Basis | Shrink | Grow):

The advantage of using Flexbox Layout is that when we have a specific width for one flex item e.g 25%. We can easily set the width of another flex-item to be 75% by just having: flex-grow: 1 - this will force the whole column to expand and fill up the remaining width (100% - 25%). Cool! Right?

Now for my CSS framework, the class for flex-grow: 1 is going to be just flex-g meaning flex item should grow. Because by default flex-grow is 0 - meaning the flex-item doesn't grow.

// A flex-item is forced to grow to fill up the remaining width

.flex-g { flex-grow: 1 }
Flex Grow Property

If you don't set flex grow to 1, it will default to zero, meaning that elements will occupy the width to fit their content. But if we set to 1, and apply it to all elements, they will expand to fit the container. And if we set it to only one element that one element will expand to fit all the unoccupied space.

Alternatively, we can set flex-grow to be double or even triple by adjusting the flex-grow number to 2 and 3 respectively. And what that means that specific element will get double or triple of the remaining space within the container NOT necessarily double the size or triple the size of other elements.

.flex-g-2 {flex-grow: 2 } /*will occupy double the space*/

.flex-g-3 {flex-grow: 3 } /*will occupy three times the space*/

The same applies to flex-shrink. Flex-shrink determines if a flex-item will shrink or not. Now by default, flex-shrink is set to 1, meaning it forces an item to shrink if it doesn't fit the width of its container. In other words, flexbox forces to shrink the elements so that they fit the container.

There are scenarios when you don't want this. So because by default we know it's gonna shrink, we don't have to worry about that, we are only going to set up a class for when we don't want it to shrink

A class flex-ns, meaning flex-no-shrink will be used

// A flex-item is forced not to shrink

.flex-ns { flex-shrink: 0 }
Flex No Shrink Class

Flex-Basis is used to set up the width of an item. By default it's set to auto, we have already set all the flex-basis for our flex-items above so we don't have to worry about that now.

The defaults are: flex-grow: 0 | flex-shrink: 1 | flex-basis: auto (Just in case you were wondering - and they're in that order if you wanna put them in shorthand: flex: 0 1 auto;)

As a shorthand, I would like to introduce additional two classes that works just like "flex-ns" and "flex-g" and those are "flex-0" and "flex-1". This is because the flex property can take all three values at ones,  the flex-grow,  the flex-shrink, the flex basis, and and automatically it can determine which one is used.

.flex-1 { flex-grow: 1 }

.flex-0 { flex-shrink: 0 }
Flex Grow and Flex Shrink Classes

...

Please Note:

When it comes to growing and stretching, the two word are kinds similar and they can confuse at times. Flex-Grow means that the element is growing horizontally, while Flex Stretching is when by default the element stretches vertically. Stretch value comes from the align-items property.

What's next?

While we're still here on the layout...it's important to consider that the width that we have set will cause the flex-item to be next to each other. See below

A container with two items

As you can see above...the two flex items which have 50% width each do cover the whole container. There is no margin between them and also no padding at all. So in this scenario all the content, if it's text or images will be touching each other...a situation we don't want.

...

My CSS framework is slowly getting in some shape now.

To recap:

If we want to have a container with three items inside side by side, here is how our HTML will look like

<div class="container flex">
	<div class="flex-33">
    Item One
	</div>
    <div class="flex-33">
    Item One
	</div>
    <div class="flex-33">
    Item One
	</div>
</div>
HTML for three columns

Just like that, we should have a container with three equal-width items inside just like this:

A container with three columns

Ok...Part Two is over. My CSS framework is kinda starting to look good. We have our base and layout already. Let's see what's next.

...

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.