NextJS

[NextJS] 다양한 Style 적용법: module.css, 1개의 컴포넌트에 2개 이상의 className 설정하는 방법, styles JSX

깃짱 2023. 12. 21. 22:00
반응형
반응형

 

 

소스 코드 보러가기 👉🏻 https://github.com/gitchan-Study/2023-next-js-beginner

 

GitHub - gitchan-Study/2023-next-js-beginner: 노마드코더 [NextJS 시작하기] 학습 코드

노마드코더 [NextJS 시작하기] 학습 코드. Contribute to gitchan-Study/2023-next-js-beginner development by creating an account on GitHub.

github.com

 

 

 

 

 

💋 컴포넌트에 Style 적용하기

✔️ 컴포넌트에 직접 style 속성 작성하기

곧바로 컴포넌트에 style 속성을 작성하면 된다.

 

 

NavBar.js

import Link from "next/link";
import {useRouter} from "next/router";

export default function NavBar() {
	const router = useRouter();

	return (
		<nav>
			<Link href="/" legacyBehavior>
				<a style={{color: router.pathname === "/" ? "red" : "blue"}}>Home</a>
			</Link>
			<Link href="/about" legacyBehavior>
				<a style={{color: router.pathname === "/about" ? "red" : "blue"}}> About < /a>
			</Link>
		</nav>
	);
}

 

코드가 정말 지저분해지기 때문에 상당히 비추

 

✔️ module css 사용하기

 

NavBar.module.css

.nav {
	display: flex;
	justify-content: space-between;
	background-color: tomato;
}

 

스타일을 적용할 태그에 className 속성과 함께 module.css 파일에서 정의한 속성 이름을 적어주면 된다.

import도 해줘야 하는데, 경로에 특히 주의해서 적어주자!

 

NavBar.js

import Link from "next/link";
import {useRouter} from "next/router";
import styles from "./NavBar.module.css"

export default function NavBar() {
	const router = useRouter();

	return (
		<nav className={styles.nav}>
			<Link href="/" legacyBehavior>
				<a>Home</a>
			</Link>
			<Link href="/about" legacyBehavior>
				<a> About < /a>
			</Link>
		</nav>
	);
}

 

그러면, css 적용이 겁나게 잘되어서, 백그라운드 컬러가 통째로 토마토 색이 되어버린 것을 볼 수 있다.

 

 

css module을 사용하면, property 형식으로 적기 때문에 실제 클래스 이름을 찾아보면, 띡 nav가 아니라, 겁나 복잡하게 붙여주기 때문에 다른 컴포넌트에서 nav라는 클래스 이름을 사용할 수 있게 되어서 골치아프게 충돌이 나지 않는다. ⇒ 클래스 이름을 중복 고민 없이 잘 지을 수 있게 된다.

 

 

또한, 이런식으로 className 자체를 조건에 따라서 붙여줄 수도 있다.

 

NavBar.js

import Link from "next/link";
import {useRouter} from "next/router";
import styles from "./NavBar.module.css";

export default function NavBar() {
	const router = useRouter();

	return (
		<nav>
			<Link href="/" legacyBehavior>
				<a className={router.pathname === "/" ? styles.active : ""}>Home</a>
			</Link>
			<Link href="/about" legacyBehavior>
				<a className={router.pathname === "/about" ? styles.active : ""}> About < /a>
			</Link>
		</nav>
	);
}

 

💋 1개의 컴포넌트에 2개 이상의 className 설정하기

 

NavBar.module.css

.link {
	text-decoration: none;
}

.active {
	color: tomato;
}

 

이렇게 두 가지 클래스를 하나의 컴포넌트에 적용하고 싶다면?

active는 조건에 따라서 적용하거나 적용하지 않게 할 것이라면?

 

✔️ 문자열로 className 여러 개 나열하기

className 속성에 백틱을 사용해서 문자열을 연결해준다. (조건문에 따라서 문자열이 알아서 바뀔 수 있도록)

 

NavBar.js

import Link from "next/link";
import {useRouter} from "next/router";
import styles from "./NavBar.module.css";

