Learning
레슨 12 / 13·5개 토픽

HTML 테이블과 미디어

HTML 테이블 기초

HTML 테이블은 행(row)과 열(column)로 구성된 데이터를 표현할 때 사용합니다.

안에 (헤더), (본문), (푸터)로 구조를 나누고, (행) 안에
(헤더 셀)와 (데이터 셀)를 배치합니다. 테이블은 반드시 표 형태의 데이터에만 사용하고, 레이아웃 목적으로는 사용하지 않습니다.

html
<!-- ── 기본 테이블 구조 ── -->
<table>
  <thead>
    <tr>
      <th>이름</th>
      <th>역할</th>
      <th>이메일</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>홍길동</td>
      <td>프론트엔드</td>
      <td>hong@example.com</td>
    </tr>
    <tr>
      <td>김영희</td>
      <td>백엔드</td>
      <td>kim@example.com</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3">총 2명</td>
    </tr>
  </tfoot>
</table>

colspan과 rowspan

colspan은 셀을 가로로 병합하고, rowspan은 세로로 병합합니다. 복잡한 표를 만들 때 유용하지만, 과도하게 사용하면 접근성이 떨어지므로 가능한 단순한 구조를 유지하세요.

html
<!-- ── colspan / rowspan 예시 ── -->
<table>
  <thead>
    <tr>
      <th rowspan="2">구분</th>
      <th colspan="2">2024년</th>
      <th colspan="2">2025년</th>
    </tr>
    <tr>
      <th>상반기</th>
      <th>하반기</th>
      <th>상반기</th>
      <th>하반기</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>매출</td>
      <td>120억</td>
      <td>135억</td>
      <td>150억</td>
      <td>170억</td>
    </tr>
    <tr>
      <td>영업이익</td>
      <td>18억</td>
      <td>22억</td>
      <td>25억</td>
      <td>30억</td>
    </tr>
  </tbody>
</table>

반응형 테이블 패턴

테이블은 모바일에서 가로 스크롤이 발생하기 쉽습니다. 가장 간단한 해결책은 래퍼에 overflow-x: auto를 적용하는 것이고, 더 정교한 방법으로는 미디어 쿼리로 셀을 블록으로 변환하는 패턴이 있습니다.

css
/* ── 방법 1: 가로 스크롤 래퍼 (가장 간단) ── */
.table-wrapper {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.table-wrapper table {
  min-width: 600px;
  width: 100%;
  border-collapse: collapse;
}

/* ── 기본 테이블 스타일 ── */
table {
  width: 100%;
  border-collapse: collapse;
}

th, td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid #e5e7eb;
}

thead th {
  background: #f9fafb;
  font-weight: 600;
}

tbody tr:hover {
  background: #f3f4f6;
}

/* ── 방법 2: 카드형 변환 (모바일) ── */
@media (max-width: 640px) {
  table, thead, tbody, tr, th, td {
    display: block;
  }

  thead {
    display: none;  /* 헤더 숨기기 */
  }

  tr {
    margin-bottom: 16px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 12px;
  }

  td::before {
    content: attr(data-label);
    font-weight: 600;
    display: block;
    margin-bottom: 4px;
    color: #6b7280;
  }
}

비디오와 오디오

HTML5의 태그를 사용하면 플러그인 없이 미디어를 재생할 수 있습니다. 태그로 여러 형식을 제공하면 브라우저가 지원하는 형식을 자동으로 선택합니다.

html
<!-- ── 비디오 ── -->
<video controls width="100%" poster="thumbnail.jpg" preload="metadata">
  <source src="video.mp4" type="video/mp4" />
  <source src="video.webm" type="video/webm" />
  <track
    src="captions-ko.vtt"
    kind="subtitles"
    srclang="ko"
    label="한국어"
    default
  />
  브라우저가 비디오를 지원하지 않습니다.
</video>

<!-- ── 오디오 ── -->
<audio controls preload="metadata">
  <source src="podcast.mp3" type="audio/mpeg" />
  <source src="podcast.ogg" type="audio/ogg" />
  브라우저가 오디오를 지원하지 않습니다.
</audio>

<!-- 주요 속성 -->
<!-- controls : 재생/정지/볼륨 UI 표시 -->
<!-- autoplay : 자동 재생 (muted와 함께 사용 필수) -->
<!-- loop     : 반복 재생 -->
<!-- muted    : 음소거 시작 -->
<!-- poster   : 비디오 썸네일 이미지 -->
<!-- preload  : none | metadata | auto -->

picture 태그와 반응형 이미지

태그는 화면 크기나 해상도에 따라 서로 다른 이미지를 제공합니다. 태그의 media 속성으로 조건을 지정하고, 가 폴백(fallback)으로 항상 포함되어야 합니다.

html
<!-- ── picture: 화면 크기별 최적 이미지 제공 ── -->
<picture>
  <!-- 넓은 화면: 가로형 이미지 -->
  <source
    media="(min-width: 1024px)"
    srcset="hero-wide.webp"
    type="image/webp"
  />
  <!-- 태블릿: 중간 크기 -->
  <source
    media="(min-width: 768px)"
    srcset="hero-medium.webp"
    type="image/webp"
  />
  <!-- 폴백: 모바일 또는 WebP 미지원 -->
  <img
    src="hero-small.jpg"
    alt="히어로 이미지"
    loading="lazy"
    width="800"
    height="450"
  />
</picture>

<!-- ── iframe: 외부 콘텐츠 임베드 ── -->
<iframe
  src="https://www.youtube.com/embed/VIDEO_ID"
  width="560"
  height="315"
  title="YouTube 동영상 플레이어"
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope"
  allowfullscreen
  loading="lazy"
></iframe>

<!-- 반응형 iframe 래퍼 -->
<div style="position: relative; padding-bottom: 56.25%; height: 0;">
  <iframe
    src="https://www.youtube.com/embed/VIDEO_ID"
    style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
    title="동영상"
    allowfullscreen
  ></iframe>
</div>
💡

미디어 성능 최적화를 위해 loading="lazy"를 이미지와 iframe에 적용하세요. 비디오는 preload="metadata"로 필요한 정보만 미리 불러오고, 와 WebP 형식을 활용하면 이미지 용량을 30~50% 줄일 수 있습니다. widthheight 속성을 명시하면 레이아웃 시프트(CLS)를 방지할 수 있습니다.