Skip to content

Sticky Headers ​

Pin file names and tab bars while scrolling through long code blocks.

How It Works ​

Enable sticky headers with the stickyHeader prop. The header stays pinned at the top of the viewport (or offset by stickyTop pixels) while the code scrolls beneath it.

The overflow: clip Approach ​

Sticky positioning (position: sticky) breaks when any ancestor has overflow: hidden. bxp-code solves this by using overflow: clip on the container instead:

  • overflow: hidden — Creates a new scroll context, breaking position: sticky
  • overflow: clip — Clips overflowing content like hidden, but does not create a scroll context, so sticky works correctly

This is handled internally — you don't need to do anything. But if you wrap BxpCode or BxpCodeTabs in your own container, make sure to use overflow: clip instead of overflow: hidden on parent elements:

css
/* ❌ Breaks sticky headers */
.parent {
  overflow: hidden;
}

/* ✅ Works with sticky headers */
.parent {
  overflow: clip;
}

BxpCode — Sticky Header ​

tsx
import { BxpCode } from "bxp-code";

<BxpCode
  code={longCodeString}
  lang="typescript"
  fileName="server.ts"
  theme="dark"
  stickyHeader
  stickyTop={64}
  showLineNumbers
/>;
jsx
import { BxpCode } from "bxp-code";

<BxpCode
  code={longCodeString}
  lang="javascript"
  fileName="server.js"
  theme="dark"
  stickyHeader
  stickyTop={64}
  showLineNumbers
/>;

With Container Height ​

Set a maximum height to enable internal scrolling:

tsx
const style = { maxHeight: "400px" };

<BxpCode
  code={longCodeString}
  lang="typescript"
  fileName="api.ts"
  theme="dark"
  stickyHeader
  stickyTop={0}
  showLineNumbers
  style={style}
/>;

Full Example ​

tsx
const serverCode = `
import express from 'express';
const app = express();

app.get('/api/health', (req, res) => {
  res.json({ status: 'ok' });
});

app.get('/api/users', async (req, res) => {
  const users = await db.users.findMany();
  res.json(users);
});

const PORT = process.env.PORT || 3000;
app.listen(PORT);
`;

const style = { maxHeight: "300px" };

<BxpCode
  code={serverCode}
  lang="typescript"
  fileName="server.ts"
  theme="dark"
  stickyHeader
  stickyTop={0}
  showLineNumbers
  style={style}
/>;

BxpCodeTabs — Sticky Tab Bar ​

The tab bar stays pinned while you scroll through the active tab's content:

tsx
const style = { maxHeight: "400px", overflow: "auto" };

<BxpCodeTabs
  stickyHeader
  stickyTop={64}
  style={style}
  tabs={[
    { lang: "typescript", code: longTsCode },
    { lang: "python", code: longPyCode },
  ]}
/>;

stickyTop Offset ​

If your app has a fixed navbar, set stickyTop to the navbar's height so the sticky header doesn't overlap:

tsx
// Navbar is 64px tall
<BxpCode code={code} lang="typescript" stickyHeader stickyTop={64} />
ValueUse Case
0No fixed navbar
64Standard navbar
CustomYour navbar height in pixels

Best Practices ​

  1. Use with long code — Sticky headers are most useful when code exceeds the viewport height
  2. Set max height — Combine with a maxHeight style for contained scrollable areas
  3. Account for navbars — Use stickyTop to offset below fixed headers
  4. Avoid overflow: hidden on parents — Use overflow: clip instead to preserve sticky behavior
  5. Both components — Works identically on BxpCode and BxpCodeTabs

Props Reference ​

PropTypeDefaultComponent
stickyHeaderbooleanfalseBoth
stickyTopnumber0Both

→ BxpCode API Reference · BxpCodeTabs API Reference

Released under the MIT License.