CSS 입문 10편 - 실전 프로젝트

(수정: ) learning by Seven Fingers Studio 25분
CSS실전프로젝트포트폴리오랜딩페이지웹사이트제작

css guide 10 practical

이제 진짜 웹사이트를 만들 시간!

지금까지 CSS의 기초부터 고급 기능까지 모두 배웠어요. 이제 이론은 충분하니 실전 프로젝트로 실력을 다져봅시다!

이번 글에서는 세 가지 완성도 높은 웹사이트를 처음부터 끝까지 만들어볼 거예요. 코드를 직접 따라 치면서 실력을 쌓으세요!

프로젝트 1: 개인 포트폴리오 사이트

HTML 구조

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>김개발 - 프론트엔드 개발자</title>
  <link rel="stylesheet" href="portfolio.css">
</head>
<body>
  <nav class="navbar">
    <div class="logo">Kim Dev</div>
    <ul class="nav-menu">
      <li><a href="#about">About</a></li>
      <li><a href="#projects">Projects</a></li>
      <li><a href="#skills">Skills</a></li>
      <li><a href="#contact">Contact</a></li>
    </ul>
  </nav>

  <section class="hero">
    <div class="hero-content">
      <h1>안녕하세요, 김개발입니다</h1>
      <p>사용자 경험을 최우선으로 생각하는 프론트엔드 개발자입니다.</p>
      <a href="#projects" class="btn-primary">프로젝트 보기</a>
    </div>
  </section>

  <section id="about" class="section">
    <div class="container">
      <h2>About Me</h2>
      <div class="about-grid">
        <div class="about-text">
          <p>3년차 프론트엔드 개발자로, React와 Vue를 주로 사용합니다.</p>
          <p>깔끔한 코드와 사용자 경험에 관심이 많습니다.</p>
        </div>
        <div class="about-image">
          <img src="profile.jpg" alt="프로필">
        </div>
      </div>
    </div>
  </section>

  <section id="projects" class="section section-gray">
    <div class="container">
      <h2>Projects</h2>
      <div class="projects-grid">
        <div class="project-card">
          <img src="project1.jpg" alt="프로젝트 1">
          <h3>전자상거래 플랫폼</h3>
          <p>React와 Redux를 활용한 쇼핑몰 프로젝트</p>
          <div class="project-tags">
            <span class="tag">React</span>
            <span class="tag">Redux</span>
            <span class="tag">TypeScript</span>
          </div>
        </div>
        <div class="project-card">
          <img src="project2.jpg" alt="프로젝트 2">
          <h3>업무 관리 대시보드</h3>
          <p>Vue3와 Vuex를 활용한 프로젝트 관리 도구</p>
          <div class="project-tags">
            <span class="tag">Vue 3</span>
            <span class="tag">Vuex</span>
            <span class="tag">Sass</span>
          </div>
        </div>
        <div class="project-card">
          <img src="project3.jpg" alt="프로젝트 3">
          <h3>날씨 알림 앱</h3>
          <p>API 연동 및 위치 기반 날씨 정보 제공</p>
          <div class="project-tags">
            <span class="tag">JavaScript</span>
            <span class="tag">API</span>
            <span class="tag">CSS3</span>
          </div>
        </div>
      </div>
    </div>
  </section>

  <section id="contact" class="section">
    <div class="container">
      <h2>Contact</h2>
      <div class="contact-info">
        <p>이메일: kim@example.com</p>
        <p>GitHub: github.com/kimdev</p>
        <p>LinkedIn: linkedin.com/in/kimdev</p>
      </div>
    </div>
  </section>

  <footer>
    <p>&copy; 2025 Kim Dev. All rights reserved.</p>
  </footer>
</body>
</html>

CSS (portfolio.css)

/* 변수 정의 */
:root {
  --color-primary: #6366f1;
  --color-text: #1f2937;
  --color-text-light: #6b7280;
  --color-bg: #ffffff;
  --color-bg-light: #f9fafb;
  --spacing: clamp(1rem, 3vw, 2rem);
  --font-size-base: clamp(1rem, 2.5vw, 1.125rem);
  --font-size-heading: clamp(2rem, 5vw, 3rem);
}

/* 리셋 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  color: var(--color-text);
  line-height: 1.6;
  font-size: var(--font-size-base);
}

/* 네비게이션 */
.navbar {
  position: fixed;
  top: 0;
  width: 100%;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  padding: 1rem 2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
  z-index: 1000;
}

.logo {
  font-size: 1.5rem;
  font-weight: bold;
  color: var(--color-primary);
}

