NEXT.js로 포트폴리오 제작-2
Header-Menu
Navbar.jsx


특정 화면 크기 이하의 경우(모바일)

메뉴 위치 및 변경
-right-64 -> -right-0으로 변경 시 확인 가능
OpenMenu / CloseMenu 생성


'use client'
import { assets } from '@/assets/assets'
import React, {useRef} from 'react'
import Image from 'next/image'
const Navbar = () => {
const sideMenuRef = useRef(); ### useRef
const openMenu = () => {
sideMenuRef.current.style.transform = 'translateX(0)' //// 처음부터 열려있음 (-16rem)이면 닫힘
};
const closeMenu = () => {
sideMenuRef.current.style.transform = 'translateX(16rem)'
};
return (
<>
<div className='fixed top-0 right-10 w-11/12 -z-10 translate-y-[-80%]'>
<Image src={assets.header_bg_color} alt='header background' className='w-full' />
</div>
<nav className="w-full px-4 py-4 lg:px-8 xl:px-16 flex items-center justify-between z-50">
<a href="">
<Image src={assets.logo} alt='name' className='w-28 cursor-pointer mr-14' />
</a>
<ul className="hidden md:flex items-center gap-8 lg:gap-8 rounded-full px-12 py-3 bg-white
shadow-sm bog-opacity-50 backdrop-blur-md">
<li><a className='font-ovo' href="#top">Home</a></li>
<li><a className='font-ovo' href="#about">About Me</a></li>
<li><a className='font-ovo' href="#service">Services</a></li>
<li><a className='font-ovo' href="#work">My Work</a></li>
<li><a className='font-ovo' href="#contact">Contact Me</a></li>
</ul>
<div className='flex items-center gap-4 lg:gap-6'>
<button>
<Image src={assets.moon_icon} alt='dark_mode' className='w-8'/>
</button>
<a href="#contact" className='hidden lg:flex items-center gap-3 px-10 py-2.5
border border-gray-500 rounded-full ml-4'>Contact
<Image src={assets.arrow_icon} alt='arrow' className='w-3'/></a>
<button className='block md:hidden ml-3' onClick={openMenu}>
<Image src={assets.menu_black} alt='menu' className='w-6'/>
</button>
</div>
{/* {mobile menu} */}
<ul ref={sideMenuRef} style={{ transform: 'translateX(0)'}} ##### 첫 화면부터 오픈 메뉴 활성화
className='absolute flex md:hidden flex-col gap-4 py-20 px-10 fixed -right-0 top-0 bottom-0
w-64 z-50 h-screen bg-rose-50 transition duration-500'>
<div className='absolute top-5 right-5' onClick={closeMenu}>
<Image src={assets.close_black} alt='X-bar' className='w-5 cursor-pointer mb-2' />
</div>
<li><a className='font-ovo' onClick={closeMenu} href="#top">Home</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#about">About Me</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#service">Services</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#work">My Work</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#contact">Contact Me</a></li>
</ul>
</nav>
</>
)
}
export default Navbar

translateX(0)으로 해결 완료

Header.jsx


h-screen: 화면에 맞추어 높이 설정
overflow-x-hidden : 가로 스크롤 숨김

layout.js

page.js

About.jsx

tailwindcss.jsx

NEXT.js 포트폴리오 제작-3

'use client'
import { assets } from '@/assets/assets'
import React, {useEffect, useRef, useState} from 'react'
import Image from 'next/image'
const Navbar = () => {
const [isScroll, setIsScroll] = useState(false);
const sideMenuRef = useRef();
const openMenu = () => {
sideMenuRef.current.style.transform = 'translateX(0)'
};
const closeMenu = () => {
sideMenuRef.current.style.transform = 'translateX(16rem)'
};
useEffect(() => {
window.addEventListener('scroll', () => {
if(scrollY > 50) {
setIsScroll(true)
}else {
setIsScroll(false)
}
})
}, []);
return (
<>
<div className='fixed top-0 right-10 w-11/12 -z-10 translate-y-[-80%]'>
<Image src={assets.header_bg_color} alt='header background' className='w-full' />
</div>
<nav className='w-full fixed px-4 py-4 lg:px-8 xl:px-[8%] flex items-center justify-between z-50
${isScroll ? "bg-white bg-opacity-50 backdrop-blur-lg shadow-sm" : "" }'>
<a href="#top">
<Image src={assets.logo} alt='name' className='w-28 cursor-pointer mr-14' />
</a>
<ul className={`hidden min-[795px]:flex items-center gap-8 lg:gap-8 rounded-full px-12 py-3 bg-white
shadow-sm bg-opacity-50`}>
<li><a className='font-ovo' href="#top">Home</a></li>
<li><a className='font-ovo' href="#about">About Me</a></li>
<li><a className='font-ovo' href="#service">Services</a></li>
<li><a className='font-ovo' href="#work">My Work</a></li>
<li><a className='font-ovo' href="#contact">Contact Me</a></li>
</ul>
<div className='flex items-center gap-4 lg:gap-6'>
<button>
<Image src={assets.moon_icon} alt='dark_mode' className='w-8 cursor-pointer'/>
</button>
<a href="#contact" className='hidden lg:flex items-center gap-3 px-10 py-2.5
border border-gray-500 rounded-full ml-4'>Contact
<Image src={assets.arrow_icon} alt='arrow' className='w-3'/></a>
<button className='block md:hidden ml-3 cursor-pointer' onClick={openMenu}>
<Image src={assets.menu_black} alt='menu' className='w-6'/>
</button>
</div>
{/* {mobile menu} */}
<ul ref={sideMenuRef} style={{ transform: 'translateX(0)'}}
className='absolute flex md:hidden flex-col gap-4 py-20 px-10 fixed -right-0 top-0 bottom-0
w-64 z-50 h-screen bg-rose-50 transition duration-500'>
<div className='absolute top-5 right-5' onClick={closeMenu}>
<Image src={assets.close_black} alt='X-bar' className='w-5 cursor-pointer mb-2' />
</div>
<li><a className='font-ovo' onClick={closeMenu} href="#top">Home</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#about">About Me</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#service">Services</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#work">My Work</a></li>
<li><a className='font-ovo' onClick={closeMenu} href="#contact">Contact Me</a></li>
</ul>
</nav>
</>
)
}
export default Navbar

상단 메뉴바 고정
카드박스 호버<ul className={'hidden min-[795px]:flex items-center gap-8 lg:gap-8 rounded-full px-12 py-3 bg-white shadow-sm bg-opacity-50'(백틱)}>
'알토르' 카테고리의 다른 글
| Git / Github (0) | 2026.05.06 |
|---|---|
| 알토르 2주차 채팅 레이아웃 (0) | 2026.05.05 |
| 알토르 2주차 NEXT.js로 포트폴리오 제작 (0) | 2026.05.04 |
| React 입문 5가지: SPA/MPA, JSX, 컴포넌트, Props/State, create-react-app 설치까지 (0) | 2026.05.03 |
| 알토르 1주차 - 업다운 게임 (3) | 2025.08.18 |