Back to CSS Code Blocks Expandable / Collapsible Code Wrapper Pure CSS
Share
HTML
<section class="ccb-exp" aria-label="Expandable collapsible code wrapper demo">
  <div class="ccb-exp__wrap">
    <div class="ccb-exp__block">
      <div class="ccb-exp__head">utils/animate.js <span class="ccb-exp__lines">142 lines</span></div>
      <input type="checkbox" id="ccb-exp-toggle" class="ccb-exp__toggle" aria-label="Expand or collapse code">
      <div class="ccb-exp__codewrap">
        <pre class="ccb-exp__pre"><code><span class="ccb-exp__c">// easing + tween helpers</span>
<span class="ccb-exp__k">export const</span> <span class="ccb-exp__f">easeOutCubic</span> = t =&gt; <span class="ccb-exp__n">1</span> - Math.<span class="ccb-exp__f">pow</span>(<span class="ccb-exp__n">1</span> - t, <span class="ccb-exp__n">3</span>);
<span class="ccb-exp__k">export const</span> <span class="ccb-exp__f">easeInOut</span> = t =&gt; t &lt; .5
  ? <span class="ccb-exp__n">4</span> * t * t * t
  : <span class="ccb-exp__n">1</span> - Math.<span class="ccb-exp__f">pow</span>(-<span class="ccb-exp__n">2</span> * t + <span class="ccb-exp__n">2</span>, <span class="ccb-exp__n">3</span>) / <span class="ccb-exp__n">2</span>;

<span class="ccb-exp__k">export function</span> <span class="ccb-exp__f">tween</span>({ from, to, duration, onUpdate }) {
  <span class="ccb-exp__k">const</span> start = performance.<span class="ccb-exp__f">now</span>();
  <span class="ccb-exp__k">function</span> <span class="ccb-exp__f">frame</span>(now) {
    <span class="ccb-exp__k">const</span> p = Math.<span class="ccb-exp__f">min</span>((now - start) / duration, <span class="ccb-exp__n">1</span>);
    <span class="ccb-exp__f">onUpdate</span>(from + (to - from) * <span class="ccb-exp__f">easeOutCubic</span>(p));
    <span class="ccb-exp__k">if</span> (p &lt; <span class="ccb-exp__n">1</span>) <span class="ccb-exp__f">requestAnimationFrame</span>(frame);
  }
  <span class="ccb-exp__f">requestAnimationFrame</span>(frame);
}

<span class="ccb-exp__k">export function</span> <span class="ccb-exp__f">stagger</span>(items, delay = <span class="ccb-exp__n">60</span>) {
  items.<span class="ccb-exp__f">forEach</span>((el, i) =&gt; {
    el.style.<span class="ccb-exp__p">animationDelay</span> = <span class="ccb-exp__s">`${i * delay}ms`</span>;
  });
}</code></pre>
        <div class="ccb-exp__fade" aria-hidden="true"></div>
      </div>
      <label for="ccb-exp-toggle" class="ccb-exp__btn"><span class="ccb-exp__more">Show more</span><span class="ccb-exp__less">Show less</span></label>
    </div>
  </div>
</section>
CSS
/* ─── 12 Expandable / Collapsible Code Wrapper ──────── */
@import url('https://fonts.googleapis.com/css2?family=Martian+Mono:wght@400;500;600&family=Space+Grotesk:wght@400;600;700&display=swap');

.ccb-exp {
  --ccb-exp-bg: #0c0e13;
  --ccb-exp-panel: #13161d;
  --ccb-exp-ink: #dfe4ec;
  --ccb-exp-muted: #79828f;
  --ccb-exp-accent: #34d399;
  --ccb-exp-line: rgba(255,255,255,.06);

  width: 100%;
  min-height: 360px;
  background:
    radial-gradient(640px 360px at 0% 0%, rgba(52,211,153,.09), transparent 55%),
    var(--ccb-exp-bg);
  color: var(--ccb-exp-ink);
  font-family: 'Space Grotesk', sans-serif;
  display: flex; align-items: center; justify-content: center;
  padding: 36px 22px;
  box-sizing: border-box;
}
.ccb-exp *, .ccb-exp *::before, .ccb-exp *::after { box-sizing: border-box; }

.ccb-exp__wrap { width: 100%; max-width: 600px; }
.ccb-exp__block {
  background: var(--ccb-exp-panel);
  border: 1px solid var(--ccb-exp-line);
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 24px 60px -30px rgba(0,0,0,.85);
}
.ccb-exp__head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--ccb-exp-line);
  font-family: 'Martian Mono', monospace;
  font-size: 11.5px; color: var(--ccb-exp-muted); letter-spacing: .04em;
}
.ccb-exp__lines { margin-left: auto; color: var(--ccb-exp-accent); }

.ccb-exp__toggle { display: none; }
.ccb-exp__codewrap { position: relative; }
.ccb-exp__pre {
  margin: 0; padding: 20px 20px;
  font-family: 'Martian Mono', monospace;
  font-size: 12px; line-height: 1.95;
  color: #cbd3df; overflow: hidden;
  max-height: 170px;
  transition: max-height .45s cubic-bezier(.4,0,.2,1);
}
.ccb-exp__toggle:checked ~ .ccb-exp__codewrap .ccb-exp__pre { max-height: 1200px; }

.ccb-exp__fade {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 80px;
  pointer-events: none;
  background: linear-gradient(transparent, var(--ccb-exp-panel));
  transition: opacity .3s;
}
.ccb-exp__toggle:checked ~ .ccb-exp__codewrap .ccb-exp__fade { opacity: 0; }

.ccb-exp__btn {
  display: block; width: 100%; text-align: center; cursor: pointer;
  padding: 13px;
  font-family: 'Martian Mono', monospace;
  font-size: 11.5px; letter-spacing: .08em;
  color: var(--ccb-exp-accent);
  background: rgba(52,211,153,.06);
  border-top: 1px solid var(--ccb-exp-line);
  user-select: none;
  transition: background .2s;
}
.ccb-exp__btn:hover { background: rgba(52,211,153,.12); }
.ccb-exp__btn .ccb-exp__more { display: inline; }
.ccb-exp__btn .ccb-exp__less { display: none; }
.ccb-exp__toggle:checked ~ .ccb-exp__btn .ccb-exp__more { display: none; }
.ccb-exp__toggle:checked ~ .ccb-exp__btn .ccb-exp__less { display: inline; }
.ccb-exp__btn::after {
  content: ' \25BE';
  display: inline-block;
  transition: transform .3s;
}
.ccb-exp__toggle:checked ~ .ccb-exp__btn::after { transform: rotate(180deg); }
.ccb-exp__toggle:focus-visible ~ .ccb-exp__btn { outline: 2px solid var(--ccb-exp-accent); outline-offset: -3px; }

.ccb-exp__k { color: #c792ea; }
.ccb-exp__f { color: #82aaff; }
.ccb-exp__s { color: #c3e88d; }
.ccb-exp__c { color: #586173; font-style: italic; }
.ccb-exp__p { color: #7dd3fc; }
.ccb-exp__n { color: #ffb86c; }
.ccb-exp__pre::-webkit-scrollbar       { height: 8px; }
.ccb-exp__pre::-webkit-scrollbar-thumb { background: #262b34; border-radius: 8px; }

@media (prefers-reduced-motion: reduce) {
  .ccb-exp__pre, .ccb-exp__fade, .ccb-exp__btn::after, .ccb-exp__btn { transition: none; }
}