.nav-menu {
  display: flex;
  gap: 2rem;
  list-style: none;
}

.nav-menu a {
  text-decoration: none;
  color: var(--color-text);
  font-weight: 500;
  transition: color 0.3s;
}

.nav-menu a:hover {
  color: var(--color-primary);
}

/* 히어로 섹션 */
.hero {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  text-align: center;
}

.hero-content h1 {
  font-size: var(--font-size-heading);
  margin-bottom: 1rem;
  animation: fadeInUp 0.8s ease;
}

.hero-content p {
  font-size: 1.25rem;
  margin-bottom: 2rem;
  opacity: 0.9;
  animation: fadeInUp 0.8s ease 0.2s both;
}

.btn-primary {
  display: inline-block;
  padding: 1rem 2rem;
  background: white;
  color: var(--color-primary);
  text-decoration: none;
  border-radius: 50px;
  font-weight: 600;
  transition: all 0.3s;
  animation: fadeInUp 0.8s ease 0.4s both;
}

.btn-primary:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 섹션 공통 */
.section {
  padding: 5rem 2rem;
}

.section-gray {
  background: var(--color-bg-light);
}

.container {
  max-width: 1200px;
  margin: 0 auto;
}

.section h2 {
  font-size: 2.5rem;
  text-align: center;
  margin-bottom: 3rem;
  color: var(--color-text);
}

/* About 섹션 */
.about-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 3rem;
  align-items: center;
}

.about-text p {
  margin-bottom: 1rem;
  color: var(--color-text-light);
}

.about-image img {
  width: 100%;
  border-radius: 20px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}

/* 프로젝트 그리드 */
.projects-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

.project-card {
  background: white;
  border-radius: 15px;
  overflow: hidden;
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  transition: transform 0.3s, box-shadow 0.3s;
}

.project-card:hover {
  transform: translateY(-10px);
  box-shadow: 0 15px 30px rgba(0,0,0,0.15);
}

.project-card img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.project-card h3 {
  padding: 1.5rem 1.5rem 0.5rem;
  font-size: 1.25rem;
}

.project-card p {
  padding: 0 1.5rem 1rem;
  color: var(--color-text-light);
}

.project-tags {
  display: flex;
  gap: 0.5rem;
  padding: 0 1.5rem 1.5rem;
  flex-wrap: wrap;
}

.tag {
  background: var(--color-bg-light);
  padding: 0.25rem 0.75rem;
  border-radius: 20px;
  font-size: 0.875rem;
  color: var(--color-primary);
}

/* 연락처 */
.contact-info {
  text-align: center;
  font-size: 1.125rem;
}

.contact-info p {
  margin-bottom: 1rem;
}

/* 푸터 */
footer {
  background: var(--color-text);
  color: white;
  text-align: center;
  padding: 2rem;
}

/* 반응형 */
@media (max-width: 768px) {
  .nav-menu {
    display: none;
  }

  .about-grid {
    grid-template-columns: 1fr;
  }

  .projects-grid {
    grid-template-columns: 1fr;
  }

  .section {
    padding: 3rem 1rem;
  }
}

완성 모습:

안녕하세요, 김개발입니다
사용자 경험을 최우선으로 생각하는 프론트엔드 개발자입니다.
프로젝트 보기
전자상거래 플랫폼
React와 Redux를 활용한 쇼핑몰
업무 관리 대시보드
Vue3와 Vuex를 활용한 도구
날씨 알림 앱
API 연동 및 위치 기반 서비스

고정 네비게이션, 그라디언트 히어로 섹션, 호버 효과가 있는 프로젝트 카드로 구성된 포트폴리오 사이트입니다

프로젝트 2: 제품 랜딩 페이지

핵심 CSS (간략 버전)

:root {
  --gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  --shadow-card: 0 10px 30px rgba(0,0,0,0.1);
}

/* 히어로 섹션 */
.landing-hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 100vh;
  align-items: center;
  gap: 4rem;
  padding: 2rem;
}

.hero-text h1 {
  font-size: clamp(2.5rem, 8vw, 5rem);
  line-height: 1.1;
  margin-bottom: 1.5rem;
}

.hero-image img {
  width: 100%;
  animation: float 3s ease-in-out infinite;
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-20px); }
}

/* 특징 카드 */
.features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  padding: 5rem 2rem;
}

.feature-card {
  text-align: center;
  padding: 2rem;
  border-radius: 20px;
  background: white;
  box-shadow: var(--shadow-card);
  transition: transform 0.3s;
}

.feature-card:hover {
  transform: translateY(-10px);
}

.feature-icon {
  font-size: 3rem;
  margin-bottom: 1rem;
}

