본문 바로가기
Tutorial/youtube

07. 나만의 유튜브 사이트 만들기 : 헤더 영역 완성하기

by @webstoryboy 2023. 9. 4.
Tutorial/Portfolio

나만의 유튜브 사이트 만들기

by @webs 2023. 09. 01.
07
나만의 유튜브 사이트 만들기 : 헤더 영역 완성하기
난이도 중간

소개

안녕하세요! 웹스토리보이입니다. 이 강의는 React 프레임워크와 YouTube API를 이용하여 자신만의 간단한 영상 사이트를 만들어보겠습니다. React의 기본 개념을 이해하고, 컴포넌트를 구조화하고 상태를 관리하는 방법을 학습하게 될 것입니다. 또한 YouTube Data API를 활용하여 외부 데이터를 가져오는 방법을 익히고, API 응답을 처리하여 사용자에게 의미 있는 정보를 제공하는 방법을 이해하게 됩니다. 이로써 자신만의 유튜브 사이트를 만들고, 활용해보는 것을 목표로 합니다. 그럼 한번 시작해볼까요? 🥳

인덱스

  • 1. 셋팅하기
    • 1_1. Node.js 설치
    • 1_2. Vscode 설치
    • 1_3. React.js 설치
  • 2. 라이브러리 설치하기
    • 2_1. 폴더 정리하기
    • 2_2. 라이브러리 설치하기
  • 3. Git 연동하기
    • 3_1. 저장소 만들기
    • 3_2. 모든 파일 올리기
    • 3_3. 깃 상태 확인하기
  • 4. SCSS 셋팅하기
    • 4_1. SCSS 설정하기
    • 4_2. style.scss 설정하기
    • 4_3. fonts.scss 설정하기
    • 4_4. vars.scss 설정하기
    • 4_5. reset.scss 설정하기
    • 4_6. mixin.scss 설정하기
    • 4_7. common.scss 설정하기
  • 5. 페이지 만들기
    • 5_1. 페이지 만들기
    • 5_2. 페이지 컴퍼넌트 만들기
  • 6. 섹션 컴퍼넌트 구조화하기
    • 6_1. 전체 레이아웃 만들기
    • 6_2. 섹션 컴퍼넌트 만들기
  • 7. 헤더 영역 완성하기
    • 7_1. 헤더 영역 구조 잡기
    • 7_2. 헤더 영역 디자인 작업

7. 헤더 영역 완성하기

7_1. 헤더 영역 구조 잡기

header 영역은 로고, 메뉴, SNS로 구성되어 있습니다. 리액트에서는 class 대신에 className을 사용합니다.

https://react-icons.github.io/react-icons 사이트에 아이콘을 이용하여 설정하였습니다. 사용할 아이콘의 이름을 import 하고 해당 영역에 이름을 써주면 됩니다.

import React from 'react'

import { CiBaseball } from "react-icons/ci";
import { CiCoins1 } from "react-icons/ci";
import { CiBoxes } from "react-icons/ci";
import { CiBullhorn } from "react-icons/ci";
import { CiCoffeeCup } from "react-icons/ci";
import { CiDumbbell } from "react-icons/ci";
import { CiFries } from "react-icons/ci";
import { CiMoneyBill } from "react-icons/ci";

import { AiFillGithub } from "react-icons/ai";
import { AiOutlineCodepen } from "react-icons/ai";
import { AiFillYoutube } from "react-icons/ai";
import { AiOutlineInstagram } from "react-icons/ai";

