32 CSS Accordions — Vertical & Horizontal
31 / 32

All 32 in 32 CSS Accordions — Vertical & Horizontal

  1. 01Pure CSS FAQ Accordion with <details> and <summary> (No JavaScript)
  2. 02Mobile Navigation Accordion Menu (CSS-Only Hamburger + Drill-Down)
  3. 03E-commerce Filter Sidebar Accordion with Exclusive Open (Product Filters)
  4. 04Nested Multi-Level Accordion (CSS Tree View for Docs & File Explorers)
  5. 05Smoothly Animated <details> Accordion — Transition height: auto in Pure CSS
  6. 06Exclusive Single-Open Accordion with the details name Attribute (Close Others Automatically)
  7. 07Underline Reveal Accordion — Editorial Minimal with Animated Rules
  8. 08Numbered Steps Accordion — Process Timeline for Onboarding Flows
  9. 09Plus / Minus Morph Accordion — CSS-Drawn Icon Animation
  10. 10Chevron Rotate Card Accordion — The Production Default, Perfected
  11. 11Brutalist Stamp Accordion — Bold Borders, Hard Shadows, Zero Subtlety
  12. 12Glassmorphism Frosted Accordion with backdrop-filter Blur
  13. 13Minimal Rail Accordion — Timeline Dot Spine for Changelogs & Roadmaps
  14. 14Card Lift Accordion — Elevation & Scale on Open (Material-Style Depth)
  15. 15Diagonal Slant Accordion — Skewed Parallelogram Headers
  16. 16Stepped Stair Accordion — Indented Cascade with Depth Levels
  17. 17Circular Dial Accordion — Conic-Gradient Progress Ring Toggles
  18. 18Marquee Header Accordion — Scrolling Ticker Titles on the Open Item
  19. 19Code Comment Accordion — Editor-Themed Collapsible Doc Blocks
  20. 20Paper Fold 3D Accordion — perspective + rotateX Unfolding Panels
  21. 21Equalizer Accordion — Animated Level Bars for Playlists & Audio
  22. 22Stacked Cards Deck Accordion — Overlapping Pull-Out Hand
  23. 23Holographic Slot Accordion — @property Rotating Border Sheen
  24. 24Aurora Drift Accordion — Dark Ambient Glow that Follows the Open Item
  25. 25Horizontal Strip Tabs Accordion — Vertical Text Columns with flex-grow
  26. 26Horizontal Image Reveal Accordion — Expanding Photo Gallery Panels
  27. 27Color Block Horizontal Accordion — Bold Flat Panels for Feature Sections
  28. 28Numbered Spine Horizontal Accordion — Editorial Magazine Index
  29. 29Curtain Slide Horizontal Accordion — clip-path Reveal Panels
  30. 30Vinyl Spine Horizontal Accordion — Record Shelf with Pull-Out Sleeves
  31. 31Cinema Reel Horizontal Accordion — Dark Letterboxed Showcase
  32. 32Aurora Strip Horizontal Accordion — Animated Gradient Glow Panels
Pure CSSMIT licensed

Cinema Reel Horizontal Accordion — Dark Letterboxed Showcase

A film-strip in the dark: near-black panels separated by sprocket-hole perforation rails, each expanding into a letterboxed 'frame' with a title card that tracks in like credits — wide letter-spacing easing to normal. Built for film festivals, video portfolios and anything that wants the lights turned off.

Live Demo
Plain CSSTailwind v4
Try it

Build interactive UI like this from scratch: 20 HTML, CSS & JavaScript projects

ZTM · JavaScript Web Projects · 30‑day money-back guarantee · Affiliate link

10% off at checkout with code
Check ZTM Course

The code

<section class="acc-21" aria-label="Cinema reel horizontal accordion demo">
  <div class="acc-21__strip" role="group" aria-label="Festival lineup">
    <div class="acc-21__panel" style="--tint:oklch(0.5 0.14 250 / .25)">
      <input type="radio" name="acc-21" id="acc-21-a" checked>
      <label class="acc-21__face" for="acc-21-a"><span class="acc-21__idx">I</span>
        <span class="acc-21__frame"><b class="acc-21__name">STILL WATER</b><i class="acc-21__slug">dir. E. Almqvist · 96 min · sweden</i><p class="acc-21__log">A ferry pilot on her final crossing discovers a passenger who never boarded.</p></span>
      </label>
    </div>
    <div class="acc-21__panel" style="--tint:oklch(0.5 0.16 25 / .25)">
      <input type="radio" name="acc-21" id="acc-21-b">
      <label class="acc-21__face" for="acc-21-b"><span class="acc-21__idx">II</span>
        <span class="acc-21__frame"><b class="acc-21__name">RED HARVEST</b><i class="acc-21__slug">dir. T. Okonkwo · 121 min · nigeria</i><p class="acc-21__log">Three brothers, one orchard, and the season that will decide who keeps it.</p></span>
      </label>
    </div>
    <div class="acc-21__panel" style="--tint:oklch(0.55 0.12 140 / .22)">
      <input type="radio" name="acc-21" id="acc-21-c">
      <label class="acc-21__face" for="acc-21-c"><span class="acc-21__idx">III</span>
        <span class="acc-21__frame"><b class="acc-21__name">GREENHOUSE</b><i class="acc-21__slug">dir. M. Duval · 84 min · canada</i><p class="acc-21__log">A botanist live-streams her last experiment; the plants start answering back.</p></span>
      </label>
    </div>
  </div>
