HTML 테이블에서 position: sticky와 top: 0 속성을 활용하면 스크롤을 내려도 테이블 헤더(<th>)가 화면 상단에 고정되는 '스티키 헤더'를 간단하게 구현할 수 있습니다. 별도의 JavaScript 없이 순수 CSS만으로 처리되기 때문에 성능 부담이 적고 유지보수도 쉽습니다.
동작 원리
position: sticky는 요소가 지정된 임계점(여기서는 컨테이너 상단 top: 0)에 도달하기 전까지는 일반적인 흐름대로 배치되다가, 도달한 이후에는 그 자리에 마치 fixed처럼 붙어 있는 동작 방식입니다. 테이블의 <th> 요소에 이 속성을 적용하면, 스크롤 가능한 컨테이너 안에서 헤더 행이 항상 보이게 됩니다.
예제 1: 기본적인 고정 헤더 테이블
아래 예제는 스크롤 가능한 div 컨테이너 안에 테이블을 넣고, 헤더에 sticky 속성을 적용한 기본 형태입니다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
color: white;
display: flex;
padding: 2%;
background-color: rgba(190,155,150);
height: 135px;
overflow-y: scroll;
}
td,th,p {
text-align: center;
font-size: 1.25em;
}
table {
padding: 3%;
border-collapse: collapse;
border: 2px ridge green;
}
th {
top: 0;
position: sticky;
background: #e5d2f1;
color: black;
}
</style>
</head>
<body>
<div>
<table>
<thead>
<tr>
<th>A </th>
<th>B </th>
<th>C </th>
<th>D </th>
<th>E </th>
</tr>
</thead>
<tr>
<td>Hey</td>
<td>Hey</td>
<td>Hey</td>
<td>Hey</td>
<td>Hey</td>
</tr>
<tr>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
</tr>
<tr>
<td>Yo</td>
<td>Yo</td>
<td>Yo</td>
<td>Yo</td>
<td>Yo</td>
</tr>
<tr>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
</tr>
</table>
<p>
Duis tincidunt fermentum ipsum vel sagittis. Sed ultrices quis dui ut rutrum. Quisque et varius tellus, ut vestibulum purus. Etiam in erat fringilla, laoreet libero eu, facilisis ante.
</p>
</div>
</body>
</html>실행 결과
위 코드를 실행하면 컨테이너를 세로로 스크롤하는 동안에도 연한 보라색 배경의 헤더 행(A~E)이 항상 상단에 고정되어 나타납니다.

예제 2: 그림자 효과가 있는 고정 헤더
두 번째 예제는 컨테이너에 box-shadow의 inset(내부) 그림자를 적용해 스크롤 영역임을 시각적으로 강조한 버전입니다.
<!DOCTYPE html>
<html>
<head>
<style>
div {
padding: 2%;
height: 40px;
overflow-y: scroll;
box-shadow: inset 0 0 12px lightgreen;
}
tr th {
background: #25f2f1;
}
table {
text-align: center;
position: relative;
border-collapse: separated;
width: 100%;
}
th {
top: 0;
position: sticky;
background: white;
}
</style>
</head>
<body>
<div>
<table>
<thead>
<tr>
<th>A </th>
<th>B </th>
<th>C </th>
<th>D </th>
<th>E </th>
</tr>
</thead>
<tr>
<td>Hey</td>
<td>Hey</td>
<td>Hey</td>
<td>Hey</td>
<td>Hey</td>
</tr>
<tr>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
</tr>
<tr>
<td>Yo</td>
<td>Yo</td>
<td>Yo</td>
<td>Yo</td>
<td>Yo</td>
</tr>
<tr>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
<td>Demo</td>
</tr>
</table>
</div>
</body>
</html>실행 결과
컨테이너를 스크롤하면 흰색 배경의 헤더 행이 상단에 계속 고정되며, 연한 초록색 내부 그림자 덕분에 스크롤 영역의 경계가 자연스럽게 드러납니다.

구현 시 주의사항
- 배경색 필수:
th에 배경색을 지정하지 않으면 아래쪽 셀 내용이 비쳐 보일 수 있습니다. - border-collapse 주의:
border-collapse: collapse환경에서는 일부 브라우저에서 sticky 동작이 제대로 적용되지 않을 수 있으므로, 필요하면separated값을 사용하세요. - 부모 요소 overflow: 조상 요소 중
overflow: hidden등이 설정되어 있으면 sticky가 의도대로 작동하지 않을 수 있습니다.