const Header = () => {
    return (
        <header id='header' role='banner'>
            <h1 className='header__logo'>
                <a href='/'>
                    <em aria-hidden='true'></em>
                    <span>webs<br />youtube</span>
                </a>
            </h1>

            <nav className='header__menu'>
                <ul className='menu'>
                    <li className='active'>
                        <a href='/'>
                            <CiBaseball /> 웹스토리보이
                        </a>
                    </li>
                    <li>
                        <a href='/today'>
                            <CiMoneyBill /> 추천 영상
                        </a>
                    </li>
                    <li>
                        <a href='/developer'>
                            <CiCoins1 /> 추천 개발자
                        </a>
                    </li>
                    <li>
                        <a href='/webd'>
                            <CiBoxes /> 웹디자인기능사
                        </a>
                    </li>
                    <li>
                        <a href='/website'>
                            <CiBullhorn /> 웹표준 사이트
                        </a>
                    </li>
                    <li>
                        <a href='/gsap'>
                            <CiCoffeeCup /> GSAP Parallax
                        </a>
                    </li>
                    <li>
                        <a href='/port'>
                            <CiDumbbell /> 포트폴리오 사이트
                        </a>
                    </li>
                    <li>
                        <a href='/youtube'>
                            <CiFries /> 유튜브 클론 사이트
                        </a>
                    </li>
                </ul>
                <ul className='keyword'>
                    <li>
                        <a href='/search/webstoryboy'>webstoryboy</a>
                    </li>
                    <li>
                        <a href='/search/html'>HTML</a>
                    </li>
                    <li>
                        <a href='/search/css'>CSS</a>
                    </li>
                    <li>
                        <a href='/search/javascript'>JavaScript</a>
                    </li>
                    <li>
                        <a href='/search/react.js'>React.js</a>
                    </li>
                    <li>
                        <a href='/search/vue.js'>Vue.js</a>
                    </li>
                    <li>
                        <a href='/search/next.js'>Next.js</a>
                    </li>
                    <li>
                        <a href='/search/node.js'>Node.js</a>
                    </li>
                    <li>
                        <a href='/search/sql'>SQL</a>
                    </li>
                    <li>
                        <a href='/search/React Portfolio'>portfolio</a>
                    </li>
                    <li>
                        <a href='/search/NewJeans'>music</a>
                    </li>
                </ul>
            </nav>
            
            <div className='header__sns'>
                <ul>
                    <li>
                        <a href='https://github.com/webstoryboy' rel='noopener noreferrer'>
                            <AiFillGithub />
                        </a>
                    </li>
                    <li>
                        <a href='https://www.youtube.com/webstoryboy' rel='noopener noreferrer'>
                            <AiFillYoutube />
                        </a>
                    </li>
                    <li>
                        <a href='https://codepen.io/webstoryboy' rel='noopener noreferrer'>
                            <AiOutlineCodepen />
                        </a>
                    </li>
                    <li>
                        <a href='https://www.instagram.com/webstoryboy' rel='noopener noreferrer'>
                            <AiOutlineInstagram />
                        </a>
                    </li>
                </ul>
            </div>
        </header>
    )
}

export default Header

rel="noopener noreferrer"는 <a> 태그의 rel 속성에 사용되는 값들로, 웹 페이지의 보안 및 사용성을 향상시키기 위해 사용됩니다. rel="noopener noreferrer"를 사용하면 새 탭/윈도우에서 링크를 열 때 보안 및 개인 정보 보호 측면에서 안전한 방식으로 열리게 됩니다.

  • noopener: 이 값을 사용하면 링크를 새 탭/윈도우에서 열 때, 새로 열리는 페이지가 부모 페이지의 window.opener 속성을 통해 부모 페이지를 제어하는 것을 방지합니다. 이렇게 함으로써 다른 사이트에서 자신의 페이지를 조작하는 보안 취약점을 방지할 수 있습니다.
  • noreferrer: 이 값을 사용하면 링크를 클릭할 때 HTTP 리퍼러(Referer) 헤더가 전송되지 않습니다. 이는 사용자의 개인 정보를 보호하고 어떤 사이트로부터 연결되었는지 등을 감추는 데 도움이 됩니다.

7_2. 헤더 영역 디자인 작업

scss > section > _header.scss를 만들고 다음과 같이 작업합니다. 추가된 scss는 style.scss에 추가해야 합니다.

@charset "UTF-8";

// setting
@import "setting/fonts";
@import "setting/vars";
@import "setting/reset";
@import "setting/mixin";
@import "setting/common";

// section
@import "section/layout";
@import "section/header"; // 추가

_header.scss도 추가합니다.

  • assets
    • fonts
    • img
    • scss
      • section
        • _layout.scss
        • _header.scss
      • setting
        • _common.scss
        • _fonts.scss
        • _mixin.scss
        • _reset.scss
        • _vars.scss
      • style.scss

_header.scss도 다음과 같이 작업합니다.

.header__logo {
    border-bottom: 1px solid var(--black100);

    a {
        display: flex;
        padding: 10px;
        margin: 10px;

        em {
            width: 40px;
            height: 40px;
            display: block;
            background-color: var(--red);
            margin-right: 10px;
            animation: ani 20s 20s ease-in-out infinite;
        }

        span {
            font-size: 20px;
            line-height: 1;
            font-weight: 900;
            text-transform: uppercase;
        }
    }
}

