Animated Responsive Navigation Bar

Written by Igor Dumencic•Published on August 14, 2019•Filed under ReactJS
Navigation bar icon

Hi! This is an example how I made a navigation bar with React and Styled Components that has a nice animation and is completely responsive.

End code can be found here. ( codesandbox )

Basic setup:

  1. Use create-react-app starter
  2. Add styled-components library

Project Code

I will just post the entire code here and you can of course modify it so that it will suit your needs.

1. Change styles.css File

You can use createGlobalStyle API from Styled Components but in this case I just quickly made two changes inside the .css file.

// styles.css

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

.App {
  font-family: sans-serif;
}

2. Header.js Component

I used flexbox to correctly position the elements inside the navigation bar and used media queries to show the correct menu when on mobile.

By using hooks and passing props to Styled Components allows us to toggle the mobile navigation without much effort.

// Header.js

import React, { useState } from "react";
import styled from "styled-components";

const Nav = styled.nav`
  padding: 0 20px;
  min-height: 9vh;
  background: #1c2022;
  display: flex;
  justify-content: space-between;
  align-items: center;
`;

const Logo = styled.h1`
  font-size: 25px;
  color: white;
`;

const Menu = styled.ul`
  list-style: none;
  display: flex;

  li:nth-child(2) {
    margin: 0px 20px;
  }

  @media (max-width: 768px) {
    display: none;
  }
`;

const Item = styled.li``;

const Link = styled.a`
  color: white;
  text-decoration: none;

  :hover {
    text-decoration: underline;
  }
`;

const NavIcon = styled.button`
  background: none;
  cursor: pointer;
  border: none;
  outline: none;

  @media (min-width: 769px) {
    display: none;
  }
`;

const Line = styled.span`
  display: block;
  border-radius: 50px;
  width: 25px;
  height: 3px;
  margin: 5px;
  background-color: #fff;
  transition: width 0.4s ease-in-out;

  :nth-child(2) {
    width: ${props => (props.open ? "40%" : "70%")};
  }
`;

const Overlay = styled.div`
  position: absolute;
  height: ${props => (props.open ? "91vh" : 0)};
  width: 100vw;
  background: #1c2022;
  transition: height 0.4s ease-in-out;

  @media (min-width: 769px) {
    display: none;
  }
`;

const OverlayMenu = styled.ul`
  list-style: none;
  position: absolute;
  left: 50%;
  top: 45%;
  transform: translate(-50%, -50%);

  li {
    opacity: ${props => (props.open ? 1 : 0)};
    font-size: 25px;
    margin: 50px 0px;
    transition: opacity 0.4s ease-in-out;
  }

  li:nth-child(2) {
    margin: 50px 0px;
  }
`;

const Header = () => {
  const [toggle, toggleNav] = useState(false);
  return (
    <>
      <Nav>
        <Logo>CSS Tricks</Logo>
        <Menu>
          <Item>
            <Link target="#" href="https://www.instagram.com/igor_dumencic/">
              Instagram
            </Link>
          </Item>
          <Item>
            <Link target="#" href="https://www.behance.net/igordumencic">
              Behance
            </Link>
          </Item>
          <Item>
            <Link target="#" href="https://github.com/Igor178">
              Github
            </Link>
          </Item>
        </Menu>
        <NavIcon onClick={() => toggleNav(!toggle)}>
          <Line open={toggle} />
          <Line open={toggle} />
          <Line open={toggle} />
        </NavIcon>
      </Nav>
      <Overlay open={toggle}>
        <OverlayMenu open={toggle}>
          <Item>
            <Link target="#" href="https://www.instagram.com/igor_dumencic/">
              Instagram
            </Link>
          </Item>
          <Item>
            <Link target="#" href="https://www.behance.net/igordumencic">
              Behance
            </Link>
          </Item>
          <Item>
            <Link target="#" href="https://github.com/Igor178">
              Github
            </Link>
          </Item>
        </OverlayMenu>
      </Overlay>
    </>
  );
};

export default Header;

3. Final Changes To index.js File

The last thing to do is to import the newly created Header component inside the index.js file and render it on the screen.

// index.js

import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";

import Header from "./Header";
import "./styles.css";

const Title = styled.h1`
  font-size: 25px;
  text-align: center;
  margin-top: 50px;
`;

function App() {
  return (
    <div className="App">
      <Header />
      <Title>Example of a Responsive Animated Navigation bar</Title>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Wrapping Up

You can see how easily you can make a nice animated navigation bar that is responsive and highly customizable. 🎉

Thank you for making it this far and I’ll see you next Wednesday! 😀

TAGS:

CSSHTMLReactJSResponsive DesignStyled Components

Join the Newsletter

Subscribe to get my latest content
by email.



I won't send you spam, unsubscribe at any time.