export default function NavBar() {
	const router = useRouter();

	return (
		<nav>
			<Link href="/" legacyBehavior>
				<a className={
					`${styles.link} ${
						router.pathname === "/" ? styles.active : ""
					}`
				}>Home</a>
			</Link>
			<Link href="/about" legacyBehavior>
				<a className={`${styles.link} ${
					router.pathname === "/about" ? styles.active : ""
				}`}> About < /a>
			</Link>
		</nav>
	);
}

 

아니면, 배열에 두 가지 이상의 className을 넣은 뒤에 띄어쓰기 한 칸을 두고 join하는 방식으로도 동일하게 문자열을 만들 수 있다.

 

NavBar.js

import Link from "next/link";
import {useRouter} from "next/router";
import styles from "./NavBar.module.css";

export default function NavBar() {
	const router = useRouter();

	return (
		<nav>
			<Link href="/" legacyBehavior>
				<a className={
					[
						styles.link,
						router.pathname === "/" ? styles.active : ""
					].join(" ")
				}>Home</a>
			</Link>
			<Link href="/about" legacyBehavior>
				<a className={
					[
						styles.link,
						router.pathname === "/about" ? styles.active : ""
					].join(" ")
				}> About < /a>
			</Link>
		</nav>
	);
}

 

암튼 포인트는 그냥 어떻게든 className을 띄어쓰기로 나열한 문자열을 만들면 된다는 것이다.

 

이렇게 하면, text decoration 없애기와 함께 색상 변경까지 동시에 적용된다.

 

 

근데 솔직히 가독성 구림.

 

✔️ styled JSX 사용하기

Next JS 고유의 방법이다.

 

  • 클래스 이름도 생각할 필요 없이, 태그 이름만으로도 스타일을 지정할 수 있다.
  • 부모 컴포넌트에는 적용이 안되며, 정확하게 그 클래스에만 독립적으로 적용된다.

 

NavBar.js

import Link from "next/link";
import {useRouter} from "next/router";

export default function NavBar() {
	const router = useRouter();

	return (
		<nav>
			<Link href="/" legacyBehavior>
				<a className={router.pathname === "/" ? "active" : ""}>Home</a>
			</Link>
			<Link href="/about" legacyBehavior>
				<a className={router.pathname === "/about" ? "active" : ""}>About</a>
			</Link>
			<style jsx>{
				`
				  nav {
					background-color: tomato;
				  }

				  a {
					text-decoration: none;
				  }

				  .active {
					color: yellow;
				  }
				`
			}</style>
		</nav>
	);
}

 

오…! 이전보다 더 이상해진 className이다.

 

 

 

하지만, styled JSX는 컴포넌트에 scoped(한정되어 적용)된다.

 

index.js

import NavBar from "@/components/NavBar";

export default function Home() {
	return (
		<div>
			<NavBar/>
			<h1>Hello</h1>
			<style jsx>{`
			  a {
				color: white;
			  }

			  h1 {
				background-color: tomato;
			  }
			`}</style>
		</div>
	);
}

 

현재 div에 한정되어 적용되기 때문에, NavBar에는 아무런 영향도 주지 못한다.

실제로도, h1인 Hello의 백그라운드 색에만 영향을 주고, NavBar 내부에 있는 a 태그의 글자 색은 하얀색으로 적용되지 않았다.

 

 

 

💋 Global Styled JSX

  • 컴포넌트에 scoped(한정되어 적용)되지 않게 하기 위해서는 global이라는 prop을 추가하면 된다.

 

index.js

import NavBar from "@/components/NavBar";

export default function Home() {
	return (
		<div>
			<NavBar/>
			<h1>Hello</h1>
			<style jsx global>{`
			  a {
				color: white;
			  }

			  h1 {
				background-color: tomato;
			  }
			`}</style>
		</div>
	);
}

 

 

하지만, /about으로 이동하면 다른 페이지가 되기 때문에 위에서 적용한 스타일이 모두 해제된다.

 

 

about.js

import NavBar from "@/components/NavBar";

export default function About() {
	return (
		<div>
			<NavBar/>
			<h1>About</h1>
		</div>
	);
};

 

⇒ Next JS는 페이지별로 생각해야 한다.

 

 

 

 

 

💋 참고자료

 

 

도움이 되었다면, 공감/댓글을 달아주면 깃짱에게 큰 힘이 됩니다!🌟
비밀댓글과 메일을 통해 오는 개인적인 질문은 받지 않고 있습니다. 꼭 공개댓글로 남겨주세요!

 

반응형