CSS를 적용하고 싶은 파일 (NavBar.tsx) 의 이름에 맞게 NavBar.module.css 를 생성해준다.
@component/NavBar.module.css
.nav {
display: flex;
justify-content: space-between;
background-color: tomato;
}
이렇게 CSS를 작성한 후 해당 파일에 import하기 위해선 다음과 같이 쓰면 된다.
@component/NavBar.tsx
"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import styles from './navBar.module.css' //style을 import
export default function NavBar() {
const pathname = usePathname();
return <nav className={styles.nav}>
//<nav className=nav> 로 쓰는 대신에
//<nav className={styles.nav}> 이런식으로 써야 한다.
<Link style = {{color: pathname === "/" ? "red" : "blue"}} className='Hello' href="/">
Home
</Link>
<Link style = {{color: pathname === "/about"? "red": "blue"}} href="/about">
About Us
</Link>
</nav>
}
html 태그에 class를 추가할 때 JS property 형식으로 추가해야 한다.
이런식으로 작성한 class는 실제 브라우저에 읽는 html 태그에서는
class=”NavBar_nav__임의의 문자”와 같은 형식으로 만들어져 충돌을 피한다.
이런 식으로 클래스 이름이 랜덤으로 만들어지기 때문에 클래스명이 중복되어도 큰 문제가 발생하지 않는다.
"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import styles from './navBar.module.css'
export default function NavBar() {
const pathname = usePathname();
return <nav>
<Link className={pathname === "/" ? styles.active : ""} href="/">
Home
</Link>
<Link className={pathname === "/about"? styles.active: ""} href="/about">
About Us
</Link>
</nav>
}
``
)을 사용해 템플릿 리터럴로 각 className을 묶어서 표시하기[].join(” “)
으로 한 칸 공백을 두고 합쳐버리기"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import styles from './navBar.module.css'
export default function NavBar() {
const pathname = usePathname();
return <nav>
<Link className={`${styles.link}
${pathname === "/" ? styles.active : ""}`} href="/">
Home
</Link>
<Link className={[styles.link,
pathname === "/about"? styles.active: ""].join(" ")}
href="/about">
About Us
</Link>
</nav>
}
return 으로 반환하는 html 태그에서 <style jsx>{`여기에 css 작성`}</style>
을 사용하여 CSS를 적용할 수 있다.
"use client"
import Link from 'next/link'
import { usePathname } from 'next/navigation'
export default function NavBar() {
const pathname = usePathname();
return <nav>
<Link className={pathname === "/" ? "active" : ""} href="/">
Home
</Link>
<Link className={pathname === "/about" ? "active" : ""} href="/about">
About Us
</Link>
<style jsx global>{`
nav {
background: tomato;
}
a {
text-decoration: none;
}
.active {
color: white;
}
`}</style>
</nav>
}
이렇게 jsx를 사용하면 class는 알 수 없는 16진수 숫자와 함께 랜덤생성 되며 이는 상위 페이지나 상위 컴포넌트에서 같은 class를 사용하더라도 충돌을 막아주는 역할을 한다.
그리고, Next.js 13에서 <Link>
안에 <a>
를 사용할 수 없게 되어서 발생한 문제 같은데, jsx로 <Link>
에 css를 적용하는 것이 불가능하다.
styled-jsx의 readme에서 보면, global 속성을 이용하여 <Link>
는 브라우저가 읽을 때 <a>
로 parsing되기 때문에 jsx를 global로 적용하고 a 태그에 CSS를 작성하는 것으로 어느 정도 비슷하게 할 수는 있지만 아직 className을 적용하는 것을 완벽하게 대체하지는 못하는 것 같다.
font-size, font-family 등 사이트에 전역적으로 스타일을 적용하는 방법
어떤 component에 대한 일종의 청사진.
인터넷에서 찾을 수 있는 여러 강의들에선 ./pages/_app.tsx 등의 파일을 만들고 그 파일 안에 모든 페이지에서 공용으로 사용하는 style이나 elements를 쓰라고 했었지만 Next.js 가 13으로 업데이트 되고 나선 이 역할을 기본으로 생성되는 파일 layout.tsx에서 하게 된다!
마찬가지로 공용으로 사용하는 style은 자동으로 생성되는 globals.css 안에 적어주면 자동으로 적용된다.
@app/layout.tsx
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import NavBar from '../components/NavBar';
import './globals.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>
<NavBar />
{children}
</body>
</html>
)
}
이런 식으로 RootLayout 함수 안에 모든 페이지에서 공용으로 사용할 수 있도록 import 해온 <NavBar />
태그를 가져와 모든 페이지에서 navigation 상단 바를 사용할 수 있게 했다. 이렇게 만든 후 각 페이지에 이미 작성했던 <NavBar />
태그는 지워주면 이전과 다름없이 사용할 수 있다.
이 RootLayout함수는 Next.js에서 구현된 모든 컴포넌트를 불러오는 역할을 하므로 지우거나 함부로 수정해서는 안 된다.
SEO(search engine optimize)과정에서 사용할 수 있도록 검색 봇에게 title과 description을 제공하는 기능이다.