본문 바로가기

블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기

[81일차 복습] css 반응형 햄버거 (삼선) 메뉴 만들기 / 리액트 라우터 react-router-dom

반응형

 

 

  반응형 main 햄버거 삼선 메뉴 만들기 + onClick   

 

 

 

 

 

1. 기존의 react-icon 에서 가져온 Fabars삭제 -> label 사용해서 직접 삼선 그릴 예정 / 코드가 길어질 것 같아서 Component ("NavToggle") 사용! 

                    {/* logo */}
                    <div className="nav-header">
                        <h1 className="logo">LOGO</h1>
                        <NavToggle />
                    </div>

2. NavToggle component > NavToggle.jsx 생성 / 코드 작성

import React, {Component} from 'react'

class NavToggle extends Component{
    render(){
        return(
            <>
                <input type="checkbox" id="nav-toggle" className="nav-toggle"/>
                <label htmlFor="nav-toggle">
                    <span></span>
                    <span></span>
                    <span></span>
                </label>
            </>
        )
    }
}

export default NavToggle

checkbox를 클릭하게되면 nav-toggle id를 가진 아이를 향하게 된다. label 과 for 가 세트인데 jsx 에서는 for를 htmlFor 라고 써야한다 !! 

 

서버 실행시켜서 잘되는지 중간중간 체크하기 ! 

 

 

3. cs  >  NavToggle.CSS 파일 생성 / NavToggle.jsx에 css 파일 끌어오기

NavToggle.jsx

import React, {Component} from 'react'
import '../css/NavToggle.css'

NavToggle.css

/* checkbos 가리기 */

.nav-toggle{
    display: none;
}

/* 햄버거 들어갈 공간 label 설정 
    relative  줌 
*/
.nav-toggle + label{
    display: block;
    width:2.5rem;
    height:2rem;
    position:relative;
    cursor:pointer;
}

/* span 으로 햄버거 만들기  
    absolute 주고 아래에 한 줄씩 위치 처리
*/
.nav-toggle+label>span{
    display:block;
    width:100%;
    height:5px;
    border-radius: 30px;
    background-color: black;
    transition:all .35s;
    position:absolute;
}


/* span 햄버거 한 줄 한 줄 처리 */

.nav-toggle + label>span:nth-child(1){
    top:0;
}
.nav-toggle + label>span:nth-child(2){
    top:50%;
    transform:translateY(-50%)
}
.nav-toggle + label>span:nth-child(3){
    bottom:0;
}



/* input box checked 쳌박스 눌리면 모션 주기 */


.nav-toggle:checked + label>span:nth-child(1){
    top:50%;
    transform:translateY(-50%) rotate(45deg);
}
.nav-toggle:checked + label>span:nth-child(2){
    opacity:0;
}
.nav-toggle:checked + label>span:nth-child(3){
    bottom:50%;
    transform:translateY(50%) rotate(-45deg);
}



/* PC 버전  */


/* pc에서는 햄버거가 안보이게 만들기 */

@media screen and (min-width:800px){
    .nav-toggle + label{
        display:none;
    }
}

 

* 인접 접근자 

처음 선택한 바로 아래의 동등한 element 선택할 때  '  +  ' 기호를 사용

선택한 요소의 안에 들어간 요소를 선택하는 건 ' > '요 기호 !! 

* label : inline 이라 어차피 넓이 조절이 안되어서 block 처리, relative 주기 

 

 

 


 

  반응형 시 header 메뉴들이 보이도록 만들기   

 

 

1. Navbar.jsx 에 state boolean 추가 

            }
        ],
        showLinks:false,
    }

false : 메뉴가 안보이게 - links-container 

true : 메뉴가 보이게 - links-container on (on add) 

 

2. Navbar.css 

/* 반응형 웹 header 메뉴 
현재 pc만 되어 있어서 반응형 css 하기
아래 height:0 -> 반응형에 아직 안보이게
on class 붙으면 height:100%해서  보이게 만들기 
*/


