focused breathing - A CSS animation to help with meditation and focused breathing exercises
Tags: dohackathon, css, html, javascript
Published: 2021-01-11 02:35:08

---
title: focused breathing - A CSS animation to help with meditation and focused breathing exercises
published: true
description: An experiment in CSS Animations
tags: dohackathon, css, html, javascript
canonical_url: https://shannoncrabill.com/blog/focused-breathing/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/zm9i775q650w89o5det1.jpg
---

---

## What I built

My Digital Ocean / DEV hackathon submission is *[focused breathing](http://www.shannoncrabill.com/focused-breathing)* a CSS animation to help with meditation and focused breathing exercises. 

## Category Submission

Program for the People

## App Link

[focused-breathing-ogh7t.ondigitalocean.app/](https://focused-breathing-ogh7t.ondigitalocean.app/) or [shannoncrabill.com/focused-breathing](http://www.shannoncrabill.com/focused-breathing) which redirects to the app hosted on Digital Ocean.

## Screenshots

Screenshot of *focused breathing* in its default state.

![https://dev-to-uploads.s3.amazonaws.com/i/58lh7qq52nv5258y9st2.png](https://dev-to-uploads.s3.amazonaws.com/i/58lh7qq52nv5258y9st2.png)

The timing of the animation (expanding, holding, and contracting) is set to 8 seconds by default. The timing can be changed using the input field.

Here's a gif of the app in action.

![https://dev-to-uploads.s3.amazonaws.com/i/3qy903gwz9cfkz9siett.gif](https://dev-to-uploads.s3.amazonaws.com/i/3qy903gwz9cfkz9siett.gif)

## Description

**focused breathing** includes a circle div that expands for 2 seconds, holds it's shape for 2 seconds, then contracts to its original size for 4 seconds. The breathing exercise involves inhaling through the nose as the circle expands. Holding the breath. Then exhaling through the mouth as the circle contracts.

## Link to Source Code

{% github scrabill/focused-breathing no-readme %}

## Permissive License

[MIT](https://choosealicense.com/licenses/mit/)

## Background

I recently learned about focused breathing exercises as part of a meditation or calming routine. I kept forgetting the timing of how long to inhale, hold long do I hold, etc. So, I decided to make a little app to help me with the pacing. 

I've been having fun experimenting with CSS animations and thought this would be an excellent opportunity to learn about the `animation` property, transitions, and `@keyframes`.

### How I built it

I built `*focused breathing*` in two parts. The first version was an experiment with CSS animations and `@keyframes`. I wanted to see if I could achieve the transitions and cadence I wanted with only HTML and CSS. It was possible! No Javascript was needed for the original version, which can be found on CodePen. 

For the second part, I wanted to see if I change the duration of the animation (which is in the CSS file) based on input from the user. I know I could get input values from the HTML file with Javascript, but could I pass those updated variables back to the CSS and render it to the page. It turns out this was possible too!

Here's how I approached building parts one and two and what I learned along the way. 

### Part One - HTML & CSS

Before I started coding, I was helpful for me to write down high-level steps of the focused breathing technique I had been taught. 

It goes like this. 

- Inhale through the nose
- Hold the breath
- Exhale through the mouth for 4 seconds

The amount of time to inhale of hold the breath may not matter, but to make it easier from a coding perspective, 2 seconds to inhale and 2 seconds to hold a breath seemed reasonable.

Visually, there would be a small to medium-sized circle that would expand, cueing you inhale and contract when it was time to exhale.

#### Visualizing the Animation

Using `@keyframes` was the best want to handle the expanding and contracting of the circle so that I control the timing and pacing of each step. With `@keyframes` the stops or offsets range between 0% and 100%. The beginning or start of the animation would be 0% stop and the end would be 100%. Or, any number in between.

I've worked with `@keyframes` on other projects and had a difficult time visualizing what code I needed to write to achieve what I visualized in my mind. 

It makes sense to map out what I wanted to happen like a timeline. A line segment with two endpoints could represent the timeline of the animation. The left endpoint would be the beginning of the animation cycle and the right, the end.

Some quick labels, notes and visuals and I have a timeline that looks like this. 

[`https://i1.wp.com/shannoncrabill.com/blog/wp-content/uploads/2020/12/step3.png?resize=640%2C86&ssl=1`](https://i1.wp.com/shannoncrabill.com/blog/wp-content/uploads/2020/12/step3.png?resize=640%2C86&ssl=1)

#### Translating the Timeline to `@keyframes`

Looking at the timeline above, it may look like we need 8 or 4 steps in the animation, but this is not the case. Each offset point in a `@keyframe` animation is a point where properties can be changed *from their original values.*

The circle starts small, *then* it’s changed to be larger than it was originally, *then* it holds that size, *then* it shrinks down to the size it was originally and the animation starts over. The `@keyframe` only needs 2 offset points (at the `25%` and `50%` marks) and the original styling of the circle handles the starting (and ending) visuals.

Similar to grouping other CSS attributes, multiple properties and offsets can be set at one time within the `@keyframe` declaration. 

```css
@keyframes breath {
 25%, 50% {
    background-color: lightpink;
    width: 200px;
    height: 200px;
    border-radius: 100px;
 }   
}
```

And, to make it a bit easier on ourselves, let’s divide the line into 8 even parts (1 part for each second of the animation).

The timing of the changes and width and height of the circle meant that I couldn't 

The expanding and contracting of the circle can be handled with `@keyframes`. 

{% codepen https://codepen.io/scrabill/pen/QWKgRMr default-tab=result %}

### Part 2 - Javascript

For the second part of this project, I wanted to add some customization. To start, I wanted to see if I could change the duration of the animation—which was 8s to start—to another value. Building an input field was straight forward, but how could that value get updated in the `animation` property?

In doing some Googling, I was reminded that CSS variables *could* be accessed *and* updated with Javascript using `getComputedStyle` and `getPropertyValue`. I was already using CSS variables for colors and sizes, so created a new one for `timing`.

```css
:root {
    --timing: 8s;
}
```

And updated my `animation` property to include that variable (`var(--timing)`) instead of the hardcoded value (8s)

```css
div {
   animation: breath var(--timing) ease infinite none running
}
```

Visually, nothing changed, which meant it worked! I could double-check the value of `--timing` by running the following in the Console.

```javascript
getComputedStyle(document.documentElement).getPropertyValue('--timing') // 8s
```

And I could change it with the following and see the animation speed up dramatically.

```javascript
document.documentElement.style.setProperty('--timing', '1s');
```

Then, by adding an input field onto the page, I could grab the value of that input, pass it into `.setProperty` and update the CSS.

## Wrap Up

Overall, I learned *a lot* about `@keyframes` with this project! Drawing out what I had in mind made coding go smoother with less trial and error.

Looking back at this project, I tried for the first time, or became more comfortable with:

- CSS Grid (centering things, amiright?)
- CSS Animations (the `animation` and `@keyframes` property)
- Manipulating CSS variables with Javascript ( `getComputedStyle` and `getPropertyValue`)
- Continuous deployment (yikes to manually copy and pasting files like I usually do)

For future enhancements, some thoughts are:

- The ability to change other variables (hold time is longer, shorter, etc)
- The ability to start and stop (or, incorporate a timer for 5 mins of focused breathing, etc)
- Sounds or music so accompany to indicate when you breathe in, breath out, etc.
- A detailed tutorial on how to build your own focused breathing animation/app from scratch

## Additional Resources/Info

- [https://ggia.berkeley.edu/practice/mindful_breathing](https://ggia.berkeley.edu/practice/mindful_breathing)
- [https://www.tckpublishing.com/reduce-stress-with-focused-breathing/](https://www.tckpublishing.com/reduce-stress-with-focused-breathing/)
- [https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations)
- [https://davidwalsh.name/css-variables-javascript](https://davidwalsh.name/css-variables-javascript)
- [https://css-tricks.com/updating-a-css-variable-with-javascript/](https://css-tricks.com/updating-a-css-variable-with-javascript/)