Position: Sticky

Sticks relative to scroll container.

html

<div class="ps-wrap" role="img" aria-label="A scrollable list with a sticky header; scroll the list below and the header stays pinned once it reaches its top offset">
  <div class="ps-scroll" style="height:140px;">
    <div class="ps-header" style="top:0px;background:#E8A020;">Section header</div>
    <div class="ps-row">Row one</div>
    <div class="ps-row">Row two</div>
    <div class="ps-row">Row three</div>
    <div class="ps-row">Row four</div>
    <div class="ps-row">Row five</div>
    <div class="ps-row">Row six</div>
    <div class="ps-row">Row seven</div>
  </div>
  <p class="ps-caption">position: sticky; top: 0px &mdash; scroll the list to see the header lock in place</p>
</div>
<style>
.ps-wrap { font: 13px/1.4 system-ui, sans-serif; color: #241430; width: 300px; }
.ps-scroll { overflow: auto; border: 1.5px solid #24143055; border-radius: 8px; background: #FAF7F2; }
.ps-header { position: sticky; padding: 8px 12px; font-weight: 700; font-size: 12px; color: #241430; }
.ps-row { padding: 14px 12px; border-top: 1px solid #24143022; font-size: 12px; }
.ps-caption { margin: 10px 0 0; font-size: 12px; color: #241430cc; }
</style>

tailwind

<div class="font-sans text-[#241430] w-[300px]" role="img" aria-label="A scrollable list with a sticky header; scroll the list below and the header stays pinned once it reaches its top offset">
  <div class="overflow-auto border-[1.5px] border-[#24143055] rounded-lg bg-[#FAF7F2]" style="height:140px;">
    <div class="sticky px-3 py-2 font-bold text-xs" style="top:0px;background:#E8A020;">Section header</div>
    <div class="px-3 py-3.5 border-t border-[#24143022] text-xs">Row one</div>
    <div class="px-3 py-3.5 border-t border-[#24143022] text-xs">Row two</div>
    <div class="px-3 py-3.5 border-t border-[#24143022] text-xs">Row three</div>
    <div class="px-3 py-3.5 border-t border-[#24143022] text-xs">Row four</div>
    <div class="px-3 py-3.5 border-t border-[#24143022] text-xs">Row five</div>
    <div class="px-3 py-3.5 border-t border-[#24143022] text-xs">Row six</div>
    <div class="px-3 py-3.5 border-t border-[#24143022] text-xs">Row seven</div>
  </div>
  <p class="mt-2.5 text-xs text-[#241430]/80">position: sticky; top: 0px &mdash; scroll the list to see the header lock in place</p>
</div>

react

export function PositionSticky({
  topOffset = 0,
  headerColor = "#E8A020",
  containerHeight = 140,
  label = "Section header",
}) {
  const row = { padding: "14px 12px", borderTop: "1px solid #24143022", fontSize: 12 };
  return (
    <div style={{ font: "13px/1.4 system-ui, sans-serif", color: "#241430", width: 300 }}
      role="img" aria-label="A scrollable list with a sticky header; scroll the list below and the header stays pinned once it reaches its top offset">
      <div style={{ height: containerHeight, overflow: "auto", border: "1.5px solid #24143055", borderRadius: 8, background: "#FAF7F2" }}>
        <div style={{ position: "sticky", top: topOffset, background: headerColor, padding: "8px 12px", fontWeight: 700, fontSize: 12, color: "#241430" }}>
          {label}
        </div>
        <div style={row}>Row one</div><div style={row}>Row two</div><div style={row}>Row three</div>
        <div style={row}>Row four</div><div style={row}>Row five</div><div style={row}>Row six</div><div style={row}>Row seven</div>
      </div>
      <p style={{ marginTop: 10, fontSize: 12, color: "#241430cc" }}>
        position: sticky; top: {topOffset}px &mdash; scroll the list to see the header lock in place
      </p>
    </div>
  );
}