Menu


Picture tile


A pressable tile with a picture and a short label under it, for choosing among looks, presets or templates in a gallery.

Customize the preview


Choices
Flags
View

Options


Picture tile options
ChoiceValuesDefaultWhat it does
ratiosmbk-picture-tile--ratio-<value>4-31-14-3
The picture's proportion, width to height: 4:3 or square.
selectedsmbk-picture-tile--selectedOn or offOff
The chosen tile: the rim edge at the emphasis width and a tick at the picture's corner. Pressed for assistive technology.

Partssmbk-picture-tile__picturesmbk-picture-tile__labelsmbk-picture-tile__tick

Examples


Usage

A gallery of looks, two to a row: one is chosen, and the others are toggles that are off.

Ratios

The picture at 4:3 or square.

States

Chosen tiles show the stronger edge and the tick; disabled tiles dim their picture and label.

Loading and missing pictures

A skeleton while the picture loads; an image placeholder when there is none.

A wrapping grid

Tiles fill their cells and wrap; a long label is cut short with an ellipsis.

Guidelines


Purpose

Lets someone choose among things best told apart by a picture: a look, a preset, a template, a theme. Each tile is one button with a picture on top and a short label under it, laid out in a grid that wraps. Pointing at a tile can preview it; pressing it chooses it.

When to use

  • A gallery of options that look different, where the picture says more than the name: filters, styles, layouts, templates.
  • With one tile chosen, as a set of toggles where one is on.

When not to use

  • For an article or a product with a title, a description and actions. Use a card.
  • For options that differ only by name. Use radios, a segmented control or a select.
  • For a picture that opens a larger view and nothing else. Use a link around the picture.

Usage rules

Do

  • Keep labels to a word or two.
  • Show the same subject in every tile, so only the option changes.
  • Give each tile the same proportion in one gallery.

Don't

  • Put a button or a link inside a tile.
  • Mix tiles that choose with tiles that run an action in one gallery.
Do

Show the same subject in every tile, so only the look changes.

Don't

Tiles of different proportions in one gallery break its rows.

Anatomy

  • The block, one button: a frame on the default surface with a thin edge and a small rounded corner, as wide as the cell it is given.
  • The picture part, at a 4:3 or square proportion on the sunken surface. It holds the picture, an image placeholder while there is none, or a skeleton while it loads.
  • The label part, one line of small body text under the picture, cut short with an ellipsis when it is too long.
  • The tick part, shown on the chosen tile only: a check on a brand-colored disc at the picture's top corner.

Behavior

The tile fills the cell it is given and is never narrower than a small minimum, so a grid of tiles wraps on a narrow screen. Pointing at a tile strengthens its edge; pressing sinks it onto the sunken surface; keyboard focus draws the focus ring around it. The chosen tile shows a stronger edge at double width, a slight lift and the tick; pointing at it changes nothing more. A disabled tile dims its picture and label and cannot be pressed. A picture that fails to load gives way to the image placeholder, named by the picture's alternative text when it has one, so the tile never shows the browser's broken-picture mark.

Accessibility


What it does for you

  • The whole tile is one native button and one Tab stop, named by its label.
  • With selected set, true or false, the tile is a toggle and a screen reader says whether it is pressed.
  • The picture is decoration with an empty text alternative, since the label names the tile.
  • The tick, not only the edge's color, shows which tile is chosen. In high contrast mode the chosen edge and the tick take the highlight color.
  • The label is cut short with an ellipsis when long, but the button's name is the whole label.
  • A picture that fails to load gives way to the image placeholder, named by the picture's alternative text when it has one.

What you must do

  • Leave selected out for a tile that does something once when pressed.
  • Give the picture a text alternative when it shows something the label does not say.
  • Preview anything a tile previews on pointing also on keyboard focus: nothing may be shown by pointing alone.
  • Keep labels short so everyone sees all of them.

How to test

  • Tab to a tile: the focus ring shows around it, in both themes and in a forced-color mode.
  • Press Enter, then Space: each presses the tile. A disabled tile cannot be pressed.
  • With a screen reader, a tile is read as a button by its whole label. A selecting tile is read as pressed or not pressed.
  • With text at 200% and the page 320 pixels wide, the tiles wrap into fewer columns and each keeps its label.
  • In a forced-color mode, the chosen tile's edge and tick are drawn in the highlight color.

Keyboard

