리스트, 테이블, 폼 요소
앞서 우리는 웹 페이지의 기본 뼈대를 만드는 HTML의 역할과 텍스트, 링크, 이미지를 다루는 방법을 학습했습니다. 이제는 웹 페이지에서 정보를 더욱 구조적이고 체계적으로 표현하거나, 사용자로부터 데이터를 입력받는 데 사용되는 핵심적인 HTML 요소들에 대해 깊이 있게 다룰 차례입니다.
이 장에서는 리스트(목록) 요소를 사용하여 정보를 효과적으로 나열하고, 테이블(표) 요소를 통해 데이터를 행과 열의 형태로 정리하는 방법을 배울 것입니다. 또한, 웹 애플리케이션의 핵심 기능 중 하나인 폼(Form) 요소를 통해 사용자의 입력을 받고 이를 처리하는 기본적인 방법을 알아볼 것입니다. 이 요소들은 웹 페이지의 기능성과 정보 전달력을 높이는 데 매우 중요한 역할을 합니다.
리스트 요소: 정보를 체계적으로 나열하기
2장에서도 간략하게 다루었지만, 리스트 요소는 웹 페이지에서 관련 있는 항목들을 그룹화하여 보여줄 때 매우 유용합니다. 목록은 크게 세 가지 유형으로 나눌 수 있습니다.
순서 없는 목록 (Unordered List)
<ul>
태그는 항목의 순서가 중요하지 않을 때 사용하며, 각 항목은 <li>
(list item) 태그로 정의됩니다. 웹 브라우저는 일반적으로 각 <li>
앞에 글머리 기호(•)를 표시합니다. 내비게이션 메뉴, 카테고리 목록, 중요하지 않은 정보 나열 등에 사용됩니다.
<h3>제가 좋아하는 과일들</h3>
<ul>
<li>사과</li>
<li>바나나</li>
<li>딸기</li>
</ul>
순서 있는 목록 (Ordered List)
<ol>
태그는 항목의 순서가 중요할 때 사용하며, 각 항목은 역시 <li>
태그로 정의됩니다. 웹 브라우저는 기본적으로 각 <li>
앞에 숫자를 표시합니다. 레시피의 단계, 순위, 지시 사항 등 순서가 중요한 정보에 적합합니다.
<h3>커피 만드는 법</h3>
<ol>
<li>원두를 갈아 준비합니다.</li>
<li>뜨거운 물을 준비합니다.</li>
<li>천천히 물을 부어 커피를 추출합니다.</li>
<li>맛있게 드세요!</li>
</ol>
-
type
속성 (<ol>
에 사용): 순서의 종류를 변경할 수 있습니다.type="1"
(기본값): 숫자 (1, 2, 3...)type="a"
: 소문자 알파벳 (a, b, c...)type="A"
: 대문자 알파벳 (A, B, C...)type="i"
: 소문자 로마 숫자 (i, ii, iii...)type="I"
: 대문자 로마 숫자 (I, II, III...)
<h3>시험 점수 등급</h3> <ol type="A"> <li>A 학점</li> <li>B 학점</li> <li>C 학점</li> </ol>
-
start
속성 (<ol>
에 사용): 목록 시작 번호를 변경할 수 있습니다.<h3>재개되는 작업 목록</h3> <ol start="5"> <li>이전 작업 마무리</li> <li>새로운 기능 개발 시작</li> <li>테스트 및 배포</li> </ol>
정의 목록 (Description List)
정의 목록은 용어와 그 용어에 대한 설명을 나열할 때 사용합니다. 용어 사전, 질문과 답변(FAQ) 등에 유용합니다.
<dl>
(Description List): 정의 목록 전체를 감싸는 태그입니다.<dt>
(Definition Term): 정의할 용어를 나타냅니다.<dd>
(Definition Description): 용어에 대한 설명을 나타냅니다.
<h3>용어 사전</h3>
<dl>
<dt>HTML</dt>
<dd>웹 페이지의 구조를 정의하는 마크업 언어입니다.</dd>
<dt>CSS</dt>
<dd>웹 페이지의 스타일과 디자인을 담당하는 스타일 시트 언어입니다.</dd>
<dt>JavaScript</dt>
<dd>웹 페이지에 동적인 기능과 상호작용을 부여하는 프로그래밍 언어입니다.</dd>
</dl>
테이블 요소: 데이터를 행과 열로 정리하기
테이블(Table)은 데이터를 행(row)과 열(column)의 형태로 정리하여 보여줄 때 사용합니다. 통계 데이터, 제품 비교, 시간표 등 구조화된 데이터를 표시하는 데 매우 유용합니다. 테이블은 여러 태그들의 조합으로 이루어집니다.
<table>
: 테이블 전체를 감싸는 태그<caption>
: 테이블의 제목이나 설명을 제공 (선택 사항)<thead>
: 테이블의 헤더(제목) 행들을 그룹화<tbody>
: 테이블의 본문(데이터) 행들을 그룹화<tfoot>
: 테이블의 푸터(요약) 행들을 그룹화 (선택 사항)<tr>
(Table Row): 테이블의 한 행을 나타냅니다.<th>
(Table Header): 테이블 헤더 셀(열의 제목)을 나타냅니다. (기본적으로 굵고 가운데 정렬됨)<td>
(Table Data): 테이블 데이터 셀(실제 데이터)을 나타냅니다.
<h3>월별 웹사이트 방문자 수</h3>
<table>
<caption>2024년 월별 방문자 통계</caption>
<thead>
<tr>
<th>월</th>
<th>방문자 수</th>
<th>신규 방문자</th>
</tr>
</thead>
<tbody>
<tr>
<td>1월</td>
<td>10,500</td>
<td>3,200</td>
</tr>
<tr>
<td>2월</td>
<td>12,300</td>
<td>4,100</td>
</tr>
<tr>
<td>3월</td>
<td>15,800</td>
<td>5,500</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>총계</td>
<td>38,600</td>
<td>12,800</td>
</tr>
</tfoot>
</table>
-
셀 병합 (
rowspan
,colspan
속성):colspan
: 여러 개의 열을 하나의 셀로 병합할 때 사용합니다.rowspan
: 여러 개의 행을 하나의 셀로 병합할 때 사용합니다.
<h3>시간표 (예시)</h3> <table> <thead> <tr> <th>시간</th> <th>월요일</th> <th>화요일</th> </tr> </thead> <tbody> <tr> <td>9:00 - 10:00</td> <td>HTML 기초</td> <td rowspan="2">CSS 심화</td> </tr> <tr> <td>10:00 - 11:00</td> <td>JavaScript 기초</td> </tr> <tr> <td colspan="3">점심 시간</td> </tr> </tbody> </table>
💡 Tip: 테이블은 데이터 표시를 위한 용도로만 사용해야 합니다. 웹 페이지의 레이아웃을 잡기 위해 테이블을 사용하는 것은 권장되지 않습니다. (이는 '테이블 레이아웃'이라고 불리며, 오래된 방식이고 웹 표준과 웹 접근성에 좋지 않습니다. 현대 웹에서는 CSS Flexbox나 Grid를 사용합니다.)
폼 요소: 사용자로부터 입력받기 (<form>
)
웹 페이지에서 사용자로부터 정보를 입력받는 것은 매우 중요합니다. 로그인, 회원가입, 검색, 게시글 작성 등 거의 모든 웹 서비스는 사용자로부터의 입력을 필요로 합니다. 이러한 입력 양식을 폼(Form) 이라고 하며, <form>
태그를 사용하여 만듭니다.
<form>
태그 안에는 다양한 종류의 입력 필드(input field)와 컨트롤 요소들이 포함됩니다.
<form>
태그의 주요 속성action
: 폼 데이터가 제출될 서버의 URL을 지정합니다.method
: 폼 데이터를 서버로 전송하는 HTTP 메서드를 지정합니다.GET
: URL에 폼 데이터를 쿼리 문자열로 추가하여 전송합니다. (주로 검색이나 간단한 데이터 요청 시 사용)POST
: 폼 데이터를 HTTP 요청 본문에 담아 전송합니다. (주로 회원가입, 로그인, 파일 업로드 등 민감하거나 많은 데이터를 전송 시 사용)
<form action="/submit-form" method="POST">
</form>
입력 필드 (Input Fields): <input>
<input>
태그는 폼에서 가장 많이 사용되는 요소입니다. type
속성을 변경하여 다양한 종류의 입력 필드를 만들 수 있습니다. <input>
은 닫는 태그가 없는 빈 태그입니다.
-
type="text"
: 한 줄 텍스트 입력 필드<label for="username">사용자 이름:</label> <input type="text" id="username" name="username" placeholder="이름을 입력하세요">
id
: 각 입력 필드를 고유하게 식별하는 이름 (JavaScript나<label>
과 연결)name
: 서버로 전송될 때 이 입력 필드의 데이터를 식별하는 이름 (필수)placeholder
: 입력 필드에 아무것도 없을 때 표시되는 힌트 텍스트value
: 입력 필드의 초기값required
: 필수로 입력해야 하는 필드임을 명시
-
type="password"
: 비밀번호 입력 필드 (입력 시 문자 대신 • 또는 * 표시)<label for="password">비밀번호:</label> <input type="password" id="password" name="password" required>
-
type="email"
: 이메일 주소 입력 필드 (유효성 검사 지원)<label for="email">이메일:</label> <input type="email" id="email" name="email">
-
type="number"
: 숫자 입력 필드 (화살표 버튼으로 숫자 증감 가능)<label for="quantity">수량:</label> <input type="number" id="quantity" name="quantity" min="1" max="10" value="1">
-
type="radio"
: 여러 옵션 중 하나만 선택할 수 있는 라디오 버튼- 같은
name
속성을 가진 라디오 버튼들은 하나의 그룹으로 묶여 하나만 선택 가능합니다.
<p>성별:</p> <input type="radio" id="male" name="gender" value="male"> <label for="male">남성</label><br> <input type="radio" id="female" name="gender" value="female"> <label for="female">여성</label>
- 같은
-
type="checkbox"
: 여러 옵션을 동시에 선택할 수 있는 체크박스<p>좋아하는 취미 (다중 선택 가능):</p> <input type="checkbox" id="reading" name="hobby" value="reading"> <label for="reading">독서</label><br> <input type="checkbox" id="travel" name="hobby" value="travel"> <label for="travel">여행</label>
-
type="file"
: 파일 업로드 필드<label for="upload_file">파일 업로드:</label> <input type="file" id="upload_file" name="uploaded_file" accept=".pdf,.doc">
accept
: 업로드 가능한 파일 유형을 제한합니다.
-
type="submit"
: 폼을 제출하는 버튼<input type="submit" value="제출하기">
value
속성으로 버튼에 표시될 텍스트를 지정합니다.
-
<label>
: 입력 필드의 레이블을 정의합니다.for
속성을 사용하여 해당 레이블이 어떤input
요소와 연결되는지id
값으로 명시하는 것이 좋습니다. 이는 웹 접근성을 높여줍니다. (레이블을 클릭하면 해당 입력 필드가 활성화됩니다.)
여러 줄 텍스트 입력: <textarea>
여러 줄의 텍스트를 입력받을 때 사용합니다. rows
와 cols
속성으로 초기 크기를 지정할 수 있습니다.
<label for="message">메시지:</label><br>
<textarea id="message" name="message" rows="5" cols="30" placeholder="메시지를 입력하세요."></textarea>
드롭다운 목록: <select>
와 <option>
미리 정의된 여러 옵션 중에서 하나를 선택하도록 할 때 사용합니다.
<select>
: 드롭다운 목록 전체를 감싸는 태그<option>
: 드롭다운 목록의 각 항목을 나타냅니다.value
: 서버로 전송될 실제 값selected
: 기본적으로 선택되어 있을 옵션에 사용
<label for="country">국가 선택:</label>
<select id="country" name="country">
<option value="">-- 국가를 선택하세요 --</option>
<option value="kr">대한민국</option>
<option value="us" selected>미국</option>
<option value="jp">일본</option>
</select>
버튼: <button>
클릭할 수 있는 버튼을 만듭니다. <input type="button">
과 유사하지만, <button>
태그는 텍스트뿐만 아니라 이미지와 같은 HTML 콘텐츠를 포함할 수 있어 더 유연합니다.
<button type="submit">회원가입</button>
<button type="reset">초기화</button>
<button type="button">클릭 미!</button>
type
속성:submit
(기본값): 폼을 제출합니다.reset
: 폼의 모든 입력 필드를 초기화합니다.button
: 일반적인 버튼으로, 주로 자바스크립트와 함께 사용되어 특정 동작을 수행합니다.
폼 요소 그룹화
관련된 폼 요소들을 시각적, 의미적으로 그룹화할 때 사용합니다.
<fieldset>
: 폼 요소들을 그룹화하는 박스<legend>
:<fieldset>
박스의 제목
<fieldset>
<legend>개인 정보</legend>
<label for="first_name">이름:</label>
<input type="text" id="first_name" name="first_name"><br><br>
<label for="last_name">성:</label>
<input type="text" id="last_name" name="last_name">
</fieldset>
실습: 간단한 회원가입 폼 만들기
배운 폼 요소들을 조합하여 간단한 회원가입 폼을 만들어 봅시다. web-dev-practice
폴더에 signup.html
파일을 만들고 아래 코드를 작성해 보세요.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>회원가입 페이지</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f2f2f2;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.signup-container {
background-color: white;
padding: 30px 40px;
border-radius: 8px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
width: 100%;
max-width: 450px;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
color: #555;
font-weight: bold;
}
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
textarea,
select {
width: calc(100% - 20px); /* 패딩 고려 */
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 1em;
box-sizing: border-box; /* 패딩이 너비에 포함되도록 */
}
input[type="radio"],
input[type="checkbox"] {
margin-right: 8px;
}
button[type="submit"] {
width: 100%;
padding: 12px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
font-size: 1.1em;
cursor: pointer;
transition: background-color 0.3s ease;
}
button[type="submit"]:hover {
background-color: #0056b3;
}
.radio-group label, .checkbox-group label {
display: inline-block;
margin-right: 15px;
font-weight: normal;
}
</style>
</head>
<body>
<div class="signup-container">
<h1>회원가입</h1>
<form action="/register" method="POST">
<div class="form-group">
<label for="user_id">아이디:</label>
<input type="text" id="user_id" name="user_id" placeholder="5~12자 영문/숫자" required minlength="5" maxlength="12">
</div>
<div class="form-group">
<label for="user_email">이메일:</label>
<input type="email" id="user_email" name="user_email" placeholder="email@example.com" required>
</div>
<div class="form-group">
<label for="user_password">비밀번호:</label>
<input type="password" id="user_password" name="user_password" placeholder="비밀번호 입력" required minlength="8">
</div>
<div class="form-group">
<label for="password_confirm">비밀번호 확인:</label>
<input type="password" id="password_confirm" name="password_confirm" placeholder="비밀번호 다시 입력" required>
</div>
<div class="form-group radio-group">
<label>성별:</label>
<input type="radio" id="gender_male" name="gender" value="male" checked>
<label for="gender_male">남성</label>
<input type="radio" id="gender_female" name="gender" value="female">
<label for="gender_female">여성</label>
<input type="radio" id="gender_other" name="gender" value="other">
<label for="gender_other">기타</label>
</div>
<div class="form-group">
<label for="birth_year">출생 연도:</label>
<select id="birth_year" name="birth_year">
<option value="">-- 선택 --</option>
<script>
const currentYear = new Date().getFullYear();
for (let i = currentYear; i >= 1900; i--) {
document.write(`<option value="${i}">${i}</option>`);
}
</script>
</select>
</div>
<div class="form-group">
<label for="self_intro">자기소개 (선택 사항):</label>
<textarea id="self_intro" name="self_intro" rows="5" placeholder="간단히 자신을 소개해 주세요."></textarea>
</div>
<div class="form-group checkbox-group">
<input type="checkbox" id="terms_agree" name="terms_agree" required>
<label for="terms_agree">서비스 이용 약관에 동의합니다.</label>
</div>
<button type="submit">회원가입</button>
</form>
</div>
</body>
</html>
- 위 코드에서는 CSS를
<style>
태그 내부에 직접 작성하여 예시의 간결성을 높였습니다. 실제 프로젝트에서는 별도의.css
파일로 분리하는 것이 유지보수에 더 좋습니다. birth_year
<select>
옵션을 자바스크립트로 동적으로 생성하여<script>
태그의 위치를 확인할 수 있도록 했습니다.
이번 장에서는 웹 페이지의 정보 전달력과 사용자 상호작용을 크게 향상시키는 리스트, 테이블, 그리고 폼 요소들에 대해 자세히 알아보았습니다. 이 요소들을 적절히 활용하면 데이터를 체계적으로 보여주고, 사용자로부터 필요한 정보를 효과적으로 수집할 수 있습니다.