.links-container{
    height:0;
    overflow:hidden;
}


/* 반응형일 때 메뉴 */ 
.links-container.on{
    height:100%;
}

height: 0 ---반응형일 때 (on이 붙으면 ) ----> hegith:100% 으로 메뉴 보이도록 만들기 

 

 

 

3. showContainer 라는 함수로 class 명 정해서 return -> 요 함수를 className에 옮기기

    showContainer =()=>{
        let className= this.state.showLinks ? 'links-container on':'links-container';
        return className
    }

    render() {
        return (
            <nav>
                <div className="nav-center">

                    {/* logo */}
                    <div className="nav-header">
                        <h1 className="logo">LOGO</h1>
                        <NavToggle />
                    </div>

                    {/* navigation */}
                    <div className={this.showContainer()}>
                        <ul className="links">
                            {

 

 

4. 클릭하면 showLinks 값을 반대로 만드는 함수 생성 + NavToggle로 보내기!

    handleToggle=()=>{
        this.setState({showLinks:!this.state.showLinks})
    }

    render() {
        return (
            <nav>
                <div className="nav-center">

                    {/* logo */}
                    <div className="nav-header">
                        <h1 className="logo">LOGO</h1>
                        <NavToggle 
                            toggle = {this.handleToggle}
                        />
                    </div>

 

 

5. onClick 함수를 toggle이라는 이름으로 받은 NavToggle이 사용하기

class NavToggle extends Component{
    render(){
        return(
            <>
                <input 
                    type="checkbox" 
                    id="nav-toggle" 
                    className="nav-toggle"
                    onClick={()=>this.props.toggle()}    
                />

헷갈리는 부분 : 

onClick={this.props.toggle}    O 

onClick={()=>this.props.toggle()}   O

onClick={this.props.toggle()}   X    -> 오류가 남 

onClick={()=>this.props.toggle}   X  - 오류는 안나지만 실행이 안됨

 

 

햄버거를 클릭하면 메뉴들이 나온다 

 

 

6. 메뉴들 CSS  - Navbar.css

/* mobile */

.nav-header{
    display:flex;
    align-items: center;
    justify-content: space-between; /* 양쪽 끝 */
    padding:1rem;
}


.logo{
    font-size: 3rem;
}

/* rem 확대 축소 비율로 늘어남 */ 

/* 반응형 웹 header 메뉴 
현재 pc만 되어 있어서 반응형 css 하기
아래 height:0 -> 반응형에 아직 안보이게
on class 붙으면 height:100%해서  보이게 만들기 
*/
.links-container{
    height:0;
    overflow:hidden;
}

.links-container.on{
    height:100%;
}

/* overflow hidden 을 안주면 icons 들이 새어나옴 */ 
.social-icons{
    height:0;
    overflow:hidden;
}

.nav-toggle{
    font-size:3rem;
    /*투명하게 만들기 */
    background:transparent;
    border-color:transparent;
    color:blue;
}

/*************** 웹 반응형 menu 지금 추가하는 부분 ***************/

.links>li{
    width:100%;
    text-align: center;
    border-bottom:1px solid #eee;
}
.links>li>a{
    display: inline-block;
    color: black;
    font-size: 1.25rem;
    padding:0.75rem;
}




/* PC css style */
@media screen and (min-width:800px){


    .logo{
        font-size: 4rem;
    }

    .nav-toggle{
        /*pc 경우에 토글 안보이게*/ 
        font-size: 0px;
        color:blue;
    }

    .nav-center{
        max-width:1170px;
        margin:0 auto;
        display: flex;
        align-items:center;
        justify-content: space-between;
        padding:1rem;
    }

    .links-container{
        height:auto;

    }

    /*********** 지금 추가하는 css 2 *************/ 
    /* PC */

    .links{
        display: flex;
        flex-direction: row;
    }

    .links>li{
        width:100%;
        text-align: center;
        border-bottom: none;
    }
    .links>li>a{
        margin:0 0.5rem;
        color:black;
        font-size: 2rem;
    }

    .social-icons{
        display:flex;
        height:auto;
        
    }

    .social-icons>li>a{
        margin: 0 .5rem;
        color: darkcyan;
        font-size: 3rem;
    }

}

 

 

PC

 

 

MOBILE 

 

 


 

 

 

   REACT ROUTER   

 

 

1. npm react router 패키지 설치

$npm i react-router-dom

 

2. 최상위 Component 인 App.jsx에 라우터 가져오기 & 코드 작성

import React, { Component } from 'react';
import Navbar from './component/Navbar'
import {BrowserRouter,Route,Switch} from 'react-router-dom'

class App extends Component {
    render() {
        return (
            <>
                <BrowserRouter>
                    <Navbar/>
                    {/* switch 안 내용 보이는 영역 = 가변적 (header아래 부분!) */}
                    <Switch>
                        <Route exact path="/" component={Coconut}/>
                        <Route exact path="/is" component={Is}/>
                        <Route exact path="/great" component={Great}/>
                    </Switch>
                </BrowserRouter>
                
            </>
        )
    }
}

export default App

 

BrowserRouter - 라우터 쓰겠다. 

Switch - 해당 영역 안에서 ~ url 받으면 ~component 로 바꾸줄게 

Route - router 쓰는 곳 

 

 

3. pages 폴더 생성 > 위에서 작성한 Coconut, Is, Great Component 생성 및 작성

import React,{Component} from 'react'

class Coconut extends Component{
    render(){
        return(
            <>
                코코넛
            </>
        )
    }
}

export default Coconut

X 3  만들기 

 

 

 

4. App.jsx에 위의 3개 components 가져오기  & 사용하기

class App extends Component {
    render() {
        return (
            <>
                <BrowserRouter>
                    <Navbar/>
                    {/* switch 안 내용 보이는 영역 = 가변적 (header아래 부분!) */}
                    <Switch>
                        <Route exact path="/" component={Coconut}/>
                        <Route exact path="/is" component={Is}/>
                        <Route exact path="/great" component={Great}/>
                    </Switch>
                </BrowserRouter>

 

 

 

5. Navbar.jsx url 수정

            },
        ],
        menu:[
            {
                id:1,
                url:'/',
                text:'coconut'
            },
            {
                id:2,
                url:'/is',
                text:'always'
            },
            {
                id:3,
                url:'/great',
                text:'great'
            }
        ],
        showLinks:false,

 

이제 해당 menu 클릭할 때마다 해당 component의 return text가 뜬다 ! 

 

 

 

 

 

 

   ***  url 변경에 따른 link 이동하지 않도록 만들기   ***   

 

 

6. navbar.jsx 

import React, { Component } from 'react'
import '../css/navbar.css'
import { FaFacebook, FaInstagram, FaTwitter, FaBars } from 'react-icons/fa'
import NavToggle from './NavToggle'
import {Link} from 'react-router-dom'

아까 받은 react-router-dom 에 있는 속성 Link 가져와서 

a ==> Link

hreft ==> to 로 변경하면 이제 reload가 되지 않는다 . 

                    {/* navigation */}
                    <div className={this.showContainer()}>
                        <ul className="links">
                            {
                                this.state.menu.map(v=>{
                                    let {id, url, text} = v;
                                    return(
                                        <li key={id}>
                                            <Link to={url}>{text}</Link>
                                        </li>
                                    )
                                })
                            }
                        </ul>

 

 

 

 

과제를 하다가 url 이 home이 아닌 이상 계속 오류가 나서 다시 url 을 적어야하는 불편함이 있었다. 요거는 webpack.config.js 에서 아래 코드를 입력해주면 방지할 수 있다. 

    // 실행할 때 
    devServer:{
        publicPath:'/dist',
        hot:true, 
        historyApiFallback:true,
    }
}

바로바로css  변화를 보면서 만드니깐 속이 쉬원함,,

 

 

 

 

반응형