Desktop components

Image wells

An image well is an editable version of an image view.

When to use it

Use an image well where people can drop in or replace a picture, like an avatar or artwork slot. For display-only images, use a plain <img>.

Preview

The first two are filled wells (30px and a scaled 64px). The third is empty. The last is disabled.

Anatomy

The well is a 30px box with a 3px radius holding a 24px image at a 3px inset; the image keeps square corners. The margin around the image fills with rgba(0, 0, 0, 0.02). The frame runs outside to in: a 0.5px soft edge at rgba(0, 0, 0, 0.05) just outside the box, a 1px white ring at the box edge, and a thin soft inner edge at 5% black under it. The white ring between dark hairlines is what makes it read as an inset well rather than a card.

Only the 30px size is canonical, but the frame is size independent: set any width and height and the inset and rings hold.

ClassRole
.p-imagewellThe well. A <label> wrapping an <img> and a hidden <input type="file">.
.p-dragoverDrop-target highlight; add it from your drag handlers.
.p-dimmedDisabled look; automatic when the input is disabled.

Behavior

The label makes the whole well activate the file picker, and the input stays keyboard focusable. Reading the chosen file into the <img> is app logic:

<label class="p-imagewell">
  <img src="avatar.png" alt="Profile picture" />
  <input type="file" accept="image/*" aria-label="Change profile picture" />
</label>

<script>
  document.querySelector('.p-imagewell input').addEventListener('change', (e) => {
    const [file] = e.target.files;
    if (file) e.target.closest('.p-imagewell').querySelector('img').src =
      URL.createObjectURL(file);
  });
</script>

For drag and drop, toggle .p-dragover on dragenter and dragleave and read event.dataTransfer.files on drop.

States

Focus and drag-over show a 3.5px ring in the focus band color, rgba(0,136,255,0.5), with a 1px offset. Disabled (or .p-dimmed) drops the well to 50% opacity, the standard macOS dimmed treatment.

Dark mode

The well fill lifts to rgba(255, 255, 255, 0.04), the white ring drops to rgba(255, 255, 255, 0.15), and the soft edges deepen to 30% black. Both .p-dark-mode and .p-auto-dark-mode are supported.

Copied