</section>
.acc-21,
.acc-21 *,
.acc-21 *::before,
.acc-21 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.acc-21 {
  --holes: repeating-linear-gradient(0deg,transparent 0 10px,#000 10px 22px);
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0a0a0c;
  padding: 44px 24px;
}

.acc-21__strip {
  display: flex;
  width: min(820px,100%);
  height: 380px;
  background: #17171b;
  padding: 0 22px;
  position: relative;
  border-radius: 8px;
}

.acc-21__strip::before,
.acc-21__strip::after {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  width: 12px;
  background: var(--holes);
  border-radius: 3px;
}

.acc-21__strip::before {
  left: 5px;
}

.acc-21__strip::after {
  right: 5px;
}

.acc-21__panel {
  display: flex;
  flex-grow: 1;
  flex-basis: 0;
  min-width: 64px;
  position: relative;
  transition: flex-grow .55s cubic-bezier(.4,0,.2,1);
}

.acc-21__panel + .acc-21__panel::before {
  content: "";
  position: absolute;
  left: -6px;
  top: 12px;
  bottom: 12px;
  width: 12px;
  background: var(--holes);
  border-radius: 3px;
  z-index: 2;
}

.acc-21__panel:has(input:checked) {
  flex-grow: 6;
}

.acc-21__panel input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.acc-21__face {
  position: relative;
  flex: 1;
  display: block;
  cursor: pointer;
  overflow: hidden;
  background: #0f0f13 radial-gradient(70% 60% at 50% 40%,var(--tint),transparent 75%);
  margin: 12px 8px;
  border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06);
  transition: box-shadow .3s;
}

.acc-21__face:hover {
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.16);
}

.acc-21__idx {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  font-family: Georgia,serif;
  font-size: 26px;
  color: rgba(240,236,225,.4);
  transition: opacity .25s;
}

.acc-21__panel:has(input:checked) .acc-21__idx {
  opacity: 0;
}

.acc-21__frame {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  padding: 30px;
  opacity: 0;
  transition: opacity .4s .2s;
  box-shadow: inset 0 14px 0 #000,inset 0 -14px 0 #000;
}

.acc-21__panel:has(input:checked) .acc-21__frame {
  opacity: 1;
}

.acc-21__name {
  font-size: clamp(22px,3.4vw,34px);
  font-weight: 800;
  color: rgba(240,236,225,.92);
  letter-spacing: .5em;
  text-indent: .5em;
  transition: letter-spacing .8s cubic-bezier(.2,.7,.2,1) .2s,text-indent .8s cubic-bezier(.2,.7,.2,1) .2s;
  white-space: nowrap;
}

.acc-21__panel:has(input:checked) .acc-21__name {
  letter-spacing: .06em;
  text-indent: .06em;
}

.acc-21__slug {
  font-style: normal;
  font-family: ui-monospace,Menlo,monospace;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(240,236,225,.55);
}

.acc-21__log {
  font-size: 14px;
  line-height: 1.6;
  color: rgba(240,236,225,.75);
  max-width: 44ch;
}

.acc-21__panel:has(input:focus-visible) .acc-21__face {
  outline: 3px solid rgba(240,236,225,.9);
  outline-offset: 2px;
}

