typestar

app_shell.css in CSS

The whole page frame: a sticky header, a sidebar that folds away, and a content column that behaves.

/* The application frame. Grid areas first, then each region. */

.app {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 16rem minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  min-block-size: 100svh;
}

.app__header {
  grid-area: header;
  position: sticky;
  inset-block-start: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1.25rem;
  background: var(--surface, white);
  border-block-end: 1px solid var(--edge, #e5e7eb);
}

.app__header .spacer { flex: 1 1 auto; min-inline-size: 0; }

.app__sidebar {
  grid-area: sidebar;
  padding: 1.25rem;
  border-inline-end: 1px solid var(--edge, #e5e7eb);
  overflow-y: auto;
  position: sticky;
  inset-block-start: 3.5rem;
  block-size: calc(100svh - 3.5rem);
  scrollbar-width: thin;
}

.app__main {
  grid-area: main;
  padding: 2rem 1.25rem;
  display: grid;
  gap: 1.5rem;
  align-content: start;
}

.app__main > * { max-inline-size: 68ch; }

.app__footer {
  grid-area: footer;
  padding: 1.25rem;
  border-block-start: 1px solid var(--edge, #e5e7eb);
  color: var(--text-muted, #64748b);
  font-size: 0.875rem;
}

.content-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1rem;
}

@media (width < 60rem) {
  .app {
    grid-template-areas:
      "header"
      "main"
      "footer";
    grid-template-columns: minmax(0, 1fr);
  }

  .app__sidebar {
    position: fixed;
    inset: 3.5rem auto 0 0;
    inline-size: min(18rem, 80vw);
    translate: -100% 0;
    transition: translate 200ms ease;
    background: var(--surface, white);
  }

  .app__sidebar[data-state="open"] { translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .app__sidebar { transition: none; }
}

html { scroll-padding-block-start: 4.5rem; }

How it works

  1. Named grid areas make the layout readable at a glance.
  2. One media query moves from two columns to one.
  3. The sticky header and the scroll padding are set together, or anchors land under it.

Keywords and builtins used here

The run, in numbers

Lines
89
Characters to type
1703
Tokens
394
Three-star pace
95 tpm

At the three-star pace of 95 tokens a minute, this run takes about 249 seconds.

Type this snippet

Step 1 of 1 in Encore, step 13 of 13 in Styling components.

← Previous