Picture tile keys
KeyWhat it does
Tab
Moves focus to the tile. A disabled tile is skipped.
EnterorSpace
Presses the tile.

Source


The files the picture tile is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.

Stylesheet
picture-tile.css
/* smbk-picture-tile — Picture tile. Figma "Picture tile" 7119:143 (Selected × State × Ratio, 20 variants).
 * One native button: a picture on top, at 4:3 or 1:1, and a short label under
 * it, in a frame of the default surface with a hairline edge in the subtle
 * border color and a small container's corner. It fills the cell it is given,
 * never narrower than the 88 size step, so a grid of them wraps. Pointing
 * strengthens the edge; pressing sinks the frame onto the sunken surface;
 * focus draws the shared ring outside it. Chosen, the edge turns the rim color
 * at the emphasis width, drawn inside so nothing moves, the tile lifts with
 * the control elevation, and a tick on a brand disc marks the picture's
 * corner: the shape says it is chosen, not the color alone. Disabled dims the
 * picture and the label. */

.smbk-picture-tile {
  box-sizing: border-box;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-sm);
  width: 100%;
  min-width: var(--smbk-size-88);
  margin: 0;
  padding: var(--smbk-space-inset-2xs);
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-subtle);
  border-radius: var(--smbk-radius-container-sm);
  background: var(--smbk-color-surface-default);
  color: var(--smbk-color-text-default);
  font: inherit;
  text-align: start;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* The picture: the tile's width at the ratio, on the sunken surface, with the inset corner. Whatever it holds
   (a picture, an image placeholder, a skeleton) fills it. */
.smbk-picture-tile__picture {
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--smbk-radius-inset);
  background: var(--smbk-color-surface-sunken);
}

.smbk-picture-tile__picture > * {
  display: block;
  width: 100%;
  height: 100%;
}

.smbk-picture-tile__picture > img {
  object-fit: cover;
}

.smbk-picture-tile--ratio-1-1 .smbk-picture-tile__picture {
  aspect-ratio: 1 / 1;
}

/* The label: one line of Body SM, cut short with an ellipsis; the button's name stays the whole label. */
.smbk-picture-tile__label {
  display: block;
  overflow: hidden;
  padding: var(--smbk-space-inset-xs) var(--smbk-space-inset-md) var(--smbk-space-inset-md);
  font-family: var(--smbk-typography-body-sm-font-family);
  font-size: var(--smbk-typography-body-sm-font-size);
  font-weight: var(--smbk-typography-body-sm-font-weight);
  line-height: var(--smbk-typography-body-sm-line-height);
  letter-spacing: var(--smbk-typography-body-sm-letter-spacing);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The tick: a brand disc with a check, 8 in from the tile's top and end corner. Shown only when chosen. */
.smbk-picture-tile__tick {
  position: absolute;
  inset-block-start: var(--smbk-space-inset-md);
  inset-inline-end: var(--smbk-space-inset-md);
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--smbk-size-20);
  height: var(--smbk-size-20);
  border-radius: var(--smbk-radius-full);
  background: var(--smbk-color-action-brand-background);
  color: var(--smbk-color-icon-on-brand);
}

.smbk-picture-tile__tick .smbk-icon {
  font-size: var(--smbk-size-icon-xs);
}

/* ---- states ---- */

@media (hover: hover) {
  .smbk-picture-tile:hover:enabled:not(.smbk-picture-tile--selected) {
    border-color: var(--smbk-color-border-strong);
  }
}

.smbk-picture-tile:active:enabled {
  background: var(--smbk-color-surface-sunken);
}

.smbk-picture-tile:focus-visible {
  outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
  outline-offset: var(--smbk-focus-ring-offset);
}

/* Chosen: the rim at the emphasis width, the hairline border plus the rest drawn inside, and the lift. */
.smbk-picture-tile--selected {
  border-color: var(--smbk-color-border-rim);
  box-shadow: inset 0 0 0 calc(var(--smbk-border-width-emphasis) - var(--smbk-border-width-hairline)) var(--smbk-color-border-rim), var(--smbk-elevation-control);
}

.smbk-picture-tile--selected .smbk-picture-tile__tick {
  display: flex;
}

.smbk-picture-tile:disabled {
  cursor: default;
}

.smbk-picture-tile:disabled .smbk-picture-tile__picture {
  opacity: var(--smbk-opacity-disabled);
}

.smbk-picture-tile:disabled .smbk-picture-tile__label {
  color: var(--smbk-color-text-disabled);
}