@media (max-width: 620px) {
  .acc-21__strip {
    flex-direction: column;
    height: auto;
    padding: 22px 0;
  }

  .acc-21__strip::before,
    .acc-21__strip::after {
    top: 5px;
    bottom: auto;
    left: 12px;
    right: 12px;
    width: auto;
    height: 12px;
    background: repeating-linear-gradient(90deg,transparent 0 10px,#000 10px 22px);
  }

  .acc-21__strip::after {
    top: auto;
    bottom: 5px;
  }

  .acc-21__panel {
    min-height: 64px;
  }

  .acc-21__panel:has(input:checked) {
    min-height: 280px;
  }

  .acc-21__panel + .acc-21__panel::before {
    display: none;
  }

  .acc-21__name {
    white-space: normal;
  }
}

@media (prefers-reduced-motion: reduce) {
  .acc-21__panel,
    .acc-21__name,
    .acc-21__frame,
    .acc-21__idx {
    transition: none;
  }

  .acc-21__name {
    letter-spacing: .06em;
    text-indent: .06em;
  }
}
/* No JavaScript — sprocket rails are repeating-linear-gradients, letterbox bars are inset box-shadows, and the title's cinematic track-in is a letter-spacing transition fired by :has(input:checked). */
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Accordions — Vertical & Horizontal from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Cinema Reel Horizontal Accordion — Dark Letterboxed Showcase
Source: https://codefronts.com/navigation/css-accordions/cinema-reel/

A film-strip in the dark: near-black panels separated by sprocket-hole perforation rails, each expanding into a letterboxed 'frame' with a title card that tracks in like credits — wide letter-spacing easing to normal. Built for film festivals, video portfolios and anything that wants the lights turned off.
## HTML
```html
<section class="acc-21" aria-label="Cinema reel horizontal accordion demo">
  <div class="acc-21__strip" role="group" aria-label="Festival lineup">
    <div class="acc-21__panel" style="--tint:oklch(0.5 0.14 250 / .25)">
      <input type="radio" name="acc-21" id="acc-21-a" checked>
      <label class="acc-21__face" for="acc-21-a"><span class="acc-21__idx">I</span>
        <span class="acc-21__frame"><b class="acc-21__name">STILL WATER</b><i class="acc-21__slug">dir. E. Almqvist · 96 min · sweden</i><p class="acc-21__log">A ferry pilot on her final crossing discovers a passenger who never boarded.</p></span>
      </label>
    </div>
    <div class="acc-21__panel" style="--tint:oklch(0.5 0.16 25 / .25)">
      <input type="radio" name="acc-21" id="acc-21-b">
      <label class="acc-21__face" for="acc-21-b"><span class="acc-21__idx">II</span>
        <span class="acc-21__frame"><b class="acc-21__name">RED HARVEST</b><i class="acc-21__slug">dir. T. Okonkwo · 121 min · nigeria</i><p class="acc-21__log">Three brothers, one orchard, and the season that will decide who keeps it.</p></span>
      </label>
    </div>
    <div class="acc-21__panel" style="--tint:oklch(0.55 0.12 140 / .22)">
      <input type="radio" name="acc-21" id="acc-21-c">
      <label class="acc-21__face" for="acc-21-c"><span class="acc-21__idx">III</span>
        <span class="acc-21__frame"><b class="acc-21__name">GREENHOUSE</b><i class="acc-21__slug">dir. M. Duval · 84 min · canada</i><p class="acc-21__log">A botanist live-streams her last experiment; the plants start answering back.</p></span>
      </label>
    </div>
  </div>
</section>
```
## CSS
```css
.acc-21,
.acc-21 *,
.acc-21 *::before,
.acc-21 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.acc-21 {
  --holes: repeating-linear-gradient(0deg,transparent 0 10px,#000 10px 22px);
  font-family: 'Segoe UI',system-ui,sans-serif;
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0a0a0c;
  padding: 44px 24px;
}

.acc-21__strip {
  display: flex;
  width: min(820px,100%);
  height: 380px;
  background: #17171b;
  padding: 0 22px;
  position: relative;
  border-radius: 8px;
}

.acc-21__strip::before,
.acc-21__strip::after {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  width: 12px;
  background: var(--holes);
  border-radius: 3px;
}

.acc-21__strip::before {
  left: 5px;
}

.acc-21__strip::after {
  right: 5px;
}

.acc-21__panel {
  display: flex;
  flex-grow: 1;
  flex-basis: 0;
  min-width: 64px;
  position: relative;
  transition: flex-grow .55s cubic-bezier(.4,0,.2,1);
}

.acc-21__panel + .acc-21__panel::before {
  content: "";
  position: absolute;
  left: -6px;
  top: 12px;
  bottom: 12px;
  width: 12px;
  background: var(--holes);
  border-radius: 3px;
  z-index: 2;
}

.acc-21__panel:has(input:checked) {
  flex-grow: 6;
}

.acc-21__panel input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.acc-21__face {
  position: relative;
  flex: 1;
  display: block;
  cursor: pointer;
  overflow: hidden;
  background: #0f0f13 radial-gradient(70% 60% at 50% 40%,var(--tint),transparent 75%);
  margin: 12px 8px;
  border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06);
  transition: box-shadow .3s;
}

.acc-21__face:hover {
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.16);
}

.acc-21__idx {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  font-family: Georgia,serif;
  font-size: 26px;
  color: rgba(240,236,225,.4);
  transition: opacity .25s;
}

.acc-21__panel:has(input:checked) .acc-21__idx {
  opacity: 0;
}

.acc-21__frame {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  padding: 30px;
  opacity: 0;
  transition: opacity .4s .2s;
  box-shadow: inset 0 14px 0 #000,inset 0 -14px 0 #000;
}

.acc-21__panel:has(input:checked) .acc-21__frame {
  opacity: 1;
}

.acc-21__name {
  font-size: clamp(22px,3.4vw,34px);
  font-weight: 800;
  color: rgba(240,236,225,.92);
  letter-spacing: .5em;
  text-indent: .5em;
  transition: letter-spacing .8s cubic-bezier(.2,.7,.2,1) .2s,text-indent .8s cubic-bezier(.2,.7,.2,1) .2s;
  white-space: nowrap;
}

.acc-21__panel:has(input:checked) .acc-21__name {
  letter-spacing: .06em;
  text-indent: .06em;
}

.acc-21__slug {
  font-style: normal;
  font-family: ui-monospace,Menlo,monospace;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(240,236,225,.55);
}

.acc-21__log {
  font-size: 14px;
  line-height: 1.6;
  color: rgba(240,236,225,.75);
  max-width: 44ch;
}

.acc-21__panel:has(input:focus-visible) .acc-21__face {
  outline: 3px solid rgba(240,236,225,.9);
  outline-offset: 2px;
}

@media (max-width: 620px) {
  .acc-21__strip {
    flex-direction: column;
    height: auto;
    padding: 22px 0;
  }

  .acc-21__strip::before,
    .acc-21__strip::after {
    top: 5px;
    bottom: auto;
    left: 12px;
    right: 12px;
    width: auto;
    height: 12px;
    background: repeating-linear-gradient(90deg,transparent 0 10px,#000 10px 22px);
  }

  .acc-21__strip::after {
    top: auto;
    bottom: 5px;
  }

  .acc-21__panel {
    min-height: 64px;
  }

  .acc-21__panel:has(input:checked) {
    min-height: 280px;
  }

  .acc-21__panel + .acc-21__panel::before {
    display: none;
  }

  .acc-21__name {
    white-space: normal;
  }
}

@media (prefers-reduced-motion: reduce) {
  .acc-21__panel,
    .acc-21__name,
    .acc-21__frame,
    .acc-21__idx {
    transition: none;
  }

  .acc-21__name {
    letter-spacing: .06em;
    text-indent: .06em;
  }
}
```

## JavaScript
```js
/* No JavaScript — sprocket rails are repeating-linear-gradients, letterbox bars are inset box-shadows, and the title's cinematic track-in is a letter-spacing transition fired by :has(input:checked). */
```

How this works

The strip metaphor is carried by the perforation rails: vertical columns of punched sprocket holes drawn with repeating-linear-gradient between every panel (and at both ends), so the whole row reads as physical film. Panels are near-black with a faint per-item color grade (a radial tint), expanding on the radio + flex-grow chassis.

The signature move is typographic: the active title enters with letter-spacing: .5em → .06em transitioned alongside opacity — the classic cinematic credits track-in, done with two properties. Letterbox bars (top/bottom pseudo-borders on the frame) fade in with the content, and a mono 'scene/take' slug line completes the grammar. Everything sits on pure blacks, so the demo also shows disciplined dark-theme contrast: text at 90%, metadata at 55%, never pure white on pure black.

Techniques used: letter-spacing track-in title animation · repeating-linear-gradient sprocket perforation rails · letterbox bars via inset box-shadow · per-panel radial color grade tints · dark-theme luminance discipline (no #fff-on-#000)

Make it yours

  • Track-in drama = the starting letter-spacing (.5em).
  • Color grades = each panel's --tint radial.
  • Perforation size/pitch in the rail gradient.
  • Swap the slug line for runtime/genre metadata.

Gotchas — read before shipping

  • letter-spacing animation causes text layout shifts by design — contain it: the title is absolutely positioned so nothing else moves.
  • Avoid pure #fff on #000 (halation for astigmatic users) — 90% ivory on 6% black here.
  • The perforation rails are decoration; keep them out of the click targets and aria tree (they're plain backgrounds).
  • letter-spacing transitions repaint the text layer each frame — fine for one title, don't run it on every panel simultaneously.

Browser support

ChromeSafariFirefoxEdge
111+15.4+121+111+

Floor set by :has(), oklch() as this demo is written. The core technique itself goes back further — Chrome all.

letter-spacing transitions and gradients are baseline everywhere.

Techniques used in this demo

Search CodeFronts

Loading…