DAY21-导览设计之Navbar

codememe.jpeg

前言:

接下来要来完成我们网站的导览部分了,这里阿森主要分为两个大项目,分别是Navbar和Sidebar。Navbar就是一般看网页时会浮在最上面的导览选单,而Sidebar则是使用手机或是小视窗打开时,会缩小成一个按钮,要打开才能做选择的导览选单。

今天会先讲Navbar的设计,那我们就开始吧!

目标:

有看前几篇的figma设计篇的话,应该都看过我设计的草稿了,这里我想做的是当访客点开网页时,出现的第一个画面是这个:

截图 2021-09-04 下午3.14.45.png

当他把滑鼠滚轮往下卷时,我的Navbar会从上面跑下来,同时底部也会有一个Slogan往上跑,变成这样:

截图 2021-09-04 下午3.15.54.png

Logo也会渐渐往左上角移动,同时缩小一点。

再来是如果访客是用手机或是小视窗打开时:

截图 2021-09-04 下午3.22.17.png

会让他自动缩小,至於点开Sidebar的部分就留到明天介绍。

无情开写:

这里阿森是用前面提到过的架构来建立我react的资料夹,所以一共有这些内容:

截图 2021-09-04 下午3.24.41.png

那我们最主要的Home也是放在pages这个资料夹中的index.js里,先把我们的HeroSection加上来:

index.js in pages:

import React from 'react'
import HeroSection from '../components/HeroSection'
import { useState } from 'react'

const Home = () => {
		const [isOpen, setIsOpen] = useState(false)
const toggle = () => {
		setIsOpen(!isOpen)
}

    return (
        <>

        <HeroSection toggle = { toggle }/>
				//传入一个toggle让HeroSection里面的MobileIcon可以侦测之後Sidebar的开关。

        </>
    )
}

export default Home

接着我们在components里面新增一个HeroSection资料夹,里面有一个index.js、style.css还有一个HeroElements.js,因为这里我们会用到前面提到的style component:

截图 2021-09-04 下午3.36.42.png

为了达成scroll的效果,我们要用到css和javascript的搭配,所以index.js和style.css都完成後会长这样:

index.js

import { MobileIcon, Logo} from './HeroElements'
import logo from '../../images/logo.png'
import back from '../../images/back.jpg'
import name from '../../images/name.png'
import './style.css'
import {FaBars} from 'react-icons/fa'

const HeroSection = ({toggle}) => {
    window.addEventListener("scroll", ()=>{
        const header = document.querySelector('header');
        header.classList.toggle('sticky', window.scrollY > 0);
    });
    
    return (
        <>
        <img className="logo" src = {logo} />
        <header id="header">
        <img src= {back} style={{opacity: 1}} alt="background" className = "banner"/>
    
        <Logo className="name" src = {name}/>
        
        <nav>
            <ul>
                <li><img className="navLogo" src={logo}></img></li>
                <li><a href ="/" style={{background:"gray", borderRadius:"10px"}}>News</a></li>
                <li><a href ="/">Intro</a></li>
                <li><a href ="/">Roadmap</a></li>
                <li><a href ="/">Buy</a></li>
                <li><a href ="/">FAQs</a></li>
                <li><a href ="/">Team</a></li>
                
                
                <MobileIcon onClick = {toggle} >
                 <FaBars />
                </MobileIcon>
            </ul>
        </nav>
        <div className="bottom"><p>What if their legends never end.</p></div>
        </header>
        </>
    )
}

export default HeroSection

style.css

body{
    min-height: 1000px;
    background: black;
}

header {
    position: relative;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background-origin: #000;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    transition: 1s;
}

header .banner{
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    object-fit: cover;
    transition: 1s;
    
}

header.sticky nav{
    flex: none;
    background: black;
    width: 100%;
    transition: 1s;
    top: 0;
}

header nav {
    flex: none;
    transition: 1s;
    width: 100%;
    top: -80px;
}

header .name{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    
    height: 200px;
    width: auto;
    z-index: 10;
    transition: 1s;
}

header.sticky .name{
    position: absolute;
    font-size: 2em;
    left: 50px;
    top: 30%;
    transform: translate(0, -50%);
    width: auto;
    height: 150px;
    transition: 1s;
}

