Navigation

v0.0.4
Materials

Pile

Several things shown as one, with the edges of the others under it.

On this page

A pile shows several things as one: notifications of one kind, files sent together, drafts of one document. It holds one surface, the top one, and draws two more behind it, each a step narrower, a step lower and a step fainter. They read as sheets lying under the first, not as a shadow.

Pile

<div class="pile w-full max-w(340)">  <article class="card">    <header class="card-header">      <h3 class="card-title">3 deployments failed</h3>      <p class="card-description">atlas.dev, in the last hour</p>      <button class="card-action btn btn-sm" type="button">Show all</button>    </header>  </article></div>

#What it draws

The pile is a holder: put one surface in it, a card, a sheet, a file. The two sheets under it are drawn by the stylesheet, 8px in on both sides and 6px lower than the one above, and the pile keeps 12px under the top surface for them, so nothing after it has to make room.

The sheets take the corner in --pile-radius, a surface's corner. When the top surface has another corner, set the property to it, as the file below does. --pile-step and --pile-inset change how far each sheet shows.

Files

<div class="pile w-full max-w(280)" style="--pile-radius: var(--radius-control-lg)">  <div class="file">    <span class="file-page">pdf</span>    <div class="file-body">      <p class="file-name">Quarterly report.pdf</p>      <p class="file-meta">and 4 more files · 12.8 MB</p>    </div>  </div></div>

#Say how many

The sheets under the top one are decoration. They are always two, whether the pile stands for three things or thirty, and they are not announced. Say how many there are in words on the top surface, and give the reader a way to see them all: a button that opens the group, or a link to the list.

#Pile, list or avatar group

A pile is for members that need not all be seen. When every member matters, show them in a list. People are an avatar group, which overlaps their faces. Slides to step through are a carousel.

#Accessibility

  • The pile adds no role and no name. The surface it holds carries the meaning.
  • State the count in text, since the drawing does not.
  • In forced colors the two sheets take a system outline and are fully opaque.

#Classes

ClassDescription
pileThe holder of the top surface: two sheets lie behind it, each 8px in on both sides and 6px lower than the one above

#Custom properties

PropertyDefaultDescription
--pile-radiusvar(--radius-surface)The corner of the sheets under the top one; set it to the top surface's own corner
--pile-step.375remHow far each sheet shows below the one above it
--pile-inset.5remHow far each sheet is in from the one above it, on both sides

#Source

@master/ui/components/pile.css
/* * Pile: several things shown as one, with the edges of the others under it. * The pile holds one surface, the top one, and draws two more behind it: each a step narrower, a step lower * and a step fainter, so they read as sheets lying under the first and not as a shadow. Nothing in them is * content: say how many there are in words, on the top one. * Geometry: each sheet under the top is 8px in on both sides and shows 6px below the one above it. They take * the corner in --pile-radius, a surface's corner unless the top sheet has another. */@layer components {  .pile {    --pile-radius: var(--radius-surface);    --pile-step: .375rem;    --pile-inset: .5rem;    position: relative;    /* The sheets lie behind the top one, and no further back than the pile. */    isolation: isolate;    display: grid;    min-width: 0;    margin: 0;    padding-bottom: calc(var(--pile-step) * 2);    &::before, &::after {      content: '';      position: absolute;      inset-block-start: 1rem;      border-radius: calc(var(--pile-radius) * var(--corner-scale));      corner-shape: var(--corner-shape);      background: var(--color-surface-raised-low);      box-shadow: var(--shadow-flat), 0 1px 2px -1px var(--color-shade-2);      pointer-events: none;    }    /* The second sheet. */    &::before {      z-index: -1;      inset-block-end: var(--pile-step);      inset-inline: var(--pile-inset);      opacity: .8;    }    /* The third. */    &::after {      z-index: -2;      inset-block-end: 0;      inset-inline: calc(var(--pile-inset) * 2);      opacity: .5;    }    @media (forced-colors: active) {      &::before, &::after {        outline: 1px solid CanvasText;        outline-offset: -1px;        opacity: 1;      }    }  }}