콘텐츠로 이동

프론트엔드 기초 — HTML과 CSS

지금까지와 앞으로

지금까지는 백엔드를 만들었습니다 — 데이터를 저장하고 API를 제공하는 서버.

하지만 사용자는 터미널이 아니라 브라우저로 서비스를 사용합니다.
브라우저에서 보이는 화면을 만드는 것이 프론트엔드(Frontend)입니다.

프론트엔드 (브라우저)       백엔드 (서버)
┌────────────────┐          ┌──────────────┐
│  HTML/CSS/JS   │   HTTP   │   FastAPI    │
│  (화면, 동작)  │ ◀──────▶ │   (API)      │
└────────────────┘          └──────────────┘

웹 프론트엔드는 세 가지 언어로 구성됩니다:

언어 역할 비유
HTML 구조와 내용 건물의 뼈대
CSS 스타일과 레이아웃 인테리어
JavaScript 동작과 상호작용 사람의 행동

HTML — 페이지의 뼈대

HTML(HyperText Markup Language)은 웹 페이지의 구조를 정의합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>My Todo App</title>
</head>
<body>
  <h1>할 일 목록</h1>
  <p>오늘 할 일들을 관리하세요.</p>
</body>
</html>

태그(Tag)

HTML은 태그로 내용을 감쌉니다.

<태그이름>내용</태그이름>

자주 쓰는 태그:

<!-- 제목 (h1이 가장 크고, h6이 가장 작음) -->
<h1>가장 큰 제목</h1>
<h2>두 번째 제목</h2>

<!-- 단락 -->
<p>일반 텍스트 단락입니다.</p>

<!-- 링크 -->
<a href="https://example.com">클릭하세요</a>

<!-- 이미지 (닫는 태그 없음) -->
<img src="photo.jpg" alt="사진 설명">

<!-- 목록 -->
<ul>               <!-- 순서 없는 목록 -->
  <li>항목 1</li>
  <li>항목 2</li>
</ul>

<ol>               <!-- 순서 있는 목록 -->
  <li>첫 번째</li>
  <li>두 번째</li>
</ol>

<!-- 입력 -->
<input type="text" placeholder="입력하세요">
<button>클릭</button>

폼 (Form)

사용자 입력을 받는 영역입니다.

<form id="todo-form">
  <input type="text" id="title-input" placeholder="할 일을 입력하세요">
  <button type="submit">추가</button>
</form>

div와 span — 묶음 태그

<!-- div: 블록 단위로 묶기 (줄 바꿈) -->
<div class="card">
  <h2>제목</h2>
  <p>내용</p>
</div>

<!-- span: 인라인으로 묶기 (줄 바꿈 없음) -->
<p>이것은 <span class="highlight">강조</span>된 텍스트입니다.</p>

id와 class — 요소 식별

<!-- id: 페이지에서 유일한 식별자 -->
<div id="main-container">...</div>

<!-- class: 여러 요소에 같은 스타일 적용 -->
<div class="card">...</div>
<div class="card">...</div>

CSS — 스타일 꾸미기

CSS(Cascading Style Sheets)는 HTML 요소의 외형을 결정합니다.

<head>
  <style>
    /* 태그 선택자 */
    h1 {
      color: navy;
      font-size: 2rem;
    }

    /* 클래스 선택자 */
    .card {
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 16px;
      margin: 8px 0;
    }

    /* id 선택자 */
    #main-container {
      max-width: 600px;
      margin: 0 auto;
    }
  </style>
</head>

자주 쓰는 CSS 속성

/* 색상과 배경 */
color: #333;              /* 글자 색 */
background-color: #fff;   /* 배경 색 */

/* 글자 */
font-size: 16px;
font-weight: bold;
text-align: center;

/* 크기와 간격 */
width: 100%;
max-width: 600px;
padding: 16px;            /* 안쪽 여백 */
margin: 8px 0;            /* 바깥 여백 */

/* 테두리 */
border: 1px solid #ddd;
border-radius: 8px;       /* 모서리 둥글게 */

/* 표시 방식 */
display: flex;            /* 플렉스 레이아웃 */
display: none;            /* 숨기기 */

Flexbox — 레이아웃 정렬

.container {
  display: flex;
  gap: 8px;                    /* 요소 간 간격 */
  align-items: center;         /* 세로 중앙 정렬 */
  justify-content: space-between; /* 가로 양 끝 정렬 */
}
<div class="container">
  <input type="text" placeholder="할 일">
  <button>추가</button>
</div>

