Para congelar linhas de tabela HTML podemos usar a propriedade CSS “position: stcik” e assim manter essa linha visível enquanto você rola pelo restante da tabela.

A propriedade CSS position: sticky é usada para fixar um elemento em uma posição específica na página enquanto o usuário rola o conteúdo.
Usar essa propriedade em tabelas faz com algo muito importante acontecer: os elementos congelados da tabela permanecem visíveis mesmo quando o usuário rola a página e isso torna a experiência do usuário mais facilitada.
Exemplo de tabela com cabeçalho congelado
Nesse exemplo, o CSS é colocado diretamente dentro do HTML, a isso, chamamos de CSS inline.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tabela com Linha Congelada (Apenas position: sticky;)</title>
</head>
<body>
<table style="border-collapse: collapse; width: 100%;">
<tr style="position: sticky; top: 0; background-color: #f2f2f2; z-index: 1;">
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
<!-- Outras linhas da tabela aqui -->
</table>
</body>
</html>
Mesmo exemplo de tabela com linha congelada mas com CSS externo
HTML puro:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tabela com Linha Congelada (CSS Externo)</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<table>
<tr class="sticky-row">
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
<!-- Outras linhas da tabela aqui -->
</table>
</body>
</html>
Arquivo CSS
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.sticky-row {
position: sticky;
top: 0;
background-color: #f2f2f2;
z-index: 1;
}