/* ---- high contrast (forced colors) ---- */
/* In Windows high-contrast mode the browser drops fills and shadows; this puts the meaning back with the
   user's own colors. Nothing here applies outside that mode. */

@media (forced-colors: active) {
  /* The chosen edge's inner half is a shadow and would vanish: the edge takes Highlight at full width. The
     tick's disc is a fill: it keeps its shape in Highlight with the check in the highlight's text color. */
  .smbk-picture-tile--selected {
    border-width: var(--smbk-border-width-emphasis);
    border-color: Highlight;
    padding: calc(var(--smbk-space-inset-2xs) - var(--smbk-border-width-emphasis) + var(--smbk-border-width-hairline));
  }

  .smbk-picture-tile__tick {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }

  .smbk-picture-tile:disabled {
    border-color: GrayText;
  }
}
Tokens it reads
Picture tile tokens
Token and CSSValuePreviewFoundation
space.stack.sm--smbk-space-stack-smcomfortable: 8pxcompact: 6pxchanges with densitySpacing
size.88--smbk-size-8888pxSize
space.inset.2xs--smbk-space-inset-2xs2pxSpacing
border-width.hairline--smbk-border-width-hairline1pxBorder width
color.border.subtle--smbk-color-border-subtlelight: #c4cdd8dark: #2d3237changes with themeColor
radius.container.sm--smbk-radius-container-sm8pxRadius
color.surface.default--smbk-color-surface-defaultlight: #f3f5f8dark: #181a1cchanges with themeColor
color.text.default--smbk-color-text-defaultlight: #232527dark: #e7ebf0changes with themeColor
radius.inset--smbk-radius-inset2pxRadius
color.surface.sunken--smbk-color-surface-sunkenlight: #373d430ddark: #00000066changes with themeColor
space.inset.xs--smbk-space-inset-xs4pxSpacing
space.inset.md--smbk-space-inset-mdcomfortable: 8pxcompact: 6pxchanges with densitySpacing
typography.body-sm--smbk-typography-body-sm-font-family--smbk-typography-body-sm-font-size--smbk-typography-body-sm-font-weight--smbk-typography-body-sm-line-height--smbk-typography-body-sm-letter-spacing--smbk-typography-body-sm-text-transformfontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px

The quick brown fox

Typography
size.20--smbk-size-2020pxSize
radius.full--smbk-radius-full9999pxRadius
color.action.brand.background--smbk-color-action-brand-background#cc0d0dColor
color.icon.on-brand--smbk-color-icon-on-brand#f9fafbColor
size.icon.xs--smbk-size-icon-xs12pxSize
color.border.strong--smbk-color-border-stronglight: #9ba5b1dark: #373d43changes with themeColor
focus.ring.width--smbk-focus-ring-width2pxFocus
color.border.focus--smbk-color-border-focuslight: #cc0d0ddark: #f34336changes with themeColor
focus.ring.offset--smbk-focus-ring-offset2pxFocus
color.border.rim--smbk-color-border-rimlight: #ffffffe6dark: #ffffff0dchanges with themeColor
border-width.emphasis--smbk-border-width-emphasis2pxBorder width
elevation.control--smbk-elevation-controllight: 0px 0px 1px 0px #373d430d, 0px 1px 2px 0px #373d431a, 0px 2px 4px 0px #373d430ddark: 0px 0px 1px 0px #0000001a, 0px 1px 2px 0px #00000026, 0px 2px 4px 0px #0000001aElevation
opacity.disabled--smbk-opacity-disabled0.5Opacity
color.text.disabled--smbk-color-text-disabledlight: #7c8692dark: #606a75changes with themeColor
Manifest
picture-tile.manifest.json
{
  "name": "picture-tile",
  "block": "smbk-picture-tile",
  "summary": "A pressable tile with a picture and a short label under it, for choosing among looks, presets or templates in a gallery.",
  "adapt": "css",
  "axes": {
    "ratio": {
      "values": [
        "4-3",
        "1-1"
      ],
      "default": "4-3",
      "description": "The picture's proportion, width to height: 4:3 or square."
    }
  },
  "flags": {
    "selected": {
      "description": "The chosen tile: the rim edge at the emphasis width and a tick at the picture's corner. Pressed for assistive technology."
    }
  },
  "parts": [
    "picture",
    "label",
    "tick"
  ],
  "figmaNodeId": "7119:143"
}