React app which displays home, about, and contact pages for a fictional meditation events business. Inspired by following along with developedbyed in his Creative React and Redux course.

This app uses styled components for style, react-router-dom for page routing, and Framer Motion for animations.

Styled Components

To use styled components with the styled keyword, first styled-components must be installed (using npm or yarn).

Next, styled components were created and saved to a component using 1 of 2 methods:

  1. Using styled.div, styled.button, or similar to create styled HTML elements.
  2. Inheriting from another styled component, such as styled(Section).

The Sass-like styling rules for a styled component get wrapped in backticks, ```, and may use nesting.

Here’s an example of creating a new styled component called Work which inherits from a custom Section styled component.

OurWork.jsx

import styled from "styled-components";
import { Section } from "../styles";

const OurWork = () => {
  /** */
  return (
    <Work>
    // ...
    </Work>
  )
}

const Work = styled(Section)`
  color: #111;
  min-height: 100vh;
  overflow: hidden;
  a {
    color: #52489C;
    &:hover {
      color: #111;
    }
  }
  blockquote {
    font-size: 1.5rem;
    font-style:italic;
    position: relative;
    &::before {
      content: "\“ ";
      font-size: 2.5rem;
    }
  }
  img {
    height: 70vh;
    object-fit: cover;
    width: 100%;
  }
  @media only screen and (max-width: 320px) {
    blockquote {
      font-size: 1.1rem;
    }
  }
`;

export default OurWork;

Note that the styled component is located outside of the main component.

What I added beyond the tutorial

The focus of this project was to use Framer Motion to add page and component animations. The thing about animations is that they may not be accessible for some people, so I took the opportunity to do more research about making animations accessible.

prefers-reduced-motion

There is a CSS media query called prefers-reduced-motion which can detect whether the user’s browser settings requests the page to minimize motion. This is essential for zoom-type animatons such as pulse or transform, which can be migraine triggers.

The OurWork page has a rainbow animation that shuffles across the screen. Although it is not a flashing or zooming type of animation, I figured that it would be better to leave off if the user has requested reduced motion. For this reason, I added a display: none property on the prefers-reduced-motion query.

/** Rainbow Frame Animation */
const Frame1 = styled(motion.div)`
  position: fixed;
  left: 0;
  top: 15%;
  width: 100%;
  height: 100vh;
  background: #fffebf;
  z-index: 2;
  @media (prefers-reduced-motion) {
    display: none;
  }
`;

useReducedMotion Hook

Framer Motion has a reduced motion hook which can be used in conditions to determine what types of animations to use; for example, replacing transform animations with opacity animations.