/* CTA 버튼 */
.cta-section {
  text-align: center;
  padding: 5rem 2rem;
  background: var(--gradient-primary);
  color: white;
}

.cta-button {
  display: inline-block;
  padding: 1.25rem 3rem;
  background: white;
  color: #667eea;
  font-size: 1.25rem;
  font-weight: 600;
  border-radius: 50px;
  text-decoration: none;
  box-shadow: 0 10px 25px rgba(0,0,0,0.2);
  transition: all 0.3s;
}

.cta-button:hover {
  transform: scale(1.05);
  box-shadow: 0 15px 35px rgba(0,0,0,0.3);
}

@media (max-width: 768px) {
  .landing-hero {
    grid-template-columns: 1fr;
  }

  .features {
    grid-template-columns: 1fr;
  }
}

완성 모습:

혁신적인 제품으로 더 나은 내일을
최신 기술로 만든 완벽한 솔루션을 만나보세요
지금 시작하기
제품 이미지
빠른 속도
최적화된 성능으로 빠르게
🔒
안전한 보안
철저한 보안으로 안심
💎
프리미엄 품질
최고급 품질 보장
지금 바로 시작하세요
무료 체험으로 먼저 경험해보세요
무료로 시작하기

2단 그리드 히어로 섹션, 특징 카드, 그라디언트 CTA 버튼으로 구성된 제품 랜딩 페이지입니다

css guide 10 practical

프로젝트 3: 대시보드 UI

HTML 구조

<div class="dashboard">
  <aside class="sidebar">
    <div class="sidebar-header">
      <h2>Dashboard</h2>
    </div>
    <nav class="sidebar-nav">
      <a href="#" class="nav-item active">
        <span class="icon">📊</span>
        <span>Overview</span>
      </a>
      <a href="#" class="nav-item">
        <span class="icon">📈</span>
        <span>Analytics</span>
      </a>
      <a href="#" class="nav-item">
        <span class="icon">⚙️</span>
        <span>Settings</span>
      </a>
    </nav>
  </aside>

  <main class="main-content">
    <header class="topbar">
      <h1>Overview</h1>
      <div class="user-menu">
        <img src="avatar.jpg" alt="User">
      </div>
    </header>

    <div class="stats-grid">
      <div class="stat-card">
        <h3>Total Users</h3>
        <p class="stat-value">12,456</p>
        <span class="stat-change positive">+12.5%</span>
      </div>
      <div class="stat-card">
        <h3>Revenue</h3>
        <p class="stat-value">$45,231</p>
        <span class="stat-change positive">+8.2%</span>
      </div>
      <div class="stat-card">
        <h3>Orders</h3>
        <p class="stat-value">1,234</p>
        <span class="stat-change negative">-3.1%</span>
      </div>
    </div>

    <div class="chart-container">
      <h2>Sales Overview</h2>
      <div class="chart-placeholder">
        [차트가 여기에 표시됩니다]
      </div>
    </div>
  </main>
</div>

CSS (dashboard.css)

:root {
  --sidebar-width: 250px;
  --topbar-height: 70px;
  --color-primary: #6366f1;
  --color-success: #10b981;
  --color-danger: #ef4444;
  --color-bg: #f9fafb;
  --color-sidebar: #1e293b;
}

.dashboard {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  min-height: 100vh;
}

/* 사이드바 */
.sidebar {
  background: var(--color-sidebar);
  color: white;
  padding: 2rem 0;
}

.sidebar-header {
  padding: 0 2rem;
  margin-bottom: 2rem;
}

.sidebar-header h2 {
  font-size: 1.5rem;
  color: var(--color-primary);
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 2rem;
  color: rgba(255,255,255,0.7);
  text-decoration: none;
  transition: all 0.3s;
}

.nav-item:hover {
  background: rgba(255,255,255,0.1);
  color: white;
}

.nav-item.active {
  background: rgba(99, 102, 241, 0.2);
  color: white;
  border-left: 3px solid var(--color-primary);
}

.icon {
  font-size: 1.25rem;
}

/* 메인 콘텐츠 */
.main-content {
  background: var(--color-bg);
  display: grid;
  grid-template-rows: var(--topbar-height) 1fr;
}

/* 상단바 */
.topbar {
  background: white;
  padding: 0 2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}

.user-menu img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
}

/* 통계 카드 */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
  padding: 2rem;
}

.stat-card {
  background: white;
  padding: 1.5rem;
  border-radius: 15px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}

.stat-card h3 {
  font-size: 0.875rem;
  color: #6b7280;
  margin-bottom: 0.5rem;
}

