CSS Transitions, Animations, & Flexbox


Today I started my next course, the advanced web developer bootcamp. It covers a lot of topics that are high on my list to focus on in the next few months like ES6, React, and more. The course kicks off with CSS transitions and animations, something I’ve used only rarely and hadn’t really learned the basics of how to use them. Then we started on Flexbox. I’m really keen on learning CSS Grid (not included in this course), but I also hear a lot about how Flexbox and Grid can be used together, so this will be a helpful start!

jump to Flexbox

Transform & Transition

Transform lets you move, warp, rotate, and scale elements, for example:

transform: translate(20px, 20px);

translate moves elements along their X and Y axis, so this would have the effect of moving the element down and to the right by 20 pixels. If you only want to move something along one of the axes, you could use translateX() or translateY() as an alternative.

scale works similarly: scaleX() or scaleY() or scale(X, Y).

And rotate works in the same way, only you specify degrees to turn: positive degrees to rotate clockwise, or negative degrees to rotate counter-clockwise (example transform: rotate(45deg)).

One thing to note with all of these is that the transform by default runs from the middle of the element. If you want it to rotate or scale, etc. from a certain point, you can define that point: transform-origin: 0 0;.

Transition is the property that defines how a transform should behave and there are four main properties:

  • transition-property: which properties should be affected by the transition
  • transition-duration: how long the transition should take
  • transition-timing-function: how the transition should be applied
  • transition-delay: whether you want any delay before the transition begins

These can also be chained under one transition property:

transition: opacity 0.5s ease-in-out 300ms;

One note about timing functions, these can be as simple as linear time or as specific as you want with custom timing cubic-bezier functions. There are some great examples of the default options at easings.net, or you can create your own with a tool like Ceaser.


Animations work similarly to transitions, only you identify multiple stops during the transition, instead of just what you should see at the beginning and end. These stops are called keyframes. Here’s the basic setup to change the size and appearance of text over a 5 second period:

p {
animation-name: rainbowtext;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 0s;
animation-iteration-count: infinite;

@keyframes rainbowtext {
font-size: 20px;
50% {
font-size: 40px;
transform: translateX(200px);
color: green;
color: blue
100% {
color: purple;

So it’s in two steps:

  1. Define how the animation should behave.
  2. Identify what you should see at each keyframe during the animation.

You can have as many or as few keyframes as needed to pull off the effect you want.

There are some additional animation properties which are unique to animations (and some Codepen pens for demo):

  • animation-iteration-count: how many times it should animate, or it can be infinite
  • animation-fill-mode: what happens right before & after the animation (demo). Options are forwards, backwards, both, and none
  • animation-direction: a way to re-use animations without having to re-write them entirely, options are forward, reverse, and alternate
  • animation-play-state: whether an animation is running or not, options are running and paused

One thing it’s worth noting with animations: there are four animations that are the most efficiently loaded by browsers: translate(), scale(), rotate(), and opacity. Other properties require the browser to do a lot more in order to render properly so the intended effect may not always be carried out flawlessly. More reading about that can be found in this article.

To put all of this together we created an animation of the sun rising and setting, where the sun and sky both change colors throughout the day. Here’s how mine looked, and here was the final solution of what it was going for. Not too far off as a first attempt! The big thing is remembering that both time and position have to be calculated if they are to remain linear…my first attempt had the sun jumping across the sky because the X-axis change wasn’t consistent between keyframes : D

Finally, animations can be compressed into one line in the same way transitions can:

animation: rainbowtext 3s forwards linear infinite 0.5s;

The order is flexible but there are some rules:

  • The first time that’s encountered will be made the duration and the second will be made the delay
  • The first word will be parsed as the animation name


To use Flexbox, divs must be placed within a container div, which is given a display of flex:

<div class="container">
<div class="header"></div>
<div class="body"></div>
<div class="sidebar"></div>

Here the CSS would be .container {display: flex;}. Then all of the container children move around based on the other flex properties you set. Terminology-wise, the container becomes a flex container and the children are flex items. How the flex items move will depend on what you identify as the main axis and cross axis.

The main properties to working with Flexbox are:

Container Properties

  • flex-direction: determines where the flex items start and which direction they go from there. Default is row (left to right). Other options are row-reverse (right to left), column (top to bottom), and column-reverse (bottom to top).

  • flex-wrap: specifies whether items should be forced onto one line, or if they can wrap to the next line. Default is nowrap. Other options are wrap and wrap-reverse (changes the cross axis direction).

  • justify-content: determines how items should be distributed within the space along the main axis. Default is flex-start which puts empty space last. Other options: flex-end puts empty space first; center leave space on both sides; space-between puts even space between items, with the first and last at the end; space-around puts even space around items, including at the front and end if space allows.

  • align-items: determines how items should be distributed within the space along the cross axis. Default is stretch which takes up all available space. Other options: flex-start puts empty space at the end of the axis; flex-end does the opposite; center puts items in the middle of the cross axis; and baseline which aligns items so that the text has the same position.

  • align-content: determines how space is placed between rows on the cross axis. The options stretch (default), flex-start, flex-end, space-between, space-around, and center work the same way as the items above.

Flex Item Properties

  • order: specifies how an individual flex item should be ordered within its container. By default all flex items have an order of 0.

  • align-self: allows you to override align-items for individual flex items.

  • flex: combines the properties below into one line in the order grow-shrink-basis

  • flex-grow: determines how unused space should be spread amongst flex items. Default is 0. It divides the empty space evenly, and then gives the number of space blocks to each item. So if you have three divs div1, div2, and div3 you can set div1 { flex-grow: 1;} and div2 { flex-grow: 3;}div1 will get 25% of the empty space and div2 will get 75% of the empty space; div3 will keep its normal size.

  • flex-shrink: determines how flex items should shrink when there isn’t enough room in the container. Default is 1. Setting flex-shrink: 0; says that that flex item should never shrink. Setting flex-shrink: 2; will shrink twice as fast as flex-shrink: 1;, etc.

  • flex-basis: specifies the ideal size of a flex item before it goes into its container

Putting It All Together

To bring all of this information together I built the “holy grail layout” from scratch and made it responsive. Here’s the pen (it includes some things I could do better next time around).

Up Next

Next in the course we build a demo website from scratch, then move on to async and AJAX. Should be an interesting week!