The alternative layout library for Flex-box and CSS Grid

The alternative layout library for Flex-box and CSS Grid

If you’ve been looking for an alternative way to write Flexbox or CSS Grid, then Angular’s Flex-Layout might just be the library for you. This post will cover what Angular Flex-Layout is, how to set it up, and a basic overview of the Angular Flex-Layout library.

What is Angular Flex-Layout?

Angular Flex-Layout provides a layout API using Flexbox CSS and mediaQuery. This provides Angular developers with component layout features using a custom Layout API, mediaQuery observables, and injected DOM flexbox CSS Stylings.

The real power of Flex-Layout is the responsive engine. This responsive API enables developers to specify different layouts, sizing, visibilities and viewport sizes, and display devices.

Why choose Angular Flex-Layout?

As the name suggests [Angular Flex-Layout] is a library for laying out your components on your web page. The library does not provide a means for styling, fonts, or colours, as those tasks are delegated to traditional styling in your application. Angular Flex-Layout deals with component positioning and works well with or without Angular Material. It is also built by the Angular team and supported by the community.

Some of the main advantages for using Angular Flex-Layout are:

  • The library is a pure Typescript Layout engine.
  • Uses HTML markup to specify layout configurations.
  • Independent of Angular Material.
  • A responsive API can specify different layouts, sizing, visibilities, viewport sizes, and display devices.
  • Includes CSS Grid.
  • Requires no external stylesheets.

So, let’s have a look at Angular Flex-Layout.

Getting Started.

To install Angular Flex-Layout from the command line type the following into your project directory.

npm install @angular/flex-layout @angular/cdk

Next, we need to import this into app.module.ts. We have a couple of options, we can import both Flexbox and CSS Grid using the FlexLayoutModule or we can specify either FlexModule for Flexbox or GridModule for CSS Grid.

// Flexbox mode (only)
 import {FlexModule} from '@angular/flex-layout/flex';
 // CSS Grid mode (only)
 import {GridModule} from '@angular/flex-layout/grid';
 // Flexbox and CSS Grid (both)
 import {FlexLayoutModule} from '@angular/flex-layout';
 @NgModule({
     …
     imports: [ FlexLayoutModule ],
     …
 });

In this post, we will use the FlexLayoutModule.

Import FlexLayoutModule from the @angular/flex-layout library in your app.module.ts file as shown below.

import { NgModule } from "@angular/core";
 import { BrowserModule } from "@angular/platform-browser";
 import { FormsModule } from "@angular/forms";
 import { AppComponent } from "./app.component";
 import { FlexLayoutModule } from "@angular/flex-layout";
 @NgModule({
   imports: [BrowserModule, FormsModule, FlexLayoutModule],
   declarations: [AppComponent],
   bootstrap: [AppComponent]
 })
 export class AppModule {}

How does Angular Flex-Layout work?

Angular Flex-Layout works by dealing with one row or column at a time. Rows flow across the main axis and columns on the cross axis.

Note: remember that Flexbox is a single-dimensional layout (row or column), where CSS Grid is a two-dimensional layout (row and column).

We start by defining a row or column layout type using the Angular Flex-Layout directive fxLayout= “row” or fxLayout= “column”.

The options are:

API: fxLayout <direction> [wrap]
Allowed values: row | column | row reverse | column reverse
Wrap: is optional and can be applied regardless of the direction.

Content can be positioned on either axis by using another Angular Flex-Layout directive called fxLayoutAlign and this directive requires at least one value (main-axis).

API: fxLayoutAlign <main-axis><cross-axis>
Allowed values:
(main-axis): start* | center | end | space-around | space-between | space-evenly.
(cross-axis): start | center | end | stretch* | space-between | space-around | baseline.

*denotes the default values

The default for fxFlexLayoutAlign is “start stretch” (regardless of whether fxLayout is set to row or column), fxLayoutAlign= “start stretch” can also be shortened to fxLayoutAlign= “start”.

Flexbox — direction reference map

For a default Angular app using Angular Flex-Layout, add the following markup to the app.component.html file.

<div class="outerContainer">
  <div fxLayout="row" fxLayoutGap="10px" class="container">
    <div fxLayoutAlign="center center">1</div>
    <div fxLayoutAlign="center center">2</div>
    <div fxLayoutAlign="center center">3</div>
    <div fxLayoutAlign="center center">4</div>
  </div>
</div>
.outerContainer {
  padding: 5px;
  border: 1px solid #b6b6b6;
  box-sizing: content-box;
}

div.container {
  color: #eeeeee;
  margin-bottom: 10px;
}

div.container > div {
  height: 50px;
  width: 50px;
  background-color: blue;
}

The above markup creates the four numbered boxes shown below in image 1. I’ve added the above CSS to make it easier to see. Let’s walk through the HTML code.

