HTML 완벽 가이드: 웹 개발의 첫걸음
HTML 소개
HTML(HyperText Markup Language)은 웹 페이지를 만들기 위한 표준 마크업 언어입니다. HTML은 웹 페이지의 구조와 내용을 정의하며, 텍스트, 이미지, 비디오 등 다양한 콘텐츠를 표현할 수 있습니다. 모든 웹 개발자가 반드시 마스터해야 하는 기초 기술이며, CSS와 JavaScript와 함께 웹의 3대 핵심 기술 중 하나입니다.
개발 환경 설정
HTML을 시작하기 위해 필요한 것은 단순합니다:
- 텍스트 에디터: Visual Studio Code, Sublime Text, Atom 등
- 웹 브라우저: Chrome, Firefox, Safari, Edge 등
- 파일 확장자: .html 또는 .htm
1. HTML 기본 구조
HTML 문서의 기본 뼈대
모든 HTML 문서는 기본적인 구조를 가지고 있습니다. 이 구조는 웹 브라우저가 문서를 올바르게 해석하고 표시하는 데 필요합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<!-- 문서의 메타데이터 영역 -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>웹 페이지 제목</title>
</head>
<body>
<!-- 실제 화면에 표시되는 콘텐츠 영역 -->
<h1>안녕하세요, HTML!</h1>
<p>이것은 첫 번째 HTML 문서입니다.</p>
</body>
</html>
주요 구성 요소 설명
<!-- DOCTYPE 선언: HTML5 문서임을 명시 -->
<!DOCTYPE html>
<!-- html 요소: 문서의 루트 요소 -->
<html lang="ko">
<!-- head 요소: 문서 정보를 담는 컨테이너 -->
<head>
<!-- 문자 인코딩 설정 -->
<meta charset="UTF-8">
<!-- 반응형 웹 디자인을 위한 뷰포트 설정 -->
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<!-- 페이지 설명 -->
<meta name="description"
content="HTML 학습을 위한 예제 페이지입니다">
<!-- 페이지 제목 (브라우저 탭에 표시) -->
<title>HTML 기본 구조 예제</title>
<!-- 외부 CSS 파일 연결 -->
<link rel="stylesheet" href="styles.css">
</head>
<!-- body 요소: 실제 콘텐츠를 담는 컨테이너 -->
<body>
<h1>메인 제목</h1>
<p>본문 내용이 여기에 들어갑니다.</p>
</body>
</html>
2. 텍스트 관련 요소
HTML은 다양한 텍스트 표현을 위한 요소들을 제공합니다. 제목, 단락, 강조 등 텍스트의 의미와 구조를 명확하게 표현할 수 있습니다.
<!-- 제목 태그 (h1~h6) -->
<h1>가장 큰 제목 (h1)</h1>
<h2>두 번째 제목 (h2)</h2>
<h3>세 번째 제목 (h3)</h3>
<h4>네 번째 제목 (h4)</h4>
<h5>다섯 번째 제목 (h5)</h5>
<h6>가장 작은 제목 (h6)</h6>
<!-- 단락과 줄바꿈 -->
<p>이것은 단락입니다. 단락은 하나의 주제를 가진 글의 묶음입니다.</p>
<p>새로운 단락입니다.<br>
br 태그를 사용하면 같은 단락 내에서 줄바꿈을 할 수 있습니다.</p>
<!-- 텍스트 강조 -->
<p>
<strong>중요한 텍스트</strong>는 strong 태그를 사용합니다.<br>
<em>강조하고 싶은 텍스트</em>는 em 태그를 사용합니다.<br>
<b>굵은 글씨</b>는 b 태그를 사용합니다.<br>
<i>기울임 글씨</i>는 i 태그를 사용합니다.<br>
<u>밑줄 텍스트</u>는 u 태그를 사용합니다.<br>
<s>취소선 텍스트</s>는 s 태그를 사용합니다.
</p>
<!-- 인용문 -->
<blockquote>
긴 인용문은 blockquote 태그를 사용합니다.
이 태그는 들여쓰기가 적용되어 인용문임을 시각적으로 표현합니다.
</blockquote>
<p>짧은 인용문은 <q>q 태그를 사용합니다</q>.</p>
<!-- 코드와 사전 형식 텍스트 -->
<p>인라인 코드는 <code>console.log('Hello');</code> 이렇게 표현합니다.</p>
<pre>
사전 형식 텍스트는
공백과 줄바꿈이
그대로 유지됩니다.
</pre>
<!-- 기타 텍스트 요소 -->
<p>
<mark>형광펜 효과</mark>는 mark 태그로 만듭니다.<br>
<small>작은 글씨</small>는 small 태그를 사용합니다.<br>
위 첨자는 E=mc<sup>2</sup> 이렇게 표현합니다.<br>
아래 첨자는 H<sub>2</sub>O 이렇게 표현합니다.
</p>
가장 큰 제목 (h1)
중요한 텍스트는 strong 태그를 사용합니다.
강조하고 싶은 텍스트는 em 태그를 사용합니다.
형광펜 효과는 mark 태그로 만듭니다.
3. 링크와 이미지
웹의 핵심은 문서 간의 연결입니다. 링크와 이미지는 웹 페이지를 풍부하게 만드는 중요한 요소입니다.
<!-- 기본 링크 -->
<a href="https://www.example.com">외부 사이트로 이동</a>
<!-- 새 탭에서 열기 -->
<a href="https://www.google.com" target="_blank">새 탭에서 구글 열기</a>
<!-- 같은 페이지 내 이동 (앵커) -->
<a href="#section1">섹션 1로 이동</a>
<h2 id="section1">섹션 1</h2>
<!-- 이메일 링크 -->
<a href="mailto:someone@example.com">이메일 보내기</a>
<!-- 전화번호 링크 -->
<a href="tel:+821012345678">전화 걸기</a>
<!-- 파일 다운로드 -->
<a href="document.pdf" download>PDF 다운로드</a>
<!-- 기본 이미지 -->
<img src="image.jpg" alt="이미지 설명">
<!-- 크기가 지정된 이미지 -->
<img src="photo.jpg"
alt="풍경 사진"
width="500"
height="300">
<!-- 반응형 이미지 -->
<img src="responsive.jpg"
alt="반응형 이미지"
style="max-width: 100%; height: auto;">
<!-- 이미지 맵 (클릭 가능한 영역) -->
<img src="map.jpg" alt="지도" usemap="#workmap">
<map name="workmap">
<area shape="rect"
coords="34,44,270,350"
alt="컴퓨터"
href="computer.html">
<area shape="circle"
coords="337,300,44"
alt="커피"
href="coffee.html">
</map>
<!-- 이미지를 링크로 사용 -->
<a href="https://www.example.com">
<img src="banner.jpg" alt="클릭하여 이동">
</a>
<!-- picture 요소로 반응형 이미지 제공 -->
<picture>
<source media="(min-width: 768px)" srcset="large.jpg">
<source media="(min-width: 480px)" srcset="medium.jpg">
<img src="small.jpg" alt="반응형 이미지">
</picture>
4. 목록 만들기
HTML은 순서가 있는 목록, 순서가 없는 목록, 그리고 정의 목록을 만들 수 있는 요소들을 제공합니다.
<!-- 순서 없는 목록 (Unordered List) -->
<h3>장보기 목록</h3>
<ul>
<li>우유</li>
<li>빵</li>
<li>계란</li>
<li>과일
<ul>
<li>사과</li>
<li>바나나</li>
<li>오렌지</li>
</ul>
</li>
</ul>
<!-- 순서 있는 목록 (Ordered List) -->
<h3>레시피 순서</h3>
<ol>
<li>물을 끓인다</li>
<li>면을 넣는다</li>
<li>3분간 끓인다</li>
<li>스프를 넣는다</li>
<li>1분 더 끓인다</li>
</ol>
<!-- 다양한 타입의 순서 있는 목록 -->
<ol type="A">
<li>대문자 알파벳</li>
<li>순서로 표시</li>
</ol>
<ol type="i">
<li>로마 숫자</li>
<li>소문자로 표시</li>
</ol>
<!-- 정의 목록 (Description List) -->
<h3>웹 개발 용어</h3>
<dl>
<dt>HTML</dt>
<dd>HyperText Markup Language의 약자로, 웹 페이지의 구조를 정의합니다.</dd>
<dt>CSS</dt>
<dd>Cascading Style Sheets의 약자로, 웹 페이지의 스타일을 정의합니다.</dd>
<dt>JavaScript</dt>
<dd>웹 페이지에 동적인 기능을 추가하는 프로그래밍 언어입니다.</dd>
</dl>
5. 테이블 구성
테이블은 데이터를 행과 열로 구성하여 체계적으로 표현할 때 사용합니다.
<!-- 기본 테이블 구조 -->
<table>
<caption>2024년 1분기 매출 현황</caption>
<thead>
<tr>
<th>월</th>
<th>매출액</th>
<th>전월 대비</th>
</tr>
</thead>
<tbody>
<tr>
<td>1월</td>
<td>1,000만원</td>
<td>-</td>
</tr>
<tr>
<td>2월</td>
<td>1,200만원</td>
<td>+20%</td>
</tr>
<tr>
<td>3월</td>
<td>1,500만원</td>
<td>+25%</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>합계</th>
<th colspan="2">3,700만원</th>
</tr>
</tfoot>
</table>
<!-- 복잡한 테이블 (병합된 셀) -->
<table border="1">
<caption>시간표</caption>
<thead>
<tr>
<th>시간</th>
<th>월요일</th>
<th>화요일</th>
<th>수요일</th>
</tr>
</thead>
<tbody>
<tr>
<td>09:00</td>
<td rowspan="2">HTML/CSS</td>
<td>JavaScript</td>
<td>React</td>
</tr>
<tr>
<td>10:00</td>
<!-- 위 셀과 병합됨 -->
<td colspan="2">프로젝트 실습</td>
</tr>
</tbody>
</table>
<!-- 접근성을 고려한 테이블 -->
<table>
<caption>제품 비교표</caption>
<thead>
<tr>
<th scope="col">제품명</th>
<th scope="col">가격</th>
<th scope="col">재고</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">노트북</th>
<td>150만원</td>
<td>10개</td>
</tr>
<tr>
<th scope="row">마우스</th>
<td>3만원</td>
<td>50개</td>
</tr>
</tbody>
</table>
6. 폼과 입력 요소
폼은 사용자로부터 데이터를 입력받아 서버로 전송하는 중요한 인터페이스입니다.
<!-- 회원가입 폼 예제 -->
<form action="/submit" method="post">
<fieldset>
<legend>개인 정보</legend>
<!-- 텍스트 입력 -->
<label for="username">사용자명:</label>
<input type="text"
id="username"
name="username"
required
placeholder="사용자명을 입력하세요">
<br><br>
<!-- 이메일 입력 -->
<label for="email">이메일:</label>
<input type="email"
id="email"
name="email"
required>
<br><br>
<!-- 비밀번호 입력 -->
<label for="password">비밀번호:</label>
<input type="password"
id="password"
name="password"
minlength="8"
required>
<br><br>
<!-- 생년월일 -->
<label for="birthdate">생년월일:</label>
<input type="date"
id="birthdate"
name="birthdate">
<br><br>
<!-- 전화번호 -->
<label for="phone">전화번호:</label>
<input type="tel"
id="phone"
name="phone"
pattern="[0-9]{3}-[0-9]{4}-[0-9]{4}"
placeholder="010-1234-5678">
</fieldset>
<fieldset>
<legend>추가 정보</legend>
<!-- 라디오 버튼 -->
<p>성별:</p>
<input type="radio" id="male" name="gender" value="male">
<label for="male">남성</label>
<input type="radio" id="female" name="gender" value="female">
<label for="female">여성</label>
<input type="radio" id="other" name="gender" value="other">
<label for="other">기타</label>
<br><br>
<!-- 체크박스 -->
<p>관심 분야:</p>
<input type="checkbox" id="web" name="interests" value="web">
<label for="web">웹 개발</label>
<input type="checkbox" id="mobile" name="interests" value="mobile">
<label for="mobile">모바일 개발</label>
<input type="checkbox" id="ai" name="interests" value="ai">
<label for="ai">인공지능</label>
<br><br>
<!-- 드롭다운 메뉴 -->
<label for="country">국가:</label>
<select id="country" name="country">
<option value="">선택하세요</option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="jp">일본</option>
<option value="cn">중국</option>
</select>
<br><br>
<!-- 텍스트 영역 -->
<label for="message">자기소개:</label><br>
<textarea id="message"
name="message"
rows="5"
cols="50"
placeholder="자기소개를 입력해주세요"></textarea>
<br><br>
<!-- 파일 업로드 -->
<label for="file">이력서 업로드:</label>
<input type="file"
id="file"
name="file"
accept=".pdf,.doc,.docx">
<br><br>
<!-- 숫자 입력 -->
<label for="age">나이:</label>
<input type="number"
id="age"
name="age"
min="1"
max="120"
step="1">
<br><br>
<!-- 범위 선택 -->
<label for="skill">HTML 숙련도:</label>
<input type="range"
id="skill"
name="skill"
min="0"
max="100"
value="50">
</fieldset>
<!-- 버튼들 -->
<br>
<button type="submit">제출</button>
<button type="reset">초기화</button>
<button type="button" onclick="alert('클릭!')">일반 버튼</button>
</form>
7. 시맨틱 HTML
시맨틱 HTML은 의미론적 마크업을 통해 문서의 구조를 명확하게 표현합니다. 이는 검색 엔진 최적화(SEO)와 웹 접근성에 매우 중요합니다.
<!-- 시맨틱 HTML5 구조 -->
<header>
<nav>
<ul>
<li><a href="#home">홈</a></li>
<li><a href="#about">소개</a></li>
<li><a href="#services">서비스</a></li>
<li><a href="#contact">연락처</a></li>
</ul>
</nav>
<h1>웹사이트 제목</h1>
</header>
<main>
<section id="intro">
<h2>소개</h2>
<p>웹사이트에 오신 것을 환영합니다.</p>
</section>
<article>
<header>
<h2>블로그 포스트 제목</h2>
<time datetime="2024-03-15">2024년 3월 15일</time>
</header>
<p>블로그 포스트 내용이 여기에 들어갑니다...</p>
<figure>
<img src="image.jpg" alt="설명 이미지">
<figcaption>이미지 설명</figcaption>
</figure>
<footer>
<p>작성자: 홍길동</p>
</footer>
</article>
<aside>
<h3>관련 링크</h3>
<ul>
<li><a href="#">관련 글 1</a></li>
<li><a href="#">관련 글 2</a></li>
</ul>
</aside>
</main>
<footer>
<address>
연락처: <a href="mailto:info@example.com">info@example.com</a>
</address>
<p>© 2024 회사명. All rights reserved.</p>
</footer>
<!-- 추가 시맨틱 요소들 -->
<details>
<summary>더 보기</summary>
<p>숨겨진 내용이 여기에 표시됩니다.</p>
</details>
<dialog open>
<p>대화 상자 내용</p>
<button>닫기</button>
</dialog>
<mark>중요한 텍스트</mark>
<time datetime="2024-03-15T10:30">2024년 3월 15일 오전 10시 30분</time>
8. 멀티미디어 요소
HTML5는 오디오와 비디오를 플러그인 없이 직접 재생할 수 있는 요소들을 제공합니다.
<!-- 비디오 요소 -->
<video width="640"
height="360"
controls
autoplay
muted
loop
poster="thumbnail.jpg">
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
<source src="video.ogg" type="video/ogg">
브라우저가 video 태그를 지원하지 않습니다.
</video>
<!-- 오디오 요소 -->
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
<source src="audio.ogg" type="audio/ogg">
<source src="audio.wav" type="audio/wav">
브라우저가 audio 태그를 지원하지 않습니다.
</audio>
<!-- YouTube 비디오 임베드 -->
<iframe width="560"
height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
<!-- 구글 지도 임베드 -->
<iframe src="https://www.google.com/maps/embed?pb=..."
width="600"
height="450"
style="border:0;"
allowfullscreen=""
loading="lazy">
</iframe>
<!-- Canvas 요소 (그래픽 그리기용) -->
<canvas id="myCanvas" width="400" height="200">
브라우저가 canvas를 지원하지 않습니다.
</canvas>
<!-- SVG 그래픽 -->
<svg width="100" height="100">
<circle cx="50"
cy="50"
r="40"
stroke="green"
stroke-width="4"
fill="yellow"/>
</svg>
9. 메타 태그와 SEO
메타 태그는 검색 엔진 최적화(SEO)와 소셜 미디어 공유에 중요한 역할을 합니다.
<head>
<!-- 기본 메타 태그 -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- SEO 메타 태그 -->
<title>페이지 제목 - 60자 이내 권장</title>
<meta name="description"
content="페이지 설명 - 155자 이내로 작성하여 검색 결과에 표시">
<meta name="keywords"
content="HTML, CSS, JavaScript, 웹개발">
<meta name="author" content="작성자명">
<meta name="robots" content="index, follow">
<!-- Open Graph 메타 태그 (Facebook, LinkedIn) -->
<meta property="og:title" content="페이지 제목">
<meta property="og:description" content="페이지 설명">
<meta property="og:image" content="https://example.com/image.jpg">
<meta property="og:url" content="https://example.com/page">
<meta property="og:type" content="website">
<meta property="og:locale" content="ko_KR">
<!-- Twitter Card 메타 태그 -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="페이지 제목">
<meta name="twitter:description" content="페이지 설명">
<meta name="twitter:image" content="https://example.com/image.jpg">
<!-- 파비콘 -->
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<!-- 캐노니컬 URL -->
<link rel="canonical" href="https://example.com/page">
<!-- 언어 대체 페이지 -->
<link rel="alternate" hreflang="en" href="https://example.com/en/page">
<link rel="alternate" hreflang="ko" href="https://example.com/ko/page">
</head>
10. 웹 접근성
웹 접근성은 모든 사용자가 웹 콘텐츠에 접근할 수 있도록 보장하는 중요한 개념입니다.
<!-- ARIA 속성 사용 -->
<nav role="navigation" aria-label="주 메뉴">
<ul>
<li><a href="#">홈</a></li>
<li><a href="#" aria-current="page">현재 페이지</a></li>
</ul>
</nav>
<!-- 스킵 네비게이션 -->
<a href="#main-content" class="skip-link">본문으로 건너뛰기</a>
<!-- 랜드마크 역할 -->
<header role="banner">
<h1>사이트 제목</h1>
</header>
<main role="main" id="main-content">
<!-- 주요 콘텐츠 -->
</main>
<aside role="complementary" aria-label="사이드바">
<!-- 보조 콘텐츠 -->
</aside>
<!-- 접근 가능한 폼 -->
<form>
<label for="email">이메일 주소 (필수)</label>
<input type="email"
id="email"
name="email"
required
aria-required="true"
aria-describedby="email-help">
<span id="email-help">유효한 이메일 주소를 입력하세요</span>
</form>
<!-- 접근 가능한 버튼 -->
<button type="button"
aria-label="메뉴 열기"
aria-expanded="false"
aria-controls="menu">
<span aria-hidden="true">☰</span>
</button>
<!-- 접근 가능한 이미지 -->
<img src="chart.png"
alt="2024년 1분기 매출 그래프: 1월 100만원, 2월 120만원, 3월 150만원">
<!-- 장식용 이미지 -->
<img src="decoration.png" alt="" role="presentation">
<!-- 라이브 리전 -->
<div role="status" aria-live="polite" aria-atomic="true">
업데이트된 내용이 여기에 표시됩니다
</div>
<!-- 탭 인터페이스 -->
<div role="tablist">
<button role="tab"
aria-selected="true"
aria-controls="panel1">탭 1</button>
<button role="tab"
aria-selected="false"
aria-controls="panel2">탭 2</button>
</div>
<div role="tabpanel" id="panel1">탭 1 내용</div>
<div role="tabpanel" id="panel2" hidden>탭 2 내용</div>
11. HTML5 고급 기능
HTML5는 웹 애플리케이션 개발을 위한 다양한 고급 기능과 API를 제공합니다.
<!-- 로컬 스토리지 사용 예제 -->
<script>
// 데이터 저장
localStorage.setItem('username', '홍길동');
localStorage.setItem('theme', 'dark');
// 데이터 읽기
const username = localStorage.getItem('username');
const theme = localStorage.getItem('theme');
// 데이터 삭제
localStorage.removeItem('username');
// 모든 데이터 삭제
localStorage.clear();
</script>
<!-- Geolocation API -->
<button onclick="getLocation()">내 위치 찾기</button>
<p id="location"></p>
<script>
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, showError);
} else {
document.getElementById("location").innerHTML =
"이 브라우저는 Geolocation을 지원하지 않습니다.";
}
}
function showPosition(position) {
document.getElementById("location").innerHTML =
"위도: " + position.coords.latitude +
"
경도: " + position.coords.longitude;
}
function showError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
alert("위치 정보 접근이 거부되었습니다.");
break;
case error.POSITION_UNAVAILABLE:
alert("위치 정보를 사용할 수 없습니다.");
break;
case error.TIMEOUT:
alert("위치 정보 요청이 시간 초과되었습니다.");
break;
case error.UNKNOWN_ERROR:
alert("알 수 없는 오류가 발생했습니다.");
break;
}
}
</script>
<!-- 드래그 앤 드롭 -->
<div id="drag1"
draggable="true"
ondragstart="drag(event)">
드래그할 수 있는 요소
</div>
<div id="dropzone"
ondrop="drop(event)"
ondragover="allowDrop(event)">
여기에 드롭하세요
</div>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
<!-- Web Workers 예제 -->
<script>
if (typeof(Worker) !== "undefined") {
// Worker 생성
const worker = new Worker("worker.js");
// Worker에 메시지 보내기
worker.postMessage({cmd: 'start', msg: 'Hello Worker'});
// Worker로부터 메시지 받기
worker.onmessage = function(e) {
console.log('Worker said: ', e.data);
};
}
</script>
<!-- 콘텐츠 편집 가능 -->
<div contenteditable="true">
이 텍스트를 직접 편집할 수 있습니다!
</div>
<!-- 데이터 속성 -->
<div id="product"
data-product-id="12345"
data-price="29900"
data-category="electronics">
상품 정보
</div>
<script>
const product = document.getElementById('product');
console.log(product.dataset.productId); // "12345"
console.log(product.dataset.price); // "29900"
console.log(product.dataset.category); // "electronics"
</script>
<!-- Progress 요소 -->
<label for="file">다운로드 진행률:</label>
<progress id="file" value="32" max="100">32%</progress>
<!-- Meter 요소 -->
<label for="disk">디스크 사용량:</label>
<meter id="disk"
value="6"
min="0"
max="10"
low="2"
high="8"
optimum="5">
6 out of 10
</meter>
12. 실전 예제: 완성된 웹페이지
지금까지 배운 내용을 종합하여 실제 웹페이지를 만들어보겠습니다. 포트폴리오 웹사이트 예제입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>홍길동 - 웹 개발자 포트폴리오</title>
<!-- SEO 메타 태그 -->
<meta name="description" content="프론트엔드 개발자 홍길동의 포트폴리오 웹사이트">
<meta name="keywords" content="웹개발, 프론트엔드, HTML, CSS, JavaScript, React">
<!-- Open Graph -->
<meta property="og:title" content="홍길동 포트폴리오">
<meta property="og:description" content="웹 개발자 포트폴리오">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Noto Sans KR', sans-serif;
line-height: 1.6;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1rem 0;
position: fixed;
width: 100%;
top: 0;
z-index: 1000;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
nav ul {
list-style: none;
display: flex;
justify-content: center;
align-items: center;
}
nav li {
margin: 0 1.5rem;
}
nav a {
color: white;
text-decoration: none;
transition: opacity 0.3s;
}
nav a:hover {
opacity: 0.8;
}
main {
margin-top: 60px;
}
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 100px 0;
text-align: center;
}
.hero h1 {
font-size: 3rem;
margin-bottom: 1rem;
}
.section {
padding: 80px 0;
}
.section:nth-child(even) {
background-color: #f8f9fa;
}
h2 {
text-align: center;
margin-bottom: 3rem;
font-size: 2.5rem;
color: #333;
}
.skills-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.skill-card {
background: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
transition: transform 0.3s;
}
.skill-card:hover {
transform: translateY(-5px);
}
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.portfolio-item {
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
transition: transform 0.3s;
}
.portfolio-item:hover {
transform: scale(1.05);
}
.portfolio-item img {
width: 100%;
height: 200px;
object-fit: cover;
}
.portfolio-content {
padding: 1.5rem;
}
.contact-form {
max-width: 600px;
margin: 0 auto;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 0.8rem;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 1rem;
}
.form-group textarea {
resize: vertical;
min-height: 150px;
}
.btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 12px 30px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
transition: opacity 0.3s;
}
.btn:hover {
opacity: 0.9;
}
footer {
background: #333;
color: white;
text-align: center;
padding: 2rem 0;
}
.social-links {
margin-top: 1rem;
}
.social-links a {
color: white;
font-size: 1.5rem;
margin: 0 1rem;
transition: opacity 0.3s;
}
.social-links a:hover {
opacity: 0.7;
}
@media (max-width: 768px) {
.hero h1 {
font-size: 2rem;
}
nav ul {
flex-direction: column;
}
nav li {
margin: 0.5rem 0;
}
}
</style>
</head>
<body>
<!-- 스킵 네비게이션 -->
<a href="#main-content" class="skip-link" style="position: absolute; left: -9999px;">본문으로 건너뛰기</a>
<!-- 헤더 영역 -->
<header role="banner">
<nav role="navigation" aria-label="주 메뉴">
<ul>
<li><a href="#home">홈</a></li>
<li><a href="#about">소개</a></li>
<li><a href="#skills">기술</a></li>
<li><a href="#portfolio">포트폴리오</a></li>
<li><a href="#contact">연락처</a></li>
</ul>
</nav>
</header>
<!-- 메인 콘텐츠 -->
<main id="main-content" role="main">
<!-- 히어로 섹션 -->
<section id="home" class="hero">
<div class="container">
<h1>안녕하세요, 홍길동입니다</h1>
<p>열정적인 웹 개발자</p>
<a href="#portfolio" class="btn">작업물 보기</a>
</div>
</section>
<!-- 소개 섹션 -->
<section id="about" class="section">
<div class="container">
<h2>소개</h2>
<article>
<p>
5년 경력의 프론트엔드 개발자입니다. 사용자 경험을 최우선으로 생각하며,
깔끔하고 효율적인 코드를 작성하는 것을 목표로 합니다.
</p>
<p>
최신 웹 기술 트렌드를 따라가며, 지속적으로 학습하고 성장하는 개발자입니다.
팀워크를 중요시하며, 함께 일하는 동료들과 지식을 공유하는 것을 즐깁니다.
</p>
</article>
</div>
</section>
<!-- 기술 스택 섹션 -->
<section id="skills" class="section">
<div class="container">
<h2>기술 스택</h2>
<div class="skills-grid">
<div class="skill-card">
<h3>프론트엔드</h3>
<ul>
<li>HTML5 / CSS3</li>
<li>JavaScript (ES6+)</li>
<li>React.js</li>
<li>Vue.js</li>
</ul>
</div>
<div class="skill-card">
<h3>백엔드</h3>
<ul>
<li>Node.js</li>
<li>Express.js</li>
<li>MongoDB</li>
<li>MySQL</li>
</ul>
</div>
<div class="skill-card">
<h3>도구</h3>
<ul>
<li>Git / GitHub</li>
<li>Webpack</li>
<li>Docker</li>
<li>VS Code</li>
</ul>
</div>
</div>
</div>
</section>
<!-- 포트폴리오 섹션 -->
<section id="portfolio" class="section">
<div class="container">
<h2>포트폴리오</h2>
<div class="portfolio-grid">
<article class="portfolio-item">
<img src="project1.jpg" alt="전자상거래 웹사이트 스크린샷">
<div class="portfolio-content">
<h3>전자상거래 웹사이트</h3>
<p>React와 Node.js를 사용한 풀스택 쇼핑몰</p>
<a href="#" class="btn">자세히 보기</a>
</div>
</article>
<article class="portfolio-item">
<img src="project2.jpg" alt="태스크 관리 앱 스크린샷">
<div class="portfolio-content">
<h3>태스크 관리 앱</h3>
<p>Vue.js와 Firebase를 활용한 실시간 협업 도구</p>
<a href="#" class="btn">자세히 보기</a>
</div>
</article>
<article class="portfolio-item">
<img src="project3.jpg" alt="날씨 앱 스크린샷">
<div class="portfolio-content">
<h3>날씨 앱</h3>
<p>OpenWeather API를 활용한 반응형 날씨 애플리케이션</p>
<a href="#" class="btn">자세히 보기</a>
</div>
</article>
</div>
</div>
</section>
<!-- 연락처 섹션 -->
<section id="contact" class="section">
<div class="container">
<h2>연락처</h2>
<form class="contact-form" action="/submit" method="post">
<div class="form-group">
<label for="name">이름</label>
<input type="text"
id="name"
name="name"
required
aria-required="true">
</div>
<div class="form-group">
<label for="email">이메일</label>
<input type="email"
id="email"
name="email"
required
aria-required="true">
</div>
<div class="form-group">
<label for="message">메시지</label>
<textarea id="message"
name="message"
required
aria-required="true"></textarea>
</div>
<button type="submit" class="btn">메시지 보내기</button>
</form>
</div>
</section>
</main>
<!-- 푸터 영역 -->
<footer role="contentinfo">
<div class="container">
<p>© 2024 홍길동. All rights reserved.</p>
<div class="social-links">
<a href="https://github.com"
aria-label="GitHub"
target="_blank">GitHub</a>
<a href="https://linkedin.com"
aria-label="LinkedIn"
target="_blank">LinkedIn</a>
<a href="mailto:hong@example.com"
aria-label="Email">Email</a>
</div>
<address>
연락처: <a href="tel:+821012345678">010-1234-5678</a>
</address>
</div>
</footer>
<script>
// 부드러운 스크롤 효과
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// 폼 제출 처리
document.querySelector('.contact-form').addEventListener('submit', function(e) {
e.preventDefault();
alert('메시지가 전송되었습니다!');
this.reset();
});
// 스크롤 시 헤더 스타일 변경
window.addEventListener('scroll', function() {
const header = document.querySelector('header');
if (window.scrollY > 100) {
header.style.background = 'rgba(102, 126, 234, 0.95)';
} else {
header.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
}
});
</script>
</body>
</html>
마무리
이 튜토리얼에서는 HTML의 기초부터 고급 기능까지 포괄적으로 다루었습니다. HTML은 웹 개발의 기초이며, 이를 탄탄히 다지는 것이 성공적인 웹 개발자가 되는 첫걸음입니다. 실제 프로젝트에서는 HTML과 함께 CSS와 JavaScript를 활용하여 더욱 동적이고 아름다운 웹사이트를 만들 수 있습니다.
- W3C 표준 문서를 참고하여 최신 HTML 스펙을 확인하세요
- MDN Web Docs에서 각 요소의 상세한 설명과 예제를 학습하세요
- 웹 접근성 가이드라인(WCAG)을 숙지하여 모든 사용자를 위한 웹사이트를 만드세요
- 실제 웹사이트를 분석하고 구조를 파악하는 연습을 하세요
- CSS와 JavaScript를 함께 학습하여 완전한 웹 페이지를 구현하세요