CSSCSS 기초 · 10기초

[CSS 완성 프로젝트] HTML 소개 페이지를 예쁘게 꾸미기

CSS프로젝트반응형실습완성

HTML + CSS = 진짜 웹사이트

HTML 프로젝트에서 만든 소개 페이지는 내용은 있지만 디자인이 없어 투박했습니다. 이번 편에서 CSS를 입혀 실제 웹사이트처럼 만들어 봅니다.

이 프로젝트를 마치면:

  • 실제로 보여줄 수 있는 나만의 소개 사이트가 생깁니다.
  • CSS 시리즈에서 배운 모든 개념을 한 프로젝트에서 써볼 수 있습니다.
  • JavaScript를 배울 준비가 됩니다.

완성 목표

아래 기능을 모두 갖춘 소개 페이지를 만듭니다.

항목적용 기술
CSS 변수로 색상 시스템:root, var()
반응형 네비게이션Flexbox, 미디어쿼리
히어로 섹션gradient, clamp()
카드 그리드Flexbox, flex-wrap
hover 애니메이션transition, transform
반응형 레이아웃@media
구글 폰트@import, font-family

style.css 전체 코드

/* ===================================
   1. 기본 설정 & CSS 변수
=================================== */
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap');

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

:root {
  --primary: #0070f3;
  --primary-hover: #0051cc;
  --secondary: #7928ca;
  --text: #111111;
  --text-muted: #666666;
  --bg: #ffffff;
  --bg-subtle: #f9fafb;
  --border: #e5e7eb;
  --radius: 12px;
  --shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  --shadow-hover: 0 12px 32px rgba(0, 0, 0, 0.14);
}

body {
  font-family: 'Noto Sans KR', -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  color: var(--text);
  background-color: var(--bg);
}

/* ===================================
   2. 레이아웃 컨테이너
=================================== */
.container {
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 16px;
}

@media (min-width: 768px) {
  .container {
    padding: 0 32px;
  }
}

/* ===================================
   3. 네비게이션
=================================== */
header {
  position: sticky;
  top: 0;
  z-index: 100;
  background-color: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}

nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 60px;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 16px;
}

.nav-logo {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  text-decoration: none;
}

.nav-menu {
  display: none;
  list-style: none;
  gap: 28px;
}

.nav-menu a {
  font-size: 15px;
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.2s;
}

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

@media (min-width: 640px) {
  .nav-menu {
    display: flex;
  }
}

/* ===================================
   4. 히어로 섹션
=================================== */
.hero {
  background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
  color: white;
  padding: 80px 16px;
  text-align: center;
}

.hero-profile {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  border: 4px solid rgba(255, 255, 255, 0.3);
  object-fit: cover;
  margin-bottom: 20px;
}

.hero h1 {
  font-size: clamp(1.75rem, 5vw, 3rem);
  font-weight: 700;
  margin-bottom: 12px;
  letter-spacing: -0.5px;
}

.hero p {
  font-size: clamp(1rem, 2vw, 1.2rem);
  opacity: 0.8;
  max-width: 500px;
  margin: 0 auto 24px;
}

.hero-badge {
  display: inline-block;
  background-color: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 6px 16px;
  border-radius: 9999px;
  font-size: 14px;
  margin: 4px;
}

/* ===================================
   5. 섹션 공통
=================================== */
section {
  padding: 60px 16px;
}

section:nth-child(even) {
  background-color: var(--bg-subtle);
}

.section-title {
  font-size: 1.75rem;
  font-weight: 700;
  margin-bottom: 32px;
  color: var(--text);
}

.section-title span {
  color: var(--primary);
}

/* ===================================
   6. 카드 그리드
=================================== */
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 280px;
  background-color: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  box-shadow: var(--shadow);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-hover);
}

.card-icon {
  font-size: 32px;
  margin-bottom: 12px;
}

.card h3 {
  font-size: 1.1rem;
  font-weight: 700;
  margin-bottom: 8px;
}

.card p {
  color: var(--text-muted);
  font-size: 0.95rem;
}

/* ===================================
   7. 목록 스타일
=================================== */
.styled-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.styled-list li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 16px;
  background-color: var(--bg);
  border-radius: 8px;
  border: 1px solid var(--border);
}

.styled-list li::before {
  content: '✓';
  color: var(--primary);
  font-weight: 700;
  flex-shrink: 0;
}

/* ===================================
   8. 버튼
=================================== */
.btn {
  display: inline-block;
  padding: 10px 24px;
  background-color: var(--primary);
  color: white;
  text-decoration: none;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 500;
  border: none;
  cursor: pointer;
  transition: background-color 0.2s, transform 0.2s;
}

.btn:hover {
  background-color: var(--primary-hover);
  transform: translateY(-2px);
}

/* ===================================
   9. 푸터
=================================== */
footer {
  background-color: #1a1a2e;
  color: rgba(255, 255, 255, 0.7);
  padding: 40px 16px;
  text-align: center;
}

footer a {
  color: rgba(255, 255, 255, 0.8);
  text-decoration: none;
  transition: color 0.2s;
}

footer a:hover {
  color: white;
}

.footer-links {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

small {
  color: rgba(255, 255, 255, 0.4);
}

HTML 파일 업데이트

index.html <head>에 추가:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="style.css" />

히어로 섹션 구조 예시:

<div class="hero">
  <div class="container">
    <img class="hero-profile"
      src="https://picsum.photos/120/120?random=1"
      alt="프로필 사진" />
    <h1>안녕하세요, 홍길동입니다</h1>
    <p>코딩을 배우는 중학교 2학년 · 웹 개발자를 꿈꿉니다</p>
    <span class="hero-badge">HTML</span>
    <span class="hero-badge">CSS</span>
    <span class="hero-badge">학습 중</span>
  </div>
</div>

완성 후 체크리스트

  • CSS 변수로 색상을 한 곳에서 관리하고 있음
  • box-sizing: border-box 전역 적용
  • 네비게이션이 모바일에서는 숨김, 데스크톱에서 표시
  • 히어로 섹션에 그라디언트 배경 적용
  • 카드에 hover 시 떠오르는 효과
  • 반응형: 모바일/태블릿/데스크톱 모두 확인
  • 구글 폰트 적용됨
  • 링크에 :hover 효과

다음 단계: JavaScript

CSS까지 배웠으니 이제 페이지에 동적인 기능을 추가할 차례입니다. JavaScript를 배우면:

  • 버튼 클릭 시 무언가 일어나게 하기
  • 입력값 검증 (폼 유효성 검사)
  • 데이터를 받아와서 화면에 표시
  • 간단한 게임 만들기

CSS 시리즈 완료를 축하드립니다! 🎉

JavaScript 시리즈에서 만나요.

궁금한 점이 있으신가요?

협업·의뢰는 아래로, 가벼운 소통은 인스타그램 @bluefox._.hi도 환영이에요.