We start with the directive fxLayout= “row” this sets the layout direction to rows. Setting fxLayout to “column” would stack the boxes vertically as shown in image 2.

Next, fxLayoutGap=”10px” sets the margin-right property on the containing DIV elements. The margin-bottom property is set if the layout direction is by columns. This produces a 10pixel gap between each blue box. Each DIV has fxLayoutAlign= “center center” this aligns the content horizontally and vertically, in this instance, the content is the numbers within each DIV.

Image 1: fxLayout=”row”
Image 2: fxLayout= “column”

Flexbox is ideal for moving items or content around the page, but it’s also responsive, so when the browser changes its size the contents on the page change size automatically. Likewise, when the browser is on a smaller (or larger) device the content can be displayed accordingly to the screen size using breakpoints, these breakpoints coincide with CSS mediaQueries. For example:

  • lg = screen and (min-width: 1280px) and (max-width: 1919.99px)
  • lt-xl = screen and (max-width: 1919.99px)
  • gt-md = screen and (min-width: 1280px)
  • gt-sm = screen and (min-width: 960px)
  • gt-xs = screen and (min-width: 600px)
<div class="outerContainer">
  <div fxLayout="row" fxLayout.sm="column" fxLayoutGap="10px" class="container">
    <div fxLayoutAlign="center center">1</div>
    <div fxLayoutAlign="center center">2</div>
    <div fxLayoutAlign="center center">3</div>
    <div fxLayoutAlign="center center">4</div>
  </div>
</div>

In the above code, the fxLayout.sm directive triggers the small breakpoint. When the browser gets to a certain size, for example: screen and (min-width: 600px) and (max-width: 959px) the row of blue boxes now becomes a column of blue boxes. We can also add these breakpoints to other directives like:

  • fxFlexAlign — element-specific overrides on the cross axis.
  • fxLayoutGap — defines padding of child elements in a layout container.
  • fxLayoutAlign — defines the positioning of child elements along the main and cross axis in a layout container.
  • fxFlexOrder — configures the positional ordering of the element in a sorted layout container.
  • fxFlexOffset — configures the “margin-left” of the element in a layout container.

Each of the above directives can include one or more of the following breakpoints.

.xs, .sm, .md, .lg, .xl, .lt-sm, .lt-md, .lt-lg, .lt-xl, .gt-xs, .gt-sm, .gt-md, .gt-lg

For example fxLayout.xs fxLayout.sm fxLayout.lt-md. There is a breakpoint to cover almost every possible display scenario.

The fxFlex directive resizes elements horizontally or vertically. We can specify this directive in one of two ways:

fxFlex= “<grow> <shrink> <basis>”

  • grow: defines how much an item should grow, if space is available.
  • shrink: defines how much an item should shrink if there is not enough space available.
  • basis: controls the default size of an element, before it is manipulated by other properties.

or using the shorthand method:

  • fxFlex= “” (or just fxFlex)
  • fxFlex= “1 1 5em”
  • fxFlex= “1 1 calc(5em + 5px)”
  • fxFlex= “1 1 auto”

Think of this shorthand version as MaxMin and Ideal.

As an example, we set the second DIV (line 4, in code below) to fxFlex= “2 1 auto”. This means that this DIV will take up twice the space as the other DIVs.

<div class="outerContainer">
  <div fxLayout="row" fxLayoutGap="1px" fxLayout.sm="column" class="container">
    <div fxLayoutAlign="center center">1</div>
    <div fxFlex="2 1 auto" fxLayoutAlign="center center">2</div>
    <div fxLayoutAlign="center center">3</div>
    <div fxLayoutAlign="center center">4</div>
  </div>
</div>

Image 3 using fxFlex

For the shrink, we have set this to one this means use the same space at all times, if we had set this to zero it wouldn’t shrink at all.

fxFlex=”2 0 auto”

The third value is set to ‘auto’ in the above example. The width or height of the content is used as the ideal size. This setting is shown in the following markup (line 4):

<div class="outerContainer">
  <div fxLayout="row" fxLayoutGap="1px" fxLayout.sm="column" class="container">
    <div fxLayoutAlign="center center">1</div>
    <div fxFlex="0 0 auto" fxLayoutAlign="center center">2</div>
    <div fxLayoutAlign="center center">3</div>
    <div fxLayoutAlign="center center">4</div>
  </div>
</div>

The default output appears below:

fxFlex=”0 0 auto”

We have covered most of the main directives in the Angular Flex-Layout library, there are a few others such as fxFlexOrderfxFlexFill, fxFlexOffset and fxFlexAlign which I may cover in a later post.

Summary

There is a lot more to the Angular Flex-Layout library than what I have covered here. The library also includes full CSS Grid support (though this is somewhat currently lacking in documentation, it is something I’m working to improve on). I will be doing a post on Angular Flex-Layout CSS Grid at a later date.