.header__menu {
    padding: 10px 0;

    .menu {
        border-bottom: 1px solid var(--black100);

        li {
            margin-bottom: 5px;

            a {
                font-size: 1rem;
                display: block;
                padding: 0.9rem 2rem 0.9rem 3.125rem;
                margin: 0 0.625rem;
                border-radius: 40px;
                position: relative;
                line-height: 1;
                color: var(--white200);
                transition: all 0.3s;

                svg {
                    width: 1.25rem;
                    height: 1.25rem;
                    position: absolute;
                    left: 1.25rem;
                    top: 0.75rem;
                }

                &:hover {
                    background-color: var(--black100);
                    color: var(--white);
                }
            }

            &.active a {
                background-color: var(--black100);
                color: var(--white);
            }
        }
    }

    .keyword {
        padding: 1.25rem;

        li {
            display: inline-block;

            a {
                display: inline-block;
                padding: 5px 15px;
                border: 1px solid var(--black200);
                font-size: 0.8rem;
                border-radius: 40px;
                margin: 3px 1px;
                transition: all 0.3s;

                &:hover {
                    background-color: var(--black100);
                    color: var(--white);
                }
            }

            &.active a {
                background-color: var(--black100);
                color: var(--white);
            }
        }
    }
}

.header__sns {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 260px;
    text-align: center;
    padding: 15px 0 10px;
    background-color: var(--blackAlpha100);
    backdrop-filter: blur(10px);

    li {
        display: inline-block;

        a {
            padding: 5px 7px;
            display: inline-block;
        }
    }
}

@keyframes ani {
    0% {
        transform: rotate(0) scale(1);
        border-radius: 0;
    }
    50% {
        transform: rotate(720deg) scale(0.5);
        border-radius: 20px;
    }
    100% {
        transform: rotate(0) scale(1);
        border-radius: 0;
    }
}

_layout.scss도 다음과 같이 수정합니다.

#header {
    position: fixed;
    left: 0;
    top: 0;
    width: 260px;
    height: 100%;
    overflow-y: auto;
    z-index: 10000;
    background-color: #000;
}
#main {
    max-width: 2000px;
    min-height: 100vh;
    margin: 0 auto;
    padding-left: 260px;
    background-color: #111;
}
#footer {
    text-align: center;
    background-color: #333;
    padding: 20px 20px 20px 260px;
}

디자인을 확인해 보면 다음과 같이 나옵니다.

youtube2023

마무리

git 올리기

터미널에서 다음과 같이 작성하겠습니다. 새로운 페이지가 올라오는 것을 확인 할 수 있습니다.

webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git add .
webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
    (use "git restore --staged ..." to unstage)
        new file:   src/assets/scss/section/_header.scss
        modified:   src/assets/scss/setting/_vars.scss
        modified:   src/assets/scss/style.scss
        modified:   src/components/section/Header.jsx
        new file:   src/data/header.js

webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git commit -m "헤더 영역 완성하기"
[main 436eb77] 헤더 영역 완성하기
    5 files changed, 293 insertions(+), 5 deletions(-)
    create mode 100644 src/assets/scss/section/_header.scss
    create mode 100644 src/data/header.js
webstoryboyhwang@Webstoryboyui-MacBookPro webs-youtube % git push -u origin main
Enumerating objects: 26, done.
Counting objects: 100% (26/26), done.
Delta compression using up to 10 threads
Compressing objects: 100% (13/13), done.
Writing objects: 100% (15/15), 3.05 KiB | 3.05 MiB/s, done.
Total 15 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (4/4), completed with 4 local objects.
To https://github.com/webstoryboy/webs-youtube.git
    6734289..436eb77  main -> main
branch 'main' set up to track 'origin/main'.

헤더 영역을 완성하였습니다. 메뉴를 데이터화여 불러오고 화면에 출력하는 부분은 앞으로도 자주 사용하게 될 것입니다. 아직은 어려울 수 있지만 익숙해지면 쉬업집니다. 익숙해지려면 반복적으로 작업하면 됩니다. 그럼 다음 시간에도 또 반복적으로 작업해볼까요? 수고하셨습니다 🤩


예제 목록

댓글