# 챕터 5: CSS 기초 - 웹페이지에 스타일 입히기
## 서론
지금까지 우리는 HTML로 웹페이지의 구조를 만드는 방법을 배웠습니다. 하지만 HTML만으로 만든 웹페이지는 마치 시멘트 벽만 있는 건물처럼 밋밋하고 재미없어 보입니다. 이제 CSS(Cascading Style Sheets)를 사용하여 우리의 웹페이지를 아름답게 꾸며볼 시간입니다. CSS는 웹페이지의 디자이너라고 할 수 있습니다. 색상을 입히고, 크기를 조절하고, 위치를 배치하며, 애니메이션까지 추가할 수 있습니다.
이번 챕터에서는 CSS의 기본 개념과 작동 원리를 이해하고, Next.js에서 CSS를 사용하는 여러 가지 방법을 배워보겠습니다. CSS를 익히면 여러분의 웹페이지가 완전히 새로운 모습으로 변신하는 것을 경험하게 될 것입니다.
## 본론
### CSS란 무엇인가
CSS는 HTML 요소들이 화면에 어떻게 표시될지를 정의하는 스타일 언어입니다. HTML이 웹페이지의 내용과 구조를 담당한다면, CSS는 그 내용이 어떻게 보일 지를 결정합니다. 1996년에 처음 등장한 CSS는 이제 웹 개발에서 없어서는 안 될 핵심 기술이 되었습니다.
CSS의 가장 큰 장점은 스타일과 내용을 분리할 수 있다는 것입니다. 하나의 CSS 파일로 수백 개의 HTML 페이지 스타일을 일괄적으로 관리할 수 있으며, 스타일을 변경하고 싶을 때 CSS 파일만 수정하면 모든 페이지에 자동으로 반영됩니다.
### Next.js에서 CSS 사용하는 방법들
Next.js에서는 여러 가지 방법으로 CSS를 사용할 수 있습니다. 가장 기본적인 세 가지 방법을 알아보겠습니다.
첫 번째는 인라인 스타일입니다. JSX 요소에 직접 style 속성을 추가하는 방법입니다:
export default function Home() {
return (
<div style={{ backgroundColor: 'lightblue', padding: '20px' }}>
<h1 style={{ color: 'navy', fontSize: '32px' }}>
인라인 스타일 예제
</h1>
<p style={{ marginTop: '10px', lineHeight: '1.6' }}>
스타일을 직접 요소에 적용했습니다.
</p>
</div>
)
}
인라인 스타일은 빠르게 스타일을 적용할 수 있지만, 재사용이 어렵고 유지보수가 힘들다는 단점이 있습니다. 주의할 점은 CSS 속성명을 카멜케이스(camelCase)로 작성해야 한다는 것입니다. background-color는 backgroundColor로, font-size는 fontSize로 작성합니다.
두 번째는 CSS 모듈을 사용하는 방법입니다. 파일명을 .module.css로 만들면 해당 컴포넌트에서만 사용되는 독립적인 스타일을 정의할 수 있습니다. 먼저 my-first-website(root 폴더)/styles/Home.module.css 파일을 만들어봅시다.
/* styles/Home.module.css */
.container {
background-color: #f0f0f0;
padding: 20px;
border-radius: 10px;
}
.title {
color: #333;
font-size: 28px;
margin-bottom: 15px;
}
.description {
color: #666;
line-height: 1.8;
font-size: 16px;
}
그리고 이 스타일을 컴포넌트에서 import하여 사용합니다:
import styles from '../styles/Home.module.css'
export default function Home() {
return (
<div className={styles.container}>
<h1 className={styles.title}>CSS 모듈 사용하기 </h1>
<p className={styles.description}>
CSS 모듈을 사용하면 스타일이 컴포넌트별로 독립적으로 적용됩니다.
</p>
</div>
)
}
위 코드에서 styles는 Home.module.css를 불러올 때 지정한 임포트 이름입니다. CSS 모듈은 기본 임포트로 객체를 반환하며, .container, .title 같은 클래스명이 그 객체의 속성으로 매핑됩니다. 그래서 className={styles.container}처럼 작성하면 해당 클래스가 적용됩니다. 임포트 이름은 관례적으로 styles를 많이 쓰지만 homeCss처럼 다른 이름을 사용해도 되며, 이 경우 아래에서도 같은 이름으로 접근해야 합니다.
import homeCss from '../styles/Home.module.css'
// ...
<div className={homeCss.container}>...</div>
세 번째는 글로벌 CSS를 사용하는 방법입니다. 모든 페이지에 공통으로 적용되는 스타일은 global.css 파일에 정의합니다. 이에 대해서는 다음 챕터에서 자세히 다루겠습니다.
### CSS 선택자 이해하기
CSS 선택자는 어떤 HTML 요소에 스타일을 적용할지 지정하는 패턴입니다. 가장 기본적인 선택자들을 알아보겠습니다.
클래스 선택자는 점(.)으로 시작하며, className 속성이 일치하는 모든 요소에 스타일을 적용합니다:
/* 클래스 선택자 */
.box {
width: 200px;
height: 200px;
background-color: lightgreen;
}
.text-large {
font-size: 24px;
font-weight: bold;
}
태그 선택자는 특정 HTML 태그 모두에 스타일을 적용합니다:
/* 태그 선택자 */
h1 {
color: darkblue;
border-bottom: 2px solid #ddd;
}
p {
margin: 10px 0;
text-align: justify;
}
위 예시에서 .box, .text-large는 클래스 선택자입니다. 컴포넌트에서 필요한 요소에만 선택적으로 적용하며, CSS 모듈을 임포트한 뒤 className으로 연결합니다. 예를 들어 .box는 className={styles.box}로, 케밥 표기인 .text-large는 className={styles['text-large']}처럼 대괄호 표기로 접근합니다(점 표기를 쓰고 싶다면 .textLarge처럼 클래스명을 카멜표기로 바꾸는 것이 좋습니다).
반면 h1, p는 태그 선택자로, 문서 내 해당 태그 전체에 스타일을 적용합니다. CSS 모듈 파일 안에 작성하더라도 태그 선택자는 로컬 범위로 한정되지 않으므로 전역에 영향을 줄 수 있습니다. 따라서 페이지 전체에 적용되어야 하는 공통 규칙은 app/globals.css에 두고, 특정 컴포넌트에만 적용할 규칙은 .module.css 안에서 클래스 선택자로 정의해 className={styles.클래스명} 형태로 사용하는 것을 권장합니다.
이 두 코드를 styles/Home.module.css에 복사한 뒤, app/page.js 파일을 다음과 같이 수정해보면 CSS가 적용된 것을 확인할 수 있습니다. 이때 h1, p처럼 태그 전체에 적용되는 선택자는 CSS 모듈(Home.module.css)의 최상위에 두면 오류가 발생합니다. CSS 모듈은 로컬 범위를 강제하므로 최상위 선택자는 반드시 로컬 클래스나 ID를 포함해야 합니다. 따라서 문서 전역에 적용할 h1, p 스타일은 app/globals.css에 작성하는 것이 맞습니다. 반대로 특정 컴포넌트 내부에만 적용하고 싶다면 .container h1, .container p처럼 로컬 클래스 하위에 작성해 사용하세요.
import styles from '../styles/Home.module.css';
export default function Home() {
return (
<div>
<h1>제목입니다</h1>
<p className={styles['text-large']}>큰 텍스트 예시</p>
<div className={styles.box} />
<p>일반 단락</p>
</div>
);
}
### 색상과 배경 다루기
CSS에서 색상을 지정하는 방법은 여러 가지가 있습니다. 색상 이름, 16진수 코드, RGB, RGBA 등을 사용할 수 있습니다:
export default function Home() {
return (
<div>
<div style={{ backgroundColor: 'red' }}>
색상 이름 사용
</div>
<div style={{ backgroundColor: '#FF5733' }}>
16진수 코드 사용
</div>
<div style={{ backgroundColor: 'rgb(100, 200, 150)' }}>
RGB 값 사용
</div>
<div style={{ backgroundColor: 'rgba(100, 200, 150, 0.5)' }}>
투명도가 있는 RGBA
</div>
</div>
)
}
배경에는 색상뿐만 아니라 이미지도 설정할 수 있습니다:
.hero-section {
background-image: url('/hero-image.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
height: 400px;
}
import styles from '@/styles/Home.module.css';
export default function Home() {
return (
<section className={styles['hero-section']}>
<h1>Hero Section</h1>
</section>
);
}
### 부모 자식 이해하기(중요)
HTML에서는 한 요소가 다른 요소를 감싸면 앞의 요소를 ‘부모’, 안에 있는 요소를 ‘자식’이라고 부릅니다. 같은 부모 안에 나란히 있는 요소들은 ‘형제’입니다. 페이지는 이런 부모-자식 관계가 반복된 트리 구조(돔 트리)로 이루어집니다. 부모에 준 스타일은 자식에게도 영향을 줍니다. 레이아웃/박스 관련(배경색, 패딩, 디스플레이, flex/grid 컨텍스트 등)은 부모 박스에 적용되어 자식의 배치에 영향을 줍니다. 글자 관련(color, font-size 등)은 기본적으로 자식에게 상속됩니다. 자식은 자신의 스타일로 부모의 값을 덮어쓸 수 있습니다. 형제 요소는 서로 직접적인 상하 관계는 없고, 같은 부모 안에서 나란히 배치됩니다.
export default function Home() {
return (
<div style={{ background: '#f3f4f6', padding: 16, color: '#1f2937' }}>
<h2>부모 요소</h2>
<p>이 문장은 부모의 글자색(color)을 상속받습니다.</p>
<p style={{ color: '#ef4444' }}>이 문장은 자식에서 색을 덮어써 빨간색입니다.</p>
<div style={{ background: 'white', padding: 8 }}>
또 다른 자식 박스입니다.
</div>
</div>
);
}
여기서 중요한 점은 가장 바깥의 <div> 안에 들어있는 <h2>, <p>, <div>는 모두 형제 관계라는 점입니다.
### 크기와 여백 설정하기
요소의 크기는 width와 height로 설정합니다. 픽셀(px), 퍼센트(%), viewport 단위(vw, vh) 등 다양한 단위를 사용할 수 있습니다:
export default function Home() {
return (
<div>
<div style={{
width: '300px',
height: '100px',
backgroundColor: 'lightblue'
}}>
고정 크기 (300px × 100px)
</div>
<div style={{
width: '50%',
height: '100px',
backgroundColor: 'lightgreen'
}}>
부모 요소의 50% 너비
</div>
<div style={{
width: '80vw',
height: '20vh',
backgroundColor: 'lightyellow'
}}>
화면 크기의 80% 너비, 20% 높이
</div>
</div>
)
}
여백은 margin(외부 여백)과 padding(내부 여백)으로 구분됩니다. 이를 박스 모델이라고 부릅니다:
export default function home() {
return (
<div style={{ backgroundColor: '#f0 f0 f0' }}>
<div style={{
margin: '20px',
padding: '15px',
backgroundColor: 'white',
border: '2px solid #ddd'
}}>
margin은 요소 외부 여백, padding은 내부 여백입니다
</div>
<div style={{
marginTop: '10px',
marginBottom: '10px',
marginLeft: '20px',
marginRight: '20px',
padding: '10px 20px 30px 40px', // 상 우 하 좌
backgroundColor: 'lightcyan'
}}>
개별적으로 여백을 설정할 수도 있습니다
</div>
</div>
)
}
### 텍스트 스타일링
텍스트를 꾸미는 다양한 CSS 속성들이 있습니다:
export default function Home() {
return (
<div>
<p style={{
fontSize: '18px',
fontWeight: 'bold',
fontFamily: 'Arial, sans-serif'
}}>
글꼴 크기, 굵기, 종류를 설정했습니다
</p>
<p style={{
color: '#333',
textAlign: 'center',
textDecoration: 'underline'
}}>
색상, 정렬, 밑줄을 적용했습니다
</p>
<p style={{
lineHeight: '2',
letterSpacing: '2px',
textTransform: 'uppercase'
}}>
줄 간격, 자간, 대문자 변환을 적용했습니다
</p>
<p style={{
textShadow: '2px 2px 4px rgba(0,0,0,0.3)',
fontStyle: 'italic'
}}>
그림자와 기울임꼴을 적용했습니다
</p>
</div>
)
}
### 실습: 카드 컴포넌트 스타일링
이제 배운 내용을 종합하여 실제로 유용한 카드 컴포넌트를 만들고 스타일을 적용해 보겠습니다:
export default function Home() {
const cardStyle = {
width: '300px',
backgroundColor: 'white',
borderRadius: '8px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
overflow: 'hidden',
margin: '20px'
}
const imageStyle = {
width: '100%',
height: '200px',
backgroundColor: '#e0e0e0',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#999'
}
const contentStyle = {
padding: '20px'
}
const titleStyle = {
fontSize: '20px',
fontWeight: 'bold',
marginBottom: '10px',
color: '#333'
}
const descriptionStyle = {
color: '#666',
lineHeight: '1.6',
marginBottom: '15px'
}
const buttonStyle = {
backgroundColor: '#007bff',
color: 'white',
border: 'none',
padding: '10px 20px',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '14px'
}
return (
<div style={cardStyle}>
<div style={imageStyle}>
[이미지 영역]
</div>
<div style={contentStyle}>
<h2 style={titleStyle}>카드 제목 </h2>
<p style={descriptionStyle}>
이것은 CSS로 스타일링한 카드 컴포넌트입니다.
그림자, 둥근 모서리, 여백 등 다양한 스타일이 적용되었습니다.
</p>
<button style={buttonStyle}>더 알아보기</button>
</div>
</div>
)
}
앞서 설명한 방식은 .css 파일에 클래스를 만들고 className으로 적용하는 방법이었습니다. 지금은 “인라인 스타일” 방식으로, 자바스크립트 객체를 만들어 style={...}에 바로 넣고 있습니다. 둘 다 맞는 방법입니다. 간단한 데모나 빠른 실습은 인라인 스타일이 편하고, 규모가 커지면 CSS 모듈(예: *.module.css)로 클래스 관리가 더 좋습니다.
## 결론
CSS는 웹페이지에 생명을 불어넣는 마법과 같습니다. 이번 챕터에서 우리는 CSS의 기본 개념과 Next.js에서 CSS를 사용하는 방법, 선택자, 색상, 크기, 여백, 텍스트 스타일링 등 CSS의 핵심 속성들을 배웠습니다. 또한 실제로 카드 컴포넌트를 만들면서 배운 내용을 종합적으로 적용해 보았습니다.
CSS는 배울 내용이 매우 많지만, 기본 개념을 확실히 이해하면 나머지는 필요할 때마다 찾아가며 학습할 수 있습니다. 중요한 것은 직접 코드를 작성하고 결과를 확인하면서 경험을 쌓는 것입니다. 스타일을 조금씩 변경해보고, 어떤 변화가 일어나는지 관찰하면서 CSS와 친해지시기 바랍니다.
다음 챕터에서는 전체 웹사이트에 일관된 스타일을 적용하는 Global CSS에 대해 배워보겠습니다. Global CSS를 활용하면 더욱 체계적이고 유지보수가 쉬운 스타일 시스템을 구축할 수 있습니다!
'학습자료 > Next.js 초보자 학습 과정' 카테고리의 다른 글
| # Next.js 가이드 / 챕터 7: Tailwind CSS 시작하기 (2) | 2025.08.09 |
|---|---|
| # Next.js 가이드 / 챕터 6: Global CSS로 전체 스타일 관리하기 (4) | 2025.08.09 |
| # Next.js 가이드 / 챕터 4: HTML 기본 태그 완전 정복 (7) | 2025.08.08 |
| # Next.js 가이드 / 챕터 3: HTML의 기본 개념과 div 태그 이해하기 (1) | 2025.08.08 |
| # Next.js 가이드 / 챕터 2: Next.js 프로젝트 생성과 실행 (4) | 2025.08.08 |