Learn

Row Animations for Our Flex Grid

An extension of our flex grid system to animate each child in each row using an animation delay.

Written by Pete Wright

We use the flex-grid mixin a lot here at Urban Influence. We needed a way to animate each child of each row of the flex-grid, so I wrote a mixin for it.

The mixin depends on the flex-grid mixin. I modified the original one that Steve came up with a couple months ago. I started to include an argument for x-small screens because sometimes I want 1 column on phones, but 2 columns on tablets. Without the x-small argument there would be the same amount of children per row on phones and tablets.

The flex-grid-animation mixin adds an animation delay to each child of that row. You have a row that has 4 child elements? You would see :nth-child(4n+1) to :nth-child(4n+4) which an increasing animation-delay for each one (0.1s to 0.4s). I use WOW.js to add an animated class when the element is in viewport, which triggers the animation delay that is set by the mixin.

See the Pen Flexbox Grid Animation by Thomas Vaeth (@thomasvaeth) on CodePen.

The Mixin


//---------------------------------------------- 
//  Flex Grid Animation - flex-grid-animation()
//  @description: Animation delay for flex grid
//  @param:       $xs, $sm, $md, $lg, $xl: [null] - Media sizes
//  @param:       $delay: [0.1s] - Animation delay of child elements
//----------------------------------------------
@mixin flex-grid-animation($xs, $sm, $md, $lg: null, $xl: null, $delay: 0.1s) {
  
  & > * {
    $count: 1;
    @while $count <= $xs {
      &:nth-child(#{$xs}n + #{$count}) {
        animation-delay: $delay * $count;
      }
      $count: $count + 1;
    }
      
    @media (min-width: $mq-small) {
      $count: 1;
      @while $count <= $sm {
        &:nth-child(#{$sm}n + #{$count}) {
          animation-delay: $delay * $count;  
        }
        $count: $count + 1;
      }
    }

    @media (min-width: $mq-med) {
      $count: 1;
      @while $count <= $md {
        &:nth-child(#{$md}n + #{$count}) {
          animation-delay: $delay * $count;  
        }
        $count: $count + 1;
      }
    }

    @if $lg {
      @media (min-width: $mq-large) {
        $count: 1;
        @while $count <= $lg {
          &:nth-child(#{$lg}n + #{$count}) {
            animation-delay: $delay * $count;  
          }
          $count: $count + 1;
        }
      }
    }

    @if $xl {
      @media (min-width: $mq-xlarge) {
        $count: 1;
        @while $count <= $xl {
          &:nth-child(#{$xl}n + #{$count}) {
            animation-delay: $delay * $count;  
          }
          $count: $count + 1;
        }
      }
    }
  }
}

//---------------------------------------------- 
//  Media Queries
//----------------------------------------------
$mq-xsmall: 22em;
$mq-small: 32em;
$mq-med: 54em;
$mq-large: 65em;
$mq-xlarge: 91em;

Usage

The idea is to match the arguments of the flex-grid with the flex-grid-animation. These mixins could be combined if you really want to get down to it, but I wanted to keep them separate because not every flex-grid is being animated across all of our projects.


.flex-grid {
  @include flex-grid(1, 2, 3, $xl: 4, $pad: 1em);
  @include flex-grid-animation(1, 2, 3, $xl: 4, $delay: 0.2s);
}

The mixin takes 6 arguments.

The first 5 are related to the number of columns across 4 breakpoints ($xs, $sm, $md, $lg, and $xl). 2 of the sizing arguments are optional ($lg, $xl), so you can add just what you need without generating any extra output.

The last argument applied the animation delay, which defaults to 0.1 seconds.

Demo & Documentation

Demo

Flex-Grid Mixin

WOW.js