@media screen and (max-width: 768px){
    header.sticky .name{
        position: absolute;
        
        transform: translate(0, -50%);
        height: 75px;
        width: auto;
        transition: 1s;
    }

    header .name{
        height: 75px;
        width: auto;
        
    }

    header .banner{
        max-width: auto;
        height: 100vh;
    }

    .bottom{
        width: fit-content;
    }

    nav ul li a{
        color: #fff;
        display: none !important;
    }

    .navLogo{
        margin-left: -70px;
    }
    .bottom p{
        margin-left: 50%;
        font-size: 0.5em;
    }

    header.sticky .navLogo{
        margin-left: -200%;
    }
}

nav {
    position: fixed;
    display: flex;
    z-index: 10;
    padding-right: 5%;
    top: 0;
}

nav ul{
    position: relative;
    display: flex;
    flex: none;
    flex-direction: row;
    transition: 0.25s;
    opacity: 0;
    justify-content: space-evenly;
    width: 100%;
}

header.sticky nav ul{
    opacity: 1;
    transition-delay: 0.75s;
    align-items: center;
}

nav ul li{
    list-style: none;
    
}

nav ul li a{
    color: #000;
    display: flex;
    padding: 10px 10px;
    font-size: 1.3em;
    text-decoration: none;
    color: white;
    top: 0;
    font-weight: 700;
    
}

nav ul li a:hover{
    color: #c64c4c;
}
nav ul li img{
    transition: 0.5s;
}
nav ul li img:hover{
    transform: scale(1.5);
    transition: 0.5s;
    cursor: pointer;
}

.navLogo{
    height: 35px;
    width: auto;
    
}

.bottom{
    width: 100%;
    height: 60px;
    position: absolute;
    display: flex;
    bottom: -60px;
    z-index: 5;
    background: #000;
    color: #fff;
    font-size: 1.8em;
    font-weight: 600;
    justify-content: center;
    align-items: center;
    transition: 1s ;
}

.bottom p{
    margin-left: 50%;
    transition: 1s;
    transition-delay: 0.75s ;
}

header.sticky .bottom{
    display: flex;
    bottom: 0;
    transition: 1s ;
}

.logo{
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    height: 200px;
    z-index: 1;
    opacity: 0.7;
}

header.sticky.logo{
    position: fixed;
    opacity: 1;
}

主要是设定header在侦测到scroll这个动作後,会触发.sticky这个class,所以在css档案中,可以用header.sticky这个选择器来选择卷动後的各个tag,之後再加上transition: 1s; 这项指令就可以达到缓缓移动的效果了。

那这里要注意@media,他可以控制在手机萤幕还有网页宽度小於768px时内容的表现方法,而为了达到我们的目的,这里要把Nav ul li a的display设成none才行,然後我们来完成HeroElements.js:

截图 2021-09-04 下午3.55.09.png

这里我们设定MobileIcon在小於768px时才会显现,而这个Icon我们会从react-icon这个插件中使用FaBars来完成,也就是在index.js中import的那个。关於react插件安装的部分也可以看前面的react介绍篇哦!

所以在完成这些之後,最重要的就是把图片存到images这个资料夹中,像是这样:

截图 2021-09-04 下午4.00.45.png

最後阿森附上我的package给大家参考:

{
  "name": "dino",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "gsap": "^3.7.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-gsap": "^3.2.1",
    "react-icons": "^4.2.0",
    "react-router-dom": "^5.2.1",
    "react-scripts": "4.0.3",
    "react-scroll": "^1.8.4",
    "react-scrollmagic": "^2.3.0",
    "styled-components": "^5.3.1",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

就可以达成我们要的效果啦!

demo2.gif

小结:

那Navbar的部分就先到这边,明天再来延伸Sidebar要怎麽和他结合在一起吧!


<<:  Day19:今天来谈一下Microsoft Defender的身分识别

>>:  [day 18] 自动布局

C# 入门笔记01

程序架构 Namespace (自订命名空间) 就是由自己写的程序库之名称,一个程序库只能有一个自订...

快速查询的秘密武器B+树索引-Part2(聚簇索引、二级索引、联合索引及相关注意事项)

聚簇索引 有两个特点 使用主键值大小进行纪录和页的排序 包含三个方面 页内的所有纪录(包含使用者纪录...

Day10 Scanner(Ⅱ)

Scanner 常使用到的Methods 整数 nextInt() 2.小数 nextDouble(...

铁人赛 Day6 -- 一定要知道的 CSS (三) - Flex 属性的应用

前言 今天就来点可以让大家在排版时能够更多样更方便的方式吧 display : flex 在写今天的...