media object

Component that pairs images or videos with related text in a consistent way

import { CdrMediaObject } from '@rei/cedar'

MediaObject pairs images or videos with related text in a consistent way. For example, it can place a product photo next to its description.

Key features:

  • Built from layout
  • Flexible media positioning
  • Decoupled content/display patterns
  • Responsive design works well across device types and screen sizes
  • Works with CdrSurface containers to build content-rich components like cards and banners

When to use

  • Pairing content with an image, video, or a mixed media component

When not to use

  • Requiring two columns of content. In that case the layout component is more appropriate

When using CdrMediaObject, make sure that:

  • A parent element has the CSS property container-size applied. This property enables container queries to work
  • The content placed inside of the content slot is flexible. This means it can respond to the changing width of its container. If not, structures can break when content bleeds outside of the layout
  • If responsive positioning is needed, pass in an object for the mediaPosition
  • If using with surface, use the as prop to pass in CdrSurface and pass any surface props directly onto the layout component
  • If you need responsive padding, use the fluid spacing options to create gaps that respond to container widths (Example: scale-3--5).
  • If using responsive props, be sure to include all breakpoint options (xs, sm, md, lg)
  • You're aware that setting a mediaHeight while using a mediaPosition of right or left is discouraged. If content expands past the set height, it may be cut off

Development responsibilities

When using this component, here's what you are responsible for:

  • Always add in appropriate alt tags to any images placed within the media slot
  • For any images placed inside the media slot, be sure to include responsive options by specifying srcset and sizes

It's just CdrLayout

The media object is built using the layout component. All props available to layout can be passed into media object as well. This includes gap to create space between cells and as to specify which component to render—for example, CdrSurface rather than a plain div.

Content padding

Content will often need padding, so here are a few good ways to apply it around the content:

  • Apply a gap between content and media by using the gap prop as specified by layout
  • Apply padding all around the content using the contentPadding prop. Specify one-x (or other common spacing tokens) for fixed padding or even scale-3--5 for fluid padding
  • Content padding can also be an object of breakpoints that specifies a padding for each breakpoint

Responsive media position

A media position can be fixed, where media and content are always in the same position across all screen sizes and containers. Alternatively, it can be an object of breakpoints (xs, sm, md, lg) that specifies a position for each breakpoint. Container queries are used for responsive changes.

Alinging content and media

The align prop allows you to determine how the slots look next to each other. What is interesting about the align prop is that depending on the media position, it will operate on a particular axis. With left or right media positioning, the alignment operates vertically. When media position is top or bottom, the alignment operates horizontally. Alignment can be either a value or a responsive object.

Media width and height

The media height is typically used when the media position is set to top or bottom—it specifies how much space the row of media should take up. When paired with the cover prop, you can easily drop media into this component. This property helps when creating columns of multiple media objects where each image should be the same row height.

The media width is typically used when the media position is set to left or right—it specifies how much space the media column should take up. This prop is helpful in creating layouts where we find 2:1 or 3:1 ratios of media to content.

Both media height and width accept fixed values or an object of breakpoints (xs, sm, md, lg) that specifies a value for each breakpoint.

Content is always set to a width and height of auto, regardless of media position.

Media cover

By default, the media slot is not forced to extend to the full height when the media position is left or right. When media position is top or bottom, it is not forced to full width.

By using :media-cover="true", the div containing the media and the media itself are applied styles forcing 100% width and height. The media is also positioned absolutely, so that it does not influence the size of the layout in any way. The mediaCover prop is probably most useful when the media position is top or bottom and a mediaHeight is specified.

Overlay

In order to produce content floating above media, use the :overlay="true" option. This will automatically float the content on top of the image. Using overlayRowAlign and overlayColumnAlign, the content can hug the top, bottom, left, right, or center of the container. The values of start, center, end are applied to a flex box that the content is placed into.

The media slot

A quick note about the media slot—it does not need to be an image or video. If a design calls for an image with a badge on top of it, you can pass in a div with multiple images inside and still use the media object.

When using CdrMediaObject in a TypeScript application, we recommend importing the MediaObject interface from the library if you want fine-grained control over the options passed to the component.

ParentComponent.vue

<script setup lang="ts">
import { CdrMediaObject, type MediaObject } from '@rei/cedar'

const example: MediaObject = {
  contentPadding: 'one-x',
  align: 'center',
  mediaWidth: '2fr'
};

</script>

<template>
  <main>
    <CdrMediaObject v-bind="example">
      ...
    </CdrMediaObject>
  </main>
</template>

CdrMediaObject

Props

NameTypeDefault
as

The component or HTML tag to render at the root level. Note: The component "CdrSurface" has special treatment and may be used in quotes.

union
columnGap

Specifies a column gap based on the token options within Cedar. Possible values: zero, one-x, two-x, scale-4, scale-3--5

Space
rowGap

Specifies a row gap based on the token options within Cedar. Possible values: zero, one-x, two-x, scale-4, scale-3--5

Space
gap

Specifies a gap based on the token options within Cedar. Possible values: zero, one-x, two-x, scale-4, scale-3--5

Space
rows

Determines the number of rows at various breakpoints

StructureOption
columns

Determines the number of columns at various breakpoints

StructureOption
flowValue

Specifies how auto-generated tracks will be created. This is translated to either `grid-auto-columns` or `grid-auto-rows`, depending on flow.

string
flow

Specifies the auto-placement behavior. This is translated to `grid-auto-flow`. Possible values: row, column

Flow
queryType

Determines if the layout is in horizontal or vertical mode. Possible values: container, media

QueryType
align

The alignment of the media and content along the x or y axis, depending on the layout. This can be an object with values for each Cedar breakpoint (xs, sm, md, lg). Possible values: start, center, end

Alignment'start'
mediaPosition

The position of the media, in relation to the content. This can be an object with values for each Cedar breakpoint (xs, sm, md, lg). Possible values: top, right, bottom, left

Position'left'
mediaWidth

The width of the column that media is placed within. This can be any CSS value. This can be an object with values for each Cedar breakpoint (xs, sm, md, lg). Possible values: 1fr, auto, 25%, 50%, 75%, 200px, 50cqh

MediaMeasurement'1fr'
mediaHeight

The height of the column that media is placed within. This can be any CSS value. This can be an object with values for each Cedar breakpoint (xs, sm, md, lg). Possible values: 1fr, auto, 25%, 50%, 75%, 200px, 50cqw

MediaMeasurement'auto'
mediaCover

This property forces media to take up the full height and width of the media container and positions media to be absolute. Images and videos will still need to be configured with object-fit and object-position.

booleanfalse
overlay

Determines if content will overlay the media. A default media height is set, but it is suggested to apply your own using as value such as container width units (cqw) or rem.

booleanfalse
overlayRowAlign

The alignment of the content along the x axis. Possible values: start, center, end

AlignmentValue'start'
overlayColumnAlign

The alignment of the content along the y axis. Possible values: start, center, end

AlignmentValue'start'
contentPadding

The spacing token to use for padding around the content. This can be an object with values for each Cedar breakpoint (xs, sm, md, lg). Possible values: zero, one-x, two-x

SpaceFixed'zero'

Slots

Name
media

Where the media should be placed. Should be a single node.

content

Where all content should be placed. Can be multiple nodes.