Tiles
Interactive navigation elements with text-only or media-and-text layouts for linking to content.
Choosing a tile pattern
Section titled “Choosing a tile pattern”Tiles are semantic links or buttons. Use Cards when the content container itself should not be interactive.
Text tile
Section titled “Text tile”The text tile is a compact interactive element with an optional icon at the top and a body label anchored to the bottom. The icon is a direct child of the tile, not a slotted element.
When the icon is omitted, space is reserved at the top and the body label stays anchored to the bottom.
Show code
import { Icon } from '@volvo-cars/react-icons';
export function TextTile() { return ( <div className="grid-cols-2 gap-x-gutter gap-y-24" style={{ height: '200px' }} > <a href="#top" className="text-tile"> <Icon icon="charging-battery" size={24} /> <span slot="body">Charging</span> </a> <a href="#top" className="text-tile"> <span slot="body">Without icon</span> </a> </div> );}This component uses slots to give content built-in styling.
- Icon – Direct child element (not slotted)
slot="body"– Label text
Show code
<a class="text-tile" href="#" style="height: 200px"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" > <path stroke="currentColor" stroke-width="1.5" d="M12 3v18M3 12h18" /> </svg> <code slot="body">body</code></a>Grid layout
Section titled “Grid layout”Wrap tiles in <li> elements inside a <ul> for semantic grouping. Give the container a fixed height so tiles share consistent dimensions.
Media tile
Section titled “Media tile”The media tile pairs an image with a body label. The media slot defaults to a 4 / 3 aspect ratio. Images hover-zoom on interaction.
Show code
<a href="#" class="media-tile" style="max-width: 360px"> <div slot="media"> <img class="img" src="/images/cars/card/es90.avif" alt="" /> </div> <span slot="body">Explore the Volvo ES90</span></a>This component uses slots to give content built-in styling.
slot="media"– Image containerslot="body"– Label text
Show code
<a class="media-tile" href="#" style="max-width: 280px"> <div slot="media" class="bg-feedback-gray flex items-center justify-center h-full" > <code>media</code> </div> <code slot="body">body</code></a>The media slot requires a wrapping <div>: images are absolutely positioned inside it for the hover zoom effect.
Horizontal layout
Section titled “Horizontal layout”Add flex-row items-center gap-16 to arrange the media beside the label. Set a fixed width on the media slot to control its size. The aspect ratio determines the height.
Grid layout
Section titled “Grid layout”Arrange media tiles as list items in a CSS grid, using the same semantic grouping as text tiles.
Accessibility
Section titled “Accessibility”- Always use
<a>for navigation or<button>for actions. Tiles must be interactive elements - Provide descriptive
alttext for images, or usealt=""for decorative images when the body label provides sufficient context - Add
aria-hidden="true"to decorative icons that repeat the body label’s meaning - In grid layouts, wrap tiles in
<li>elements inside a<ul>for semantic list structure - The body label is styled with an underline to signal interactivity without relying on color alone
CSS reference
Section titled “CSS reference”| Class | Description |
|---|---|
text-tile | Interactive tile with optional icon and bottom-anchored label. Secondary background. |
media-tile | Interactive tile with image (4:3 cover) and label. Image zooms on hover. |