Numbered Spine Horizontal Accordion — Editorial Magazine Index
A magazine table-of-contents turned interactive: cream paper, hairline column rules, and giant ghosted numerals 1–4 stacked in each collapsed spine. The open column lays its numeral behind a serif headline and dek like an art-directed spread. Quiet, typographic, and unlike any card-based accordion.
Published Updated
The code
<section class="acc-18" aria-label="Numbered spine editorial accordion demo">
<div class="acc-18__row" role="group" aria-label="Issue contents">
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-a" checked>
<label class="acc-18__face" for="acc-18-a"><span class="acc-18__num">1</span><span class="acc-18__spine">The Interview</span>
<span class="acc-18__spread"><b>The last typesetter of Fleet Street</b><p>Sixty years of hot metal, and what the craft knew that the software forgot.</p><i>By M. Okafor · 18 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-b">
<label class="acc-18__face" for="acc-18-b"><span class="acc-18__num">2</span><span class="acc-18__spine">Field Report</span>
<span class="acc-18__spread"><b>Notes from the seed vault</b><p>Inside the arctic archive where every harvest on earth keeps a backup copy.</p><i>By T. Lindqvist · 12 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-c">
<label class="acc-18__face" for="acc-18-c"><span class="acc-18__num">3</span><span class="acc-18__spine">Essay</span>
<span class="acc-18__spread"><b>In defence of the long way</b><p>On slowness as a design material, and why the fastest path is rarely the best one.</p><i>By A. Fontaine · 9 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-d">
<label class="acc-18__face" for="acc-18-d"><span class="acc-18__num">4</span><span class="acc-18__spine">Archive</span>
<span class="acc-18__spread"><b>The 1961 letters</b><p>A rediscovered correspondence between two rival foundries, annotated.</p><i>Edited by the staff · 15 min</i></span>
</label>
</div>
</div>
</section><section class="acc-18" aria-label="Numbered spine editorial accordion demo">
<div class="acc-18__row" role="group" aria-label="Issue contents">
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-a" checked>
<label class="acc-18__face" for="acc-18-a"><span class="acc-18__num">1</span><span class="acc-18__spine">The Interview</span>
<span class="acc-18__spread"><b>The last typesetter of Fleet Street</b><p>Sixty years of hot metal, and what the craft knew that the software forgot.</p><i>By M. Okafor · 18 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-b">
<label class="acc-18__face" for="acc-18-b"><span class="acc-18__num">2</span><span class="acc-18__spine">Field Report</span>
<span class="acc-18__spread"><b>Notes from the seed vault</b><p>Inside the arctic archive where every harvest on earth keeps a backup copy.</p><i>By T. Lindqvist · 12 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-c">
<label class="acc-18__face" for="acc-18-c"><span class="acc-18__num">3</span><span class="acc-18__spine">Essay</span>
<span class="acc-18__spread"><b>In defence of the long way</b><p>On slowness as a design material, and why the fastest path is rarely the best one.</p><i>By A. Fontaine · 9 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-d">
<label class="acc-18__face" for="acc-18-d"><span class="acc-18__num">4</span><span class="acc-18__spine">Archive</span>
<span class="acc-18__spread"><b>The 1961 letters</b><p>A rediscovered correspondence between two rival foundries, annotated.</p><i>Edited by the staff · 15 min</i></span>
</label>
</div>
</div>
</section>.acc-18,
.acc-18 *,
.acc-18 *::before,
.acc-18 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.acc-18 {
--ink: #211d16;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f5f1e8;
padding: 44px 24px;
}
.acc-18__row {
display: flex;
width: min(860px,100%);
height: 420px;
border-block: 2px solid var(--ink);
}
.acc-18__panel {
display: flex;
flex-grow: 1;
flex-basis: 0;
min-width: 76px;
transition: flex-grow .55s cubic-bezier(.4,0,.2,1);
}
.acc-18__panel + .acc-18__panel {
border-left: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
flex-grow: 5;
}
.acc-18__panel input {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.acc-18__face {
position: relative;
flex: 1;
display: block;
cursor: pointer;
overflow: hidden;
transition: background .3s;
}
.acc-18__face:hover {
background: #efe9dc;
}
.acc-18__num {
position: absolute;
left: 10px;
top: 0;
font-family: Georgia,serif;
font-size: 140px;
line-height: 1;
font-weight: 700;
color: color-mix(in oklab,var(--ink) 9%,transparent);
transition: font-size .55s cubic-bezier(.4,0,.2,1),left .55s;
z-index: 0;
}
.acc-18__panel:has(input:checked) .acc-18__num {
font-size: 230px;
left: 18px;
}
.acc-18__spine {
position: absolute;
bottom: 18px;
left: 50%;
translate: -50% 0;
writing-mode: vertical-rl;
rotate: 180deg;
font-size: 12px;
font-weight: 700;
letter-spacing: .18em;
text-transform: uppercase;
color: #8a8069;
transition: opacity .25s;
}
.acc-18__panel:has(input:checked) .acc-18__spine {
opacity: 0;
}
.acc-18__spread {
position: absolute;
inset: 0;
z-index: 1;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: 10px;
padding: 28px;
opacity: 0;
translate: 0 10px;
transition: opacity .35s .2s,translate .35s .2s;
}
.acc-18__panel:has(input:checked) .acc-18__spread {
opacity: 1;
translate: 0 0;
}
.acc-18__spread b {
font-family: Georgia,serif;
font-size: clamp(22px,3vw,30px);
font-weight: 700;
line-height: 1.15;
color: var(--ink);
letter-spacing: -.01em;
max-width: 22ch;
}
.acc-18__spread p {
font-size: 14px;
line-height: 1.6;
color: #5c5443;
max-width: 44ch;
}
.acc-18__spread i {
font-style: normal;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: #8a8069;
}
.acc-18__panel:has(input:focus-visible) .acc-18__face {
outline: 3px solid var(--ink);
outline-offset: -6px;
}
@media (max-width: 620px) {
.acc-18__row {
flex-direction: column;
height: auto;
border-block: none;
}
.acc-18__panel {
min-height: 70px;
}
.acc-18__panel + .acc-18__panel {
border-left: none;
border-top: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
min-height: 280px;
}
.acc-18__spine {
writing-mode: horizontal-tb;
rotate: none;
left: auto;
right: 18px;
bottom: auto;
top: 24px;
translate: 0 0;
}
}
@media (prefers-reduced-motion: reduce) {
.acc-18__panel,
.acc-18__num,
.acc-18__spread {
transition: none;
}
}.acc-18,
.acc-18 *,
.acc-18 *::before,
.acc-18 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.acc-18 {
--ink: #211d16;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f5f1e8;
padding: 44px 24px;
}
.acc-18__row {
display: flex;
width: min(860px,100%);
height: 420px;
border-block: 2px solid var(--ink);
}
.acc-18__panel {
display: flex;
flex-grow: 1;
flex-basis: 0;
min-width: 76px;
transition: flex-grow .55s cubic-bezier(.4,0,.2,1);
}
.acc-18__panel + .acc-18__panel {
border-left: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
flex-grow: 5;
}
.acc-18__panel input {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.acc-18__face {
position: relative;
flex: 1;
display: block;
cursor: pointer;
overflow: hidden;
transition: background .3s;
}
.acc-18__face:hover {
background: #efe9dc;
}
.acc-18__num {
position: absolute;
left: 10px;
top: 0;
font-family: Georgia,serif;
font-size: 140px;
line-height: 1;
font-weight: 700;
color: color-mix(in oklab,var(--ink) 9%,transparent);
transition: font-size .55s cubic-bezier(.4,0,.2,1),left .55s;
z-index: 0;
}
.acc-18__panel:has(input:checked) .acc-18__num {
font-size: 230px;
left: 18px;
}
.acc-18__spine {
position: absolute;
bottom: 18px;
left: 50%;
translate: -50% 0;
writing-mode: vertical-rl;
rotate: 180deg;
font-size: 12px;
font-weight: 700;
letter-spacing: .18em;
text-transform: uppercase;
color: #8a8069;
transition: opacity .25s;
}
.acc-18__panel:has(input:checked) .acc-18__spine {
opacity: 0;
}
.acc-18__spread {
position: absolute;
inset: 0;
z-index: 1;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: 10px;
padding: 28px;
opacity: 0;
translate: 0 10px;
transition: opacity .35s .2s,translate .35s .2s;
}
.acc-18__panel:has(input:checked) .acc-18__spread {
opacity: 1;
translate: 0 0;
}
.acc-18__spread b {
font-family: Georgia,serif;
font-size: clamp(22px,3vw,30px);
font-weight: 700;
line-height: 1.15;
color: var(--ink);
letter-spacing: -.01em;
max-width: 22ch;
}
.acc-18__spread p {
font-size: 14px;
line-height: 1.6;
color: #5c5443;
max-width: 44ch;
}
.acc-18__spread i {
font-style: normal;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: #8a8069;
}
.acc-18__panel:has(input:focus-visible) .acc-18__face {
outline: 3px solid var(--ink);
outline-offset: -6px;
}
@media (max-width: 620px) {
.acc-18__row {
flex-direction: column;
height: auto;
border-block: none;
}
.acc-18__panel {
min-height: 70px;
}
.acc-18__panel + .acc-18__panel {
border-left: none;
border-top: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
min-height: 280px;
}
.acc-18__spine {
writing-mode: horizontal-tb;
rotate: none;
left: auto;
right: 18px;
bottom: auto;
top: 24px;
translate: 0 0;
}
}
@media (prefers-reduced-motion: reduce) {
.acc-18__panel,
.acc-18__num,
.acc-18__spread {
transition: none;
}
}/* No JavaScript — one persistent ghost numeral per panel transitions its font-size as the flex column expands, so the number appears to grow into the open editorial spread. */
/* No JavaScript — one persistent ghost numeral per panel transitions its font-size as the flex column expands, so the number appears to grow into the open editorial spread. */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: Numbered Spine Horizontal Accordion — Editorial Magazine Index
Source: https://codefronts.com/navigation/css-accordions/numbered-spine/
A magazine table-of-contents turned interactive: cream paper, hairline column rules, and giant ghosted numerals 1–4 stacked in each collapsed spine. The open column lays its numeral behind a serif headline and dek like an art-directed spread. Quiet, typographic, and unlike any card-based accordion.
## HTML
```html
<section class="acc-18" aria-label="Numbered spine editorial accordion demo">
<div class="acc-18__row" role="group" aria-label="Issue contents">
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-a" checked>
<label class="acc-18__face" for="acc-18-a"><span class="acc-18__num">1</span><span class="acc-18__spine">The Interview</span>
<span class="acc-18__spread"><b>The last typesetter of Fleet Street</b><p>Sixty years of hot metal, and what the craft knew that the software forgot.</p><i>By M. Okafor · 18 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-b">
<label class="acc-18__face" for="acc-18-b"><span class="acc-18__num">2</span><span class="acc-18__spine">Field Report</span>
<span class="acc-18__spread"><b>Notes from the seed vault</b><p>Inside the arctic archive where every harvest on earth keeps a backup copy.</p><i>By T. Lindqvist · 12 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-c">
<label class="acc-18__face" for="acc-18-c"><span class="acc-18__num">3</span><span class="acc-18__spine">Essay</span>
<span class="acc-18__spread"><b>In defence of the long way</b><p>On slowness as a design material, and why the fastest path is rarely the best one.</p><i>By A. Fontaine · 9 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-d">
<label class="acc-18__face" for="acc-18-d"><span class="acc-18__num">4</span><span class="acc-18__spine">Archive</span>
<span class="acc-18__spread"><b>The 1961 letters</b><p>A rediscovered correspondence between two rival foundries, annotated.</p><i>Edited by the staff · 15 min</i></span>
</label>
</div>
</div>
</section>
```
## CSS
```css
.acc-18,
.acc-18 *,
.acc-18 *::before,
.acc-18 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.acc-18 {
--ink: #211d16;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f5f1e8;
padding: 44px 24px;
}
.acc-18__row {
display: flex;
width: min(860px,100%);
height: 420px;
border-block: 2px solid var(--ink);
}
.acc-18__panel {
display: flex;
flex-grow: 1;
flex-basis: 0;
min-width: 76px;
transition: flex-grow .55s cubic-bezier(.4,0,.2,1);
}
.acc-18__panel + .acc-18__panel {
border-left: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
flex-grow: 5;
}
.acc-18__panel input {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.acc-18__face {
position: relative;
flex: 1;
display: block;
cursor: pointer;
overflow: hidden;
transition: background .3s;
}
.acc-18__face:hover {
background: #efe9dc;
}
.acc-18__num {
position: absolute;
left: 10px;
top: 0;
font-family: Georgia,serif;
font-size: 140px;
line-height: 1;
font-weight: 700;
color: color-mix(in oklab,var(--ink) 9%,transparent);
transition: font-size .55s cubic-bezier(.4,0,.2,1),left .55s;
z-index: 0;
}
.acc-18__panel:has(input:checked) .acc-18__num {
font-size: 230px;
left: 18px;
}
.acc-18__spine {
position: absolute;
bottom: 18px;
left: 50%;
translate: -50% 0;
writing-mode: vertical-rl;
rotate: 180deg;
font-size: 12px;
font-weight: 700;
letter-spacing: .18em;
text-transform: uppercase;
color: #8a8069;
transition: opacity .25s;
}
.acc-18__panel:has(input:checked) .acc-18__spine {
opacity: 0;
}
.acc-18__spread {
position: absolute;
inset: 0;
z-index: 1;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: 10px;
padding: 28px;
opacity: 0;
translate: 0 10px;
transition: opacity .35s .2s,translate .35s .2s;
}
.acc-18__panel:has(input:checked) .acc-18__spread {
opacity: 1;
translate: 0 0;
}
.acc-18__spread b {
font-family: Georgia,serif;
font-size: clamp(22px,3vw,30px);
font-weight: 700;
line-height: 1.15;
color: var(--ink);
letter-spacing: -.01em;
max-width: 22ch;
}
.acc-18__spread p {
font-size: 14px;
line-height: 1.6;
color: #5c5443;
max-width: 44ch;
}
.acc-18__spread i {
font-style: normal;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: #8a8069;
}
.acc-18__panel:has(input:focus-visible) .acc-18__face {
outline: 3px solid var(--ink);
outline-offset: -6px;
}
@media (max-width: 620px) {
.acc-18__row {
flex-direction: column;
height: auto;
border-block: none;
}
.acc-18__panel {
min-height: 70px;
}
.acc-18__panel + .acc-18__panel {
border-left: none;
border-top: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
min-height: 280px;
}
.acc-18__spine {
writing-mode: horizontal-tb;
rotate: none;
left: auto;
right: 18px;
bottom: auto;
top: 24px;
translate: 0 0;
}
}
@media (prefers-reduced-motion: reduce) {
.acc-18__panel,
.acc-18__num,
.acc-18__spread {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — one persistent ghost numeral per panel transitions its font-size as the flex column expands, so the number appears to grow into the open editorial spread. */
```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: Numbered Spine Horizontal Accordion — Editorial Magazine Index
Source: https://codefronts.com/navigation/css-accordions/numbered-spine/
A magazine table-of-contents turned interactive: cream paper, hairline column rules, and giant ghosted numerals 1–4 stacked in each collapsed spine. The open column lays its numeral behind a serif headline and dek like an art-directed spread. Quiet, typographic, and unlike any card-based accordion.
## HTML
```html
<section class="acc-18" aria-label="Numbered spine editorial accordion demo">
<div class="acc-18__row" role="group" aria-label="Issue contents">
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-a" checked>
<label class="acc-18__face" for="acc-18-a"><span class="acc-18__num">1</span><span class="acc-18__spine">The Interview</span>
<span class="acc-18__spread"><b>The last typesetter of Fleet Street</b><p>Sixty years of hot metal, and what the craft knew that the software forgot.</p><i>By M. Okafor · 18 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-b">
<label class="acc-18__face" for="acc-18-b"><span class="acc-18__num">2</span><span class="acc-18__spine">Field Report</span>
<span class="acc-18__spread"><b>Notes from the seed vault</b><p>Inside the arctic archive where every harvest on earth keeps a backup copy.</p><i>By T. Lindqvist · 12 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-c">
<label class="acc-18__face" for="acc-18-c"><span class="acc-18__num">3</span><span class="acc-18__spine">Essay</span>
<span class="acc-18__spread"><b>In defence of the long way</b><p>On slowness as a design material, and why the fastest path is rarely the best one.</p><i>By A. Fontaine · 9 min</i></span>
</label>
</div>
<div class="acc-18__panel">
<input type="radio" name="acc-18" id="acc-18-d">
<label class="acc-18__face" for="acc-18-d"><span class="acc-18__num">4</span><span class="acc-18__spine">Archive</span>
<span class="acc-18__spread"><b>The 1961 letters</b><p>A rediscovered correspondence between two rival foundries, annotated.</p><i>Edited by the staff · 15 min</i></span>
</label>
</div>
</div>
</section>
```
## CSS
```css
.acc-18,
.acc-18 *,
.acc-18 *::before,
.acc-18 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.acc-18 {
--ink: #211d16;
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f5f1e8;
padding: 44px 24px;
}
.acc-18__row {
display: flex;
width: min(860px,100%);
height: 420px;
border-block: 2px solid var(--ink);
}
.acc-18__panel {
display: flex;
flex-grow: 1;
flex-basis: 0;
min-width: 76px;
transition: flex-grow .55s cubic-bezier(.4,0,.2,1);
}
.acc-18__panel + .acc-18__panel {
border-left: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
flex-grow: 5;
}
.acc-18__panel input {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.acc-18__face {
position: relative;
flex: 1;
display: block;
cursor: pointer;
overflow: hidden;
transition: background .3s;
}
.acc-18__face:hover {
background: #efe9dc;
}
.acc-18__num {
position: absolute;
left: 10px;
top: 0;
font-family: Georgia,serif;
font-size: 140px;
line-height: 1;
font-weight: 700;
color: color-mix(in oklab,var(--ink) 9%,transparent);
transition: font-size .55s cubic-bezier(.4,0,.2,1),left .55s;
z-index: 0;
}
.acc-18__panel:has(input:checked) .acc-18__num {
font-size: 230px;
left: 18px;
}
.acc-18__spine {
position: absolute;
bottom: 18px;
left: 50%;
translate: -50% 0;
writing-mode: vertical-rl;
rotate: 180deg;
font-size: 12px;
font-weight: 700;
letter-spacing: .18em;
text-transform: uppercase;
color: #8a8069;
transition: opacity .25s;
}
.acc-18__panel:has(input:checked) .acc-18__spine {
opacity: 0;
}
.acc-18__spread {
position: absolute;
inset: 0;
z-index: 1;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: 10px;
padding: 28px;
opacity: 0;
translate: 0 10px;
transition: opacity .35s .2s,translate .35s .2s;
}
.acc-18__panel:has(input:checked) .acc-18__spread {
opacity: 1;
translate: 0 0;
}
.acc-18__spread b {
font-family: Georgia,serif;
font-size: clamp(22px,3vw,30px);
font-weight: 700;
line-height: 1.15;
color: var(--ink);
letter-spacing: -.01em;
max-width: 22ch;
}
.acc-18__spread p {
font-size: 14px;
line-height: 1.6;
color: #5c5443;
max-width: 44ch;
}
.acc-18__spread i {
font-style: normal;
font-size: 11.5px;
font-weight: 700;
letter-spacing: .13em;
text-transform: uppercase;
color: #8a8069;
}
.acc-18__panel:has(input:focus-visible) .acc-18__face {
outline: 3px solid var(--ink);
outline-offset: -6px;
}
@media (max-width: 620px) {
.acc-18__row {
flex-direction: column;
height: auto;
border-block: none;
}
.acc-18__panel {
min-height: 70px;
}
.acc-18__panel + .acc-18__panel {
border-left: none;
border-top: 1px solid #d8d0bd;
}
.acc-18__panel:has(input:checked) {
min-height: 280px;
}
.acc-18__spine {
writing-mode: horizontal-tb;
rotate: none;
left: auto;
right: 18px;
bottom: auto;
top: 24px;
translate: 0 0;
}
}
@media (prefers-reduced-motion: reduce) {
.acc-18__panel,
.acc-18__num,
.acc-18__spread {
transition: none;
}
}
```
## JavaScript
```js
/* No JavaScript — one persistent ghost numeral per panel transitions its font-size as the flex column expands, so the number appears to grow into the open editorial spread. */
```How this works
Where demo 17 speaks in color, this one speaks entirely in type. Collapsed spines show a huge numeral (140px, 8% ink) with the section word running vertically beside it; hairline left borders between panels stand in for the printed column rules. The active panel re-uses the SAME numeral — it swells to 220px and stays ghosted while the headline and dek set over it, the classic editorial number-behind-text spread, achieved just by layering z-index over an absolutely-placed numeral.
Because the numeral persists across states (only scaling and repositioning via transition), the open/close motion reads as the number physically growing into the spread rather than elements swapping. Serif display for headlines (Georgia), sans for the deks and spine words — a two-face system that keys the whole demo.
Techniques used: persistent ghost numeral transitioning scale/position across states · hairline border-left column rules · serif/sans two-face editorial pairing · z-index text-over-numeral layering · vertical spine words via writing-mode
Make it yours
- Numeral sizes = the two font-size stops (collapsed/open).
- Ghost strength = the numeral's color alpha (8% here).
- Swap Georgia for your display serif; spine words stay sans.
- Paper tone = the section background.
Gotchas — read before shipping
- The numeral must be ONE element that transitions — swapping two differently-sized numerals kills the growing effect.
- Keep numerals ≤8% ink or headlines fail contrast sitting over them (the headline's own contrast is measured against paper + ghost).
- Hairline rules: use border-left on panels 2+, not gap+background, so the rules stretch full height.
- This pattern needs generous height (≥380px) — cramped, the numerals collide with deks.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.2+ | 121+ | 111+ |
Floor set by :has(), color-mix() as this demo is written. The core technique itself goes back further — Chrome all.
Typography, borders and flex transitions — baseline everywhere.