├── src ├── assets │ └── logo.png ├── styles.css ├── index.js └── components │ ├── Header.js │ └── Header.css ├── README.md ├── package.json └── public └── index.html /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidalidev/react-responsive-animated-header/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Responsive Animated Header 2 | 3 | CodeSandBox: https://codesandbox.io/s/lr20y45o5m 4 | 5 | ```bash 6 | yarn # npm i 7 | yarn start # npm start 8 | ``` 9 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | .App { 8 | height: 100vh; 9 | width: 100vw; 10 | background-color: #fff; 11 | } 12 | 13 | .App .Content { 14 | padding-top: 100px; 15 | text-align: center; 16 | } 17 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './styles.css'; 4 | import Header from './components/Header'; 5 | 6 | function App() { 7 | return ( 8 |
9 |
10 |
11 |

42 is the answer to everything...

12 |
13 |
14 | ); 15 | } 16 | 17 | 18 | const rootElement = document.getElementById("root"); 19 | ReactDOM.render(, rootElement); 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "responsive-animated-top-navigation-bar-with-react", 3 | "version": "1.0.0", 4 | "description": "", 5 | "keywords": [], 6 | "main": "src/index.js", 7 | "dependencies": { 8 | "react": "16.8.6", 9 | "react-dom": "16.8.6", 10 | "react-scripts": "2.1.8", 11 | "react-transition-group": "4.0.0" 12 | }, 13 | "devDependencies": { 14 | "typescript": "3.3.3" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test --env=jsdom", 20 | "eject": "react-scripts eject" 21 | }, 22 | "browserslist": [ 23 | ">0.2%", 24 | "not dead", 25 | "not ie <= 11", 26 | "not op_mini all" 27 | ] 28 | } -------------------------------------------------------------------------------- /src/components/Header.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable jsx-a11y/accessible-emoji */ 2 | import React, { useState, useEffect } from "react"; 3 | import "./Header.css"; 4 | import { CSSTransition } from "react-transition-group"; 5 | 6 | export default function Header() { 7 | const [isNavVisible, setNavVisibility] = useState(false); 8 | const [isSmallScreen, setIsSmallScreen] = useState(false); 9 | 10 | useEffect(() => { 11 | const mediaQuery = window.matchMedia("(max-width: 700px)"); 12 | mediaQuery.addListener(handleMediaQueryChange); 13 | handleMediaQueryChange(mediaQuery); 14 | 15 | return () => { 16 | mediaQuery.removeListener(handleMediaQueryChange); 17 | }; 18 | }, []); 19 | 20 | const handleMediaQueryChange = mediaQuery => { 21 | if (mediaQuery.matches) { 22 | setIsSmallScreen(true); 23 | } else { 24 | setIsSmallScreen(false); 25 | } 26 | }; 27 | 28 | const toggleNav = () => { 29 | setNavVisibility(!isNavVisible); 30 | }; 31 | 32 | return ( 33 |
34 | logo 35 | 41 | 47 | 48 | 51 |
52 | ); 53 | } 54 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 23 | React App 24 | 25 | 26 | 27 | 30 |
31 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/components/Header.css: -------------------------------------------------------------------------------- 1 | .Header { 2 | position: fixed; 3 | top: 0; /* Stick it to the top */ 4 | max-height: 70px; 5 | width: 100vw; 6 | 7 | display: grid; 8 | grid-template-areas: "logo nav"; 9 | 10 | /* Cosmetics */ 11 | background-color: #282c34; 12 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); 13 | } 14 | 15 | .Logo { 16 | grid-area: logo; 17 | height: 70px; 18 | } 19 | 20 | .Nav { 21 | display: grid; 22 | grid-area: nav; 23 | grid-template-columns: repeat(4, auto); 24 | align-items: center; 25 | justify-items: center; 26 | } 27 | .Nav a { 28 | color: #fff; 29 | font-size: 20px; 30 | font-weight: 500; 31 | transition: 0.5s; 32 | text-decoration: none; 33 | } 34 | .Nav a:hover { 35 | transform: scale(1.1); 36 | } 37 | .Nav button { 38 | padding: 10px; 39 | outline: none; 40 | border: none; 41 | font-size: 20px; 42 | color: #fff; 43 | font-weight: 600; 44 | background-color: rgba(255, 0, 0, 0.5); 45 | box-shadow: 0px 5px 0px 0px rgba(255, 0, 0, 0.25); 46 | border-radius: 10px; 47 | cursor: pointer; 48 | transition: 70ms; 49 | } 50 | 51 | .Nav button:active { 52 | transform: translateY(3px); 53 | box-shadow: 0px 2px 0px 0px rgba(255, 0, 0, 0.25); 54 | } 55 | 56 | .Burger { 57 | display: none; 58 | grid-area: burger; 59 | margin: 0 20px 0 0; 60 | padding: 0; 61 | justify-self: end; 62 | font-size: 40px; 63 | border: none; 64 | background: none; 65 | outline: none; 66 | transition: 0.1s; 67 | } 68 | .Burger:active { 69 | transform: scale(1.2); 70 | } 71 | 72 | @media (max-width: 700px) { 73 | .Header { 74 | grid-template-areas: "logo burger" "nav nav"; 75 | } 76 | .Nav { 77 | grid-template-rows: repeat(4, auto); 78 | grid-template-columns: none; 79 | grid-row-gap: 20px; 80 | 81 | padding: 30px 0 30px; 82 | background: rgba(40, 44, 47, 0.95); 83 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); 84 | border-bottom-left-radius: 10px; 85 | border-bottom-right-radius: 10px; 86 | } 87 | .Burger { 88 | display: inline; 89 | } 90 | } 91 | 92 | .NavAnimation-enter { 93 | opacity: 0; 94 | transform: scale(0.5); 95 | } 96 | .NavAnimation-enter-active { 97 | opacity: 1; 98 | transform: translateX(0); 99 | transition: opacity 350ms, transform 350ms; 100 | } 101 | .NavAnimation-exit { 102 | opacity: 1; 103 | } 104 | .NavAnimation-exit-active { 105 | opacity: 0; 106 | transform: scale(0.5); 107 | transition: opacity 350ms, transform 350ms; 108 | } 109 | --------------------------------------------------------------------------------