목차
Next js 튜토리얼 7편 : 컴포넌트 스타일링 - 현재 글
Next js 튜토리얼 8편 : 배포
Styling Components
지금까지 컴포넌트의 스타일링을 많이 하지 않았습니다. 하지만 앱에는 스타일이 필요합니다.
리엑트 앱에는 스타일을 적용하는 많은 기술들이 있으며, 크게 두가지의 방법으로 분류할 수 있습니다
1. 전통적인 css 파일 기반에 스타일링 (SASS, PostCSS 등)
2. CSS in Js 스타일링
전통적인 css 파일에는 고려해야하는 문제들이 많이 있으므로(특히 SSR에서) Next.js에서는 이 방법을 사용하지 않는 것이 좋습니다.
CSS파일을 import 하는 것보다 각각의 컴포넌트의 스타일을 지정할 수 있는 CSS in Js를 권장합니다
Next.js에는 styled-jsx 라는 CSS 프레임워크가 준비되어 있습니다. 컴포넌트에 CSS 규칙을 사용할 수 있으며, 다른 컴포넌트에 영항을 주지 않습니다.
(개인적으로는 styled-component를 주로 사용합니다.
styled-component 적용 방법은 https://jcon.tistory.com/118?category=798379 에서 확인 할 수 있습니다)
Setup
아래의 예제를 다운로드 해주세요
git clone https://github.com/zeit/next-learn-demo.git
cd next-learn-demo
cd 7-styling-components
npm install
npm run dev
Styling our home page
'pages/index.js'에 스타일을 추가해 봅시다
아래의 코드를 추가해 주세요
import Layout from '../components/MyLayout'
import Link from 'next/link'
function getPosts() {
return [
{ id: 'hello-nextjs', title: 'Hello Next.js' },
{ id: 'learn-nextjs', title: 'Learn Next.js is awesome' },
{ id: 'deploy-nextjs', title: 'Deploy apps with ZEIT' }
]
}
export default function Blog() {
return (
<Layout>
<h1>My Blog</h1>
<ul>
{getPosts().map(post => (
<li key={post.id}>
<Link href="/p/[id]" as={`/p/${post.id}`}>
<a>{post.title}</a>
</Link>
</li>
))}
</ul>
<style jsx>{`
h1,
a {
font-family: 'Arial';
}
ul {
padding: 0;
}
li {
list-style: none;
margin: 5px 0;
}
a {
text-decoration: none;
color: blue;
}
a:hover {
opacity: 0.6;
}
`}</style>
</Layout>
)
}
<style jsx>요소를 살펴 봅시다. 이곳에 우리는 css규칙을 사용했습니다
저장 후 home 페이지를 확인 해보면 css가 적용된 것을 확인 할 수 있습니다.
style 태그의 안에 직접적으로 css를 사용하지 않고, template string( `{` `}` )의 안쪽에 작성하였습니다
template string을 사용하지 않는다면 작동하지 않습니다
Styling Components
Styled jsx는 바벨 플러그인으로 작동합니다. css의 모드 것을 파싱하고 빌드 할 때 적용이 됩니다.
CSS가 template string안에 들어가야 하는 이유는 동적인 변수 또한 지원하기 때문입니다
Styles and Nested Components
home 페이지에 작은 변화를 줍시다. 아래의 코드를 pages/index.js에 작성하세요
import Layout from '../components/MyLayout'
import Link from 'next/link'
function getPosts() {
return [
{ id: 'hello-nextjs', title: 'Hello Next.js' },
{ id: 'learn-nextjs', title: 'Learn Next.js is awesome' },
{ id: 'deploy-nextjs', title: 'Deploy apps with ZEIT' }
]
}
const PostLink = ({ post }) => (
<li>
<Link href="/p/[id]" as={`/p/${post.id}`}>
<a>{post.title}</a>
</Link>
</li>
)
export default function Blog() {
return (
<Layout>
<h1>My Blog</h1>
<ul>
{getPosts().map(post => (
<PostLink key={post.id} post={post} />
))}
</ul>
<style jsx>{`
h1,
a {
font-family: 'Arial';
}
ul {
padding: 0;
}
li {
list-style: none;
margin: 5px 0;
}
a {
text-decoration: none;
color: blue;
}
a:hover {
opacity: 0.6;
}
`}</style>
</Layout>
)
}
ul 태그 안의 내용을 함수형 컴포넌트로 빼서 작성했습니다. 저장 후 확인 해보면 함수형 컴포넌트(PostLink)에 css가 적용되지 않는 것을 확인 할 수 있습니다. 즉, style-jsx는 하위 컴포넌트에 영향을 주지 않습니다. 이 기능은 큰 사이즈의 앱을 관리할 때 도움이 됩니다
이렇게 컴포넌트가 분리되어 있으면 PostLink에도 아래와 같이 스타일을 지정해 주어야 합니다
const PostLink = ({ post }) => (
<li>
<Link href="/p/[id]" as={`/p/${post.id}`}>
<a>{post.title}</a>
</Link>
<style jsx>{`
li {
list-style: none;
margin: 5px 0;
}
a {
text-decoration: none;
color: blue;
font-family: 'Arial';
}
a:hover {
opacity: 0.6;
}
`}</style>
</li>
);
또는 global selectors를 사용할 수 있습니다
Global Styles
가끔은 자식 컴포넌트의 안에서 스타일을 바꿔야 할 때가 있습니다. 특히 리엑트에서 마크다운을 사용해야 할 때 그렇습니다.
'pages/p/p[id].js'에 아래의 코드를 작성해 주세요
npm install --save react-markdown
import { useRouter } from 'next/router'
import Markdown from 'react-markdown'
import Layout from '../../components/MyLayout'
export default () => {
const router = useRouter()
return (
<Layout>
<h1>{router.query.id}</h1>
<div className="markdown">
<Markdown
source={`
This is our blog post.
Yes. We can have a [link](/link).
And we can have a title as well.
### This is a title
And here's the content.
`}
/>
</div>
<style jsx global>{`
.markdown {
font-family: 'Arial';
}
.markdown a {
text-decoration: none;
color: blue;
}
.markdown a:hover {
opacity: 0.6;
}
.markdown h3 {
margin: 0;
padding: 0;
text-transform: uppercase;
}
`}</style>
</Layout>
)
}
저장 후 확인 해보면 markdown 아래의 a 태그 등에 스타일이 적용된 것을 확인 할 수 있습니다
Global Styles Work
이는 global로 스타일을 지정했기 때문에 작동합니다.
이 기능은 유용할 수는 있지만 global스타일 보단 scoped 스타일을 사용하는 것을 권장합니다
평범한 스타일 태그를 사용하는 것보다는 좋은 방법입니다. sryled-jsx를 사용하면 바벨 플러그인 안에서 필요한 브라우저 prefixing과 css가 검증이 완료 됨으로 추가적인 overhead시간이 들어 가지 않습니다
What Next
우리는 styled-jsx까지 Next.js의 기초적인 내용을 학습했습니다.
styled-jsx에 대해 자세히 알고 싶다면 styled-jsx 깃허브 repo를 참고하세요
other styling solutions와 같은 다른 방법도 있습니다. 한번 확인해 보면 좋을 것 같습니다
다음 장에는 Next.js App을 배포하는 방법에 대해 배워보겠습니다
Next js 튜토리얼 7편 : 컴포넌트 스타일링 - 현재 글
Next js 튜토리얼 8편 : 배포