Skip to content

Right Sidebar Layout Overrides

Multiple assistants have tried to shrink the table-of-contents column and ended up with clipped links or misaligned content. Starlight’s layout relies on a shared set of CSS variables and a flex container defined in @astrojs/starlight/components/TwoColumnContent.astro. If you change only one lever (for example, --sl-sidebar-width) you create gaps because the framework reuses that variable for both sidebars and for centering the main pane.

This guide documents the working recipe we use in src/styles/global.css so future agents can adjust the right column confidently.

The following components matter when styling the right column:

  • TwoColumnContent.astro — sets the flex layout, positions .right-sidebar-container, and uses --sl-sidebar-width in width calculations for the right column and the main content.
  • PageSidebar.astro — wraps the table of contents, applies padding via --sl-sidebar-pad-x, and constrains the inner .sl-container.
  • ContentPanel.astro — consumes --sl-content-margin-inline to center or offset the main pane.

Because the same CSS variable participates in multiple calculations, always scope changes carefully and give each area its own value.

  1. Keep the global defaults at the top of src/styles/global.css.

    :root {
    --sl-sidebar-width: 20rem; /* left navigation width */
    --sl-content-width: 52rem; /* available content width */
    }

    These values keep the left sidebar wide enough for nested labels and tell Starlight how wide the main content should be when both sidebars exist.

  2. Scope a smaller width to the right column inside a large-screen media query.

    @media (min-width: 72rem) {
    .right-sidebar-container {
    --sl-sidebar-width: 12rem;
    --sl-sidebar-pad-x: 0.5rem;
    flex: 0 0 var(--sl-sidebar-width);
    width: var(--sl-sidebar-width) !important;
    }
    }

    Setting the custom property on .right-sidebar-container (and not on :root) keeps the narrower value local to the right column.

  3. Make the sidebar body honor the new width and behave like a sticky column.

    .right-sidebar-container .right-sidebar {
    position: sticky;
    top: var(--sl-nav-height);
    height: calc(100vh - var(--sl-nav-height));
    width: 100%;
    max-width: var(--sl-sidebar-width);
    }

    Starlight ships with position: fixed; width: 100%; switching to sticky lets the sidebar stay within the smaller flex column.

  4. Resize the inner container and allow headings to wrap.

    .right-sidebar-panel {
    --sl-sidebar-pad-x: 0.5rem;
    }
    .right-sidebar-panel .sl-container {
    width: calc(var(--sl-sidebar-width) - 2 * var(--sl-sidebar-pad-x)) !important;
    max-width: calc(var(--sl-sidebar-width) - 2 * var(--sl-sidebar-pad-x)) !important;
    }
    .right-sidebar-panel starlight-toc a span {
    white-space: normal;
    overflow-wrap: anywhere;
    }

    The built-in CSS enforces a 25% max-width after padding. Overriding both width and max-width ensures the table of contents uses the entire column and wraps long headings instead of truncating them.

  5. Re-center the main pane so the page does not feel left heavy.

    [data-has-sidebar][data-has-toc] .main-pane {
    --sl-content-margin-inline: 0 auto;
    flex: 1 1 auto;
    width: auto !important;
    max-width: var(--sl-content-width);
    margin-inline: 0 auto;
    }

    Without this override, Starlight offsets the main content toward the left to compensate for the wider right column. Resetting the margin and letting flexbox distribute the remaining space centers the main article.

  6. Adjust breakpoints as needed.

    The 72rem threshold matches Starlight’s default breakpoint for showing the right sidebar. If you want the narrow layout to kick in earlier or later, update the media query consistently across each block in this guide.

Paste the following block near the bottom of src/styles/global.css (after the Tailwind import) to achieve the current house style:

:root {
--sl-sidebar-width: 20rem;
--sl-content-width: 52rem;
}
@media (max-width: 1200px) {
:root {
--sl-sidebar-width: 18rem;
--sl-content-width: 46rem;
}
}
@media (max-width: 768px) {
:root {
--sl-sidebar-width: 0;
--sl-content-width: 100%;
}
}
@media (min-width: 72rem) {
.right-sidebar-container {
--sl-sidebar-width: 12rem;
--sl-sidebar-pad-x: 0.5rem;
flex: 0 0 var(--sl-sidebar-width);
width: var(--sl-sidebar-width) !important;
}
.right-sidebar-container .right-sidebar {
position: sticky;
top: var(--sl-nav-height);
height: calc(100vh - var(--sl-nav-height));
width: 100%;
max-width: var(--sl-sidebar-width);
}
.right-sidebar-panel {
--sl-sidebar-pad-x: 0.5rem;
}
.right-sidebar-panel .sl-container {
width: calc(var(--sl-sidebar-width) - 2 * var(--sl-sidebar-pad-x)) !important;
max-width: calc(var(--sl-sidebar-width) - 2 * var(--sl-sidebar-pad-x)) !important;
}
.right-sidebar-panel starlight-toc a span {
white-space: normal;
overflow-wrap: anywhere;
}
[data-has-sidebar][data-has-toc] .main-pane {
--sl-content-margin-inline: 0 auto;
flex: 1 1 auto;
width: auto !important;
max-width: var(--sl-content-width);
margin-inline: 0 auto;
}
}
  1. Restart npm run dev so Vite reloads the Tailwind plugin (it may cache the CSS module).
  2. Resize the viewport above and below 72rem to confirm the sidebar switches between the mobile accordion, the default desktop width, and the narrow layout.
  3. Visit pages with deep heading nesting to ensure the wrapped text remains readable.
  4. Run npm run build when you are done. Expect an EXDEV: cross-device link not permitted warning in this environment; it is unrelated to the CSS changes.

Following these steps keeps the right column narrow, the main article centered, and the table of contents fully legible.