Todo 앱 기본 화면 만들기

HTML + CSS만으로 기본 화면을 구성합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>Todo App</title>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    body {
      font-family: sans-serif;
      background: #f5f5f5;
      padding: 24px;
    }

    #app {
      max-width: 480px;
      margin: 0 auto;
    }

    h1 {
      font-size: 1.5rem;
      margin-bottom: 16px;
      color: #333;
    }

    .input-row {
      display: flex;
      gap: 8px;
      margin-bottom: 16px;
    }

    .input-row input {
      flex: 1;
      padding: 10px 12px;
      border: 1px solid #ddd;
      border-radius: 6px;
      font-size: 1rem;
    }

    .input-row button {
      padding: 10px 16px;
      background: #4f46e5;
      color: white;
      border: none;
      border-radius: 6px;
      font-size: 1rem;
      cursor: pointer;
    }

    .todo-item {
      display: flex;
      align-items: center;
      gap: 12px;
      background: white;
      padding: 12px 16px;
      border-radius: 8px;
      margin-bottom: 8px;
      box-shadow: 0 1px 3px rgba(0,0,0,0.08);
    }

    .todo-item.done span {
      text-decoration: line-through;
      color: #aaa;
    }

    .todo-item span {
      flex: 1;
    }

    .delete-btn {
      background: none;
      border: none;
      color: #e53e3e;
      cursor: pointer;
      font-size: 1rem;
    }
  </style>
</head>
<body>
  <div id="app">
    <h1>할 일 목록</h1>

    <div class="input-row">
      <input type="text" id="title-input" placeholder="할 일을 입력하세요">
      <button id="add-btn">추가</button>
    </div>

    <div id="todo-list">
      <!-- 할 일 항목이 여기에 추가됨 (JavaScript로) -->
      <div class="todo-item">
        <input type="checkbox">
        <span>운동하기</span>
        <button class="delete-btn">삭제</button>
      </div>
      <div class="todo-item done">
        <input type="checkbox" checked>
        <span>책 읽기</span>
        <button class="delete-btn">삭제</button>
      </div>
    </div>
  </div>
</body>
</html>

외부 CSS 파일로 분리

HTML 파일이 커지면 CSS를 별도 파일로 분리합니다.

project/
├── index.html
└── style.css
<!-- index.html -->
<head>
  <link rel="stylesheet" href="style.css">
</head>
/* style.css */
body { font-family: sans-serif; }
.card { border-radius: 8px; }

브라우저 개발자 도구

프론트엔드 개발에서 가장 중요한 도구입니다.

Chrome / Edge에서 F12 또는 우클릭 → "검사"

주요 탭:
- Elements: HTML 구조 확인, CSS 실시간 수정
- Console:  JavaScript 오류 확인, 코드 실행
- Network:  HTTP 요청/응답 확인

실습 미션

미션 1: HTML 구조 작성

index.html 파일을 만들고:
1. 제목 "할 일 목록"을 표시하세요.
2. 텍스트 입력창과 "추가" 버튼을 배치하세요.
3. 할 일 3개를 목록으로 하드코딩해 보세요.
브라우저에서 열어 확인하세요.

미션 2: CSS 스타일 적용

위 HTML에:
1. 전체 너비를 최대 480px로 제한하고 가운데 정렬하세요.
2. 입력창과 버튼을 가로로 나란히 배치하세요 (Flexbox).
3. 각 할 일 항목에 카드 스타일(흰 배경, 둥근 모서리, 그림자)을 적용하세요.

미션 3: 완료 스타일

완료된 할 일에 다음을 적용하세요:
- 체크박스가 체크된 상태
- 텍스트에 취소선
- 글자 색을 회색으로
class="done"을 추가/제거하는 방식으로 구현하세요.

미션 4 (심화): 반응형 디자인

@media 쿼리를 사용하여:
- 화면 너비가 480px 이하일 때 글자 크기를 줄이세요.
- 입력창과 버튼이 세로로 쌓이게 만드세요.

핵심 요약

개념 설명
HTML 페이지의 구조와 내용 — 태그로 의미 부여
CSS 색상, 크기, 레이아웃 등 외형
id 페이지에서 유일한 요소 식별자
class 여러 요소에 같은 스타일 적용
Flexbox display: flex — 가로/세로 정렬
개발자 도구 F12 — HTML/CSS 실시간 확인 및 수정

HTML은 무엇을, CSS는 어떻게 보일지를 담당합니다.
JavaScript는 다음 장에서 배웁니다.