.stat-value {
  font-size: 2rem;
  font-weight: bold;
  margin-bottom: 0.5rem;
}

.stat-change {
  font-size: 0.875rem;
  font-weight: 600;
}

.stat-change.positive {
  color: var(--color-success);
}

.stat-change.negative {
  color: var(--color-danger);
}

/* 차트 */
.chart-container {
  margin: 0 2rem 2rem;
  background: white;
  padding: 2rem;
  border-radius: 15px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}

.chart-placeholder {
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg);
  border-radius: 10px;
  color: #6b7280;
}

/* 반응형 */
@media (max-width: 768px) {
  .dashboard {
    grid-template-columns: 1fr;
  }

  .sidebar {
    display: none;
  }

  .stats-grid {
    grid-template-columns: 1fr;
  }
}

완성 모습:

Dashboard
📊Overview
📈Analytics
⚙️Settings
Overview
Total Users
12,456
+12.5%
Revenue
$45,231
+8.2%
Orders
1,234
-3.1%
Sales Overview
[차트 영역]

고정 사이드바, 통계 카드, 차트 영역으로 구성된 관리자 대시보드 UI입니다

최종 체크리스트

프로젝트를 완성했다면 이것들을 확인하세요:

기능성

  • 모든 링크 작동
  • 반응형 동작 확인 (모바일, 태블릿, 데스크톱)
  • 호버 효과 정상 작동
  • 애니메이션 부드러움

성능

  • 이미지 최적화 (WebP, 적절한 크기)
  • CSS 파일 압축
  • 불필요한 코드 제거
  • 렌더링 성능 (transform, opacity 사용)

접근성

  • 시맨틱 HTML 사용
  • alt 속성 모든 이미지에 추가
  • 키보드 탐색 가능
  • 색상 대비 충분

호환성

  • Chrome, Firefox, Safari에서 테스트
  • 실제 모바일 기기에서 확인

다음 학습 방향

CSS를 넘어서

  1. CSS 전처리기

    • Sass/SCSS
    • Less
  2. CSS 프레임워크

    • Tailwind CSS (추천!)
    • Bootstrap
    • Material UI
  3. CSS-in-JS

    • Styled Components
    • Emotion
  4. 빌드 도구

    • PostCSS
    • CSS Modules

JavaScript 통합

<button class="toggle-button">테마 전환</button>

<script>
const button = document.querySelector('.toggle-button');
button.addEventListener('click', () => {
  document.body.classList.toggle('dark');
});
</script>

지속적 학습

  • Codepen: 다른 사람 코드 보기
  • CSS Tricks: 최신 기법 배우기
  • Frontend Mentor: 실전 프로젝트 연습
  • Daily CSS: 매일 작은 프로젝트

마무리

CSS 독학 가이드 10편을 모두 완주하셨어요!

여러분은 이제:

  • ✅ CSS 기초 완벽 이해
  • ✅ Flexbox와 Grid로 자유로운 레이아웃
  • ✅ 반응형 디자인 구현
  • ✅ 애니메이션과 효과 추가
  • ✅ 고급 선택자와 변수 활용
  • ✅ 실전 프로젝트 제작

가장 중요한 것:

  • 매일 조금씩 코드 치기
  • 실제 프로젝트 만들어보기
  • 다른 사람 코드 분석하기
  • 트렌드 계속 따라가기

운영자 실전 노트

실제 프로젝트 진행하며 겪은 문제

  • 실무 CSS 구조화 실패 → 하나의 CSS 파일에 5000줄. 기능별 분리(reset.css, layout.css, components.css)했다
  • 유지보수 전략 부재 → 6개월 후 내가 쓴 코드 이해 못함. 주석과 명확한 네이밍이 필수다
  • 컴포넌트 재사용 안 됨 → 매번 비슷한 스타일 복붙. CSS 변수와 유틸리티 클래스로 재사용성 높였다

이 경험을 통해 알게 된 점

  • CSS 아키텍처(SMACSS, ITCSS)를 초기 설계하면 확장이 쉽다
  • 매일 작은 프로젝트를 만들면 실력이 기하급수적으로 는다

CSS는 끝이 없다. 계속 새로운 기능이 나오고, 디자인 트렌드도 바뀐다. 하지만 기초를 탄탄히 다졌으니 어떤 변화도 금방 따라잡을 수 있다.

여러분의 첫 프로젝트를 만들어보자. 완벽하지 않아도 괜찮다. 시작이 반이다.

시리즈 네비게이션

CSS 독학 가이드 시리즈를 모두 완주하셨습니다. 수고 많았어요!

← 블로그 목록으로