接下来要来完成我们网站的导览部分了,这里阿森主要分为两个大项目,分别是Navbar和Sidebar。Navbar就是一般看网页时会浮在最上面的导览选单,而Sidebar则是使用手机或是小视窗打开时,会缩小成一个按钮,要打开才能做选择的导览选单。
今天会先讲Navbar的设计,那我们就开始吧!
有看前几篇的figma设计篇的话,应该都看过我设计的草稿了,这里我想做的是当访客点开网页时,出现的第一个画面是这个:
当他把滑鼠滚轮往下卷时,我的Navbar会从上面跑下来,同时底部也会有一个Slogan往上跑,变成这样:
Logo也会渐渐往左上角移动,同时缩小一点。
再来是如果访客是用手机或是小视窗打开时:
会让他自动缩小,至於点开Sidebar的部分就留到明天介绍。
这里阿森是用前面提到过的架构来建立我react的资料夹,所以一共有这些内容:
那我们最主要的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:
为了达成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:
这里我们设定MobileIcon在小於768px时才会显现,而这个Icon我们会从react-icon这个插件中使用FaBars来完成,也就是在index.js中import的那个。关於react插件安装的部分也可以看前面的react介绍篇哦!
所以在完成这些之後,最重要的就是把图片存到images这个资料夹中,像是这样:
最後阿森附上我的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"
]
}
}
就可以达成我们要的效果啦!
那Navbar的部分就先到这边,明天再来延伸Sidebar要怎麽和他结合在一起吧!
<<: Day19:今天来谈一下Microsoft Defender的身分识别
程序架构 Namespace (自订命名空间) 就是由自己写的程序库之名称,一个程序库只能有一个自订...
You Need the “Exams4Success” Pegasystems PEGAPCSA8...
聚簇索引 有两个特点 使用主键值大小进行纪录和页的排序 包含三个方面 页内的所有纪录(包含使用者纪录...
Scanner 常使用到的Methods 整数 nextInt() 2.小数 nextDouble(...
前言 今天就来点可以让大家在排版时能够更多样更方便的方式吧 display : flex 在写今天的...