Menu California Design System

Cards

Still work in progress.

Cards combine imagery, a short description, and a link or call-to-action.

I've avoided styling the content of the card, for now. I'd prefer card content to be driven by standard building blocks, like the rest of the DS. We could provide utility classes to size things like card headings. This would be much more flexible and encourage emergent use.

Cards themselves have no explicit size. They flow into their container. This makes them useful in many different scenarios.

Simple card

Here's a basic card, all alone.

California poppy flower
<ca-card>
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" height="320" alt="California poppy flower">
  <article>
    <h3><a href="#">My first card</a></h3>
    <p>Nothing fancy yet!</p>
    <a href="#" class="button button-magenta">Button</a>
  </article>
</ca-card>

A card consists of two possible elements.

  • An image, such as an img or svg element. The abstract ca-visual element may also be used for more advanced situations.
  • A content section. This can be article, div, or section, depending upon desired semantics.

Card sizing

Cards have no explicit size themselves. They expand to fit image and content.

Note the height="320" on the image above. If we increase the image's height to 450, the whole card will expand to match.

California poppy flower
<ca-card>
  <!-- Note the image height. -->
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" height="450" alt="California poppy flower">
  <article>
    <h3><a href="#">My first card, larger</a></h3>
    <p>The larger image creates a larger card, by default.</p>
  </article>
</ca-card>

We can also shrink cards to fit wherever we need to fit them. The most intuitive way to shrink a card is to directly apply a max-width. And doing so will work.

California poppy flower
<ca-card style="max-width: 31rem;">
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" height="450" alt="California poppy flower">
  <article>
    <h3><a href="#">My first card, constrained</a></h3>
    <p>The <code>max-width</code> limits the size of the card. (But doesn't the image look a bit stretched?)</p>
  </article>
</ca-card>

With that said, in most scenarios, we will want to fit the card into a parent container, such as a div, grid, or list. Cards also shrink to fit their parent container.

Below, we place the card within a div that's locked to a max width of 31rem.

California poppy flower

My first card, in a div

We have controlled the width of this card via parent element. (But again, the image looks wrong.)

<div style="max-width: 31rem;">
  <ca-card>
    <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" height="450" alt="California poppy flower">
    <article>
      <h3><a href="#">My first card, in a div</a></h3>
      <p>We have controlled the width of this card via parent element. (But again, the image looks wrong.)</p>
    </article>
  </ca-card>
</div>

However, in both of the previous two examples, we've stretched the image. That will not do, and that's where the fit attribute comes to the rescue.

Image fit

As seen above, the card's image may stretch into unnatural shapes if we try to control the card's size. We can use the fit attribute to control how the image fits into the card.

We'll take the same code from the stretched card above, but this time apply fit="cover".

California poppy flower

Using fit

Here we get the image under control in our smaller card.

<div style="max-width: 31rem;">
  <ca-card fit="cover">
    <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" height="450" alt="California poppy flower">
    <article>
      <h3><a href="#">Using fit</a></h3>
      <p>Here we get the image under control in our smaller card.</p>
    </article>
  </ca-card>
</div>

Much better!

Here's a list of all available options for fit.

Attribute Effect
fit="cover" Instructs the image to fill all available space, without breaking aspect ratio. Some content may be hidden along the edges.
fit="contain" Instructs the image to expand, but without breaking aspect ratio or hiding anything. This may result in some margin around the image.
fit="fill" Instructs the image to fill all available space by stretching itself, breaking aspect ratio.
fit="pad" Applies padding to the image, creating a small "border" around it.
fit="pad-cover" Same as fit="cover", with padding included.
fit="pad-contain" Same as fit="contain", with padding included.
fit="pad-fill" Same as fit="fill", with padding included.

The pad options will be helpful when creating cards with simple branding or iconography. Here's an example.

California poppy flower

Using pad

The fit="pad" attributes add a border around the image.

<div style="max-width: 350px;">
  <ca-card fit="pad-cover">
    <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
    <article>
      <h3><a href="#">Using pad</a></h3>
      <p>The <code>fit="pad"</code> attributes add a border around the image.</p>
    </article>
  </ca-card>
</div>

In addition to the fit attribute, we also have two CSS variables we can use to control the size of the image.

--card-image-min-size controls the minimum available space for the image within the card. It can be a relative size, like 25%, or an actual size, like 5rem.

We also have --card-image-max-size. Same story, same rules.

California poppy flower

Using CSS vars

With the --card-image-max-size set to 50%, the image will never take more than 50% of the card's space.

<div style="max-width: 350px;">
  <ca-card fit="cover" style="--card-image-max-size: 50%">
    <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
    <article>
      <h3><a href="#">Using CSS vars</a></h3>
      <p>With the <code>--card-image-max-size</code> set to <code>50%</code>, the image will never take more than 50% of the card's space.</p>
    </article>
  </ca-card>
</div>

With interactive effects

The interactive attribute can set visual hover effects on the card.

Here we set it to interactive="links". This will raise the whole card when a link or button is hovered.

Half dome

Interactive hover on the links

When hovering a link, the whole card will rise.

<ca-card interactive="links" fit="cover" size="medium">
  <img src="https://live.staticflickr.com/5707/30956223351_b42f440856_o_d.jpg" width="300" height="200" alt="Half dome">
  <div>
    <h3><a href="#">Interactive hover on the links</a></h3>
    <p>When hovering a link, the whole card will rise.</p>
  </div>
</ca-card>

With interactive="full", we can make the whole card clickable.

Half dome

Fully clickable card

Through the magic of CSS, the whole card is now clickable.

<ca-card interactive="full" fit="cover" size="medium">
  <img src="https://live.staticflickr.com/5707/30956223351_b42f440856_o_d.jpg" width="300" height="200" alt="Half dome">
  <div>
    <h3><a href="#">Fully clickable card</a></h3>
    <p>Through the magic of CSS, the whole card is now clickable.</p>
  </div>
</ca-card>

With grid

Thus far, we've constrained our cards by sizing a parent div. But in many real-world use cases, we will be displaying many cards together, in list-like structures.

One way to do this is with our own ca-grid component.

Half dome

Grid card 1

Resize the window to see how the cards respond to changes in the grid.

California poppy flower

Grid card 2

Note how we can mix different fit attributes. The group still maintains the same card size.

Brown bear

Grid card 3

Let's throw in a pad too, for fun.

<ca-grid>
  <ca-card fit="cover" style="--card-image-max-size: 20rem">
    <img src="https://live.staticflickr.com/5707/30956223351_b42f440856_o_d.jpg" alt="Half dome">
    <div>
      <h3><a href="#">Grid card 1</a></h3>
      <p>Resize the window to see how the cards respond to changes in the grid.</p>
    </div>
  </ca-card>
  <ca-card fit="cover" style="--card-image-max-size: 20rem">
    <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
    <article>
      <h3><a href="#">Grid card 2</a></h3>
      <p>Note how we can mix different <code>fit</code> attributes. The group still maintains the same card size.</p>
    </article>
  </ca-card>
  <ca-card fit="cover" style="--card-image-max-size: 20rem">
    <img src="https://live.staticflickr.com/5609/15596534729_9c240ff83a_b.jpg" alt="Brown bear">
    <section>
      <h3><a href="#">Grid card 3</a></h3>
      <p>Let's throw in a <code>pad</code> too, for fun.</p>
    </section>
  </ca-card>
</ca-grid>

A card is nearly always displayed with friends, in a grid-like structure. We usually want every card to be the same size, nicely aligned.

Below, we use the ca-grid component's sizing capabilities to change the flow of all cards together.

Brown bear

Card heading

Lorem ipsum dolor sit amet, consectetur

Brown bear Brown bear Brown bear Brown bear
<!-- The --min-cell-inline-size variable is a function of the ca-grid component. -->
<ca-grid style="--min-cell-inline-size: 15rem;">
  <ca-card fit="cover">
    <img src="https://live.staticflickr.com/5609/15596534729_9c240ff83a_b.jpg" alt="Brown bear">
    <div>
      <h3><a href="#">Card heading</a></h3>
      <p>Lorem ipsum dolor sit amet, consectetur</p>
    </div>
  </ca-card>
  <ca-card fit="cover">
    <img src="https://live.staticflickr.com/5609/15596534729_9c240ff83a_b.jpg" alt="Brown bear">
    <article>
      <h3><a href="#">Card heading</a></h3>
      <p>Lorem ipsum dolor sit amet, consectetur</p>
    </article>
  </ca-card>
  <ca-card fit="cover">
    <img src="https://live.staticflickr.com/5609/15596534729_9c240ff83a_b.jpg" alt="Brown bear">
    <article>
      <h3><a href="#">Card heading</a></h3>
      <p>Lorem ipsum dolor sit amet, consectetur</p>
    </article>
  </ca-card>
  <ca-card fit="cover">
    <img src="https://live.staticflickr.com/5609/15596534729_9c240ff83a_b.jpg" alt="Brown bear">
    <article>
      <h3><a href="#">Card heading</a></h3>
      <p>Lorem ipsum dolor sit amet, consectetur</p>
    </article>
  </ca-card>
  <ca-card fit="cover">
    <img src="https://live.staticflickr.com/5609/15596534729_9c240ff83a_b.jpg" alt="Brown bear">
    <article>
      <h3><a href="#">Card heading</a></h3>
      <p>Lorem ipsum dolor sit amet, consectetur</p>
    </article>
  </ca-card>
</ca-grid>

With lists

Many scenarios call for cards to be displayed within a semantic ul or ol list. No problem.

<!-- Note our use of the grid class here. -->
<ul class="grid">
  <li>
    <ca-card fit="cover">
      <img src="https://live.staticflickr.com/5609/15596534729_9c240ff83a_b.jpg" alt="Brown bear">
      <article>
        <h3><a href="#">Card heading</a></h3>
        <p>Lorem ipsum dolor sit amet, consectetur</p>
      </article>
    </ca-card>
  </li>
  <li>
    <ca-card fit="cover">
      <img src="https://live.staticflickr.com/5707/30956223351_b42f440856_o_d.jpg" alt="Half dome">
      <article>
        <h3><a href="#">Card heading</a></h3>
        <p>Lorem ipsum dolor sit amet, consectetur</p>
      </article>
    </ca-card>
  </li>
  <li>
    <ca-card fit="cover">
      <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
      <article>
        <h3><a href="#">Card heading</a></h3>
        <p>Lorem ipsum dolor sit amet, consectetur</p>
      </article>
    </ca-card>
  </li>
</ul>

Without images

Images are optional in our cards.

Card heading

Lorem ipsum dolor sit amet, consectetur

Card heading

Lorem ipsum dolor sit amet, consectetur

<ca-grid>
  <ca-card>
    <!-- The content container (div, article, etc.) may be omitted when there's no image.-->
    <h3><a href="#">Card heading</a></h3>
    <p>Lorem ipsum dolor sit amet, consectetur</p>
  </ca-card>
  <ca-card>
    <h3><a href="#">Card heading</a></h3>
    <p>Lorem ipsum dolor sit amet, consectetur</p>
  </ca-card>
  <ca-card>
    <!-- But the content container will still work too. Here we use article. -->
    <article>
      <h3><a href="#">Card heading</a></h3>
      <p>Lorem ipsum dolor sit amet, consectetur</p>
    </article>
  </ca-card>
</ca-grid>

In horizontal orientation

Cards can be tipped over, placing images on the side instead.

Use the direction="horizontal" attribute.

California poppy flower

Using direction

The direction="horizontal" attribute puts the image on the side.

<ca-card direction="horizontal" fit="cover" image-min-size="small" size="large">
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
  <article>
    <h3><a href="#">Using direction</a></h3>
    <p>The <code>direction="horizontal"</code> attribute puts the image on the side.</p>
  </article>
</ca-card>

If horizontal direction is only desired on desktop, use direction="large:horizontal".

California poppy flower
<ca-card direction="large:horizontal" fit="cover" image-min-size="small" size="large">
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
  <article>
    <h3><a href="#">Using direction, responsive</a></h3>
    <p>The <code>direction="large:horizontal"</code> will switch the card back the vertical orientation on mobile.</p>
  </article>
</ca-card>

Flip image position

To put the image at the end of the card, just switch the position of the image element.

Flipping position

By changing the position of the img element, we we can put the image at bottom of the card.

California poppy flower
<ca-card fit="cover" size="medium">
  <article>
    <h3><a href="#">Flipping position</a></h3>
    <p>By changing the position of the <code>img</code> element, we we can put the image at bottom of the card.</p>
  </article>
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
</ca-card>

Works with horizontal cards too.

California poppy flower
<ca-card direction="large:horizontal" fit="cover" image-min-size="small" size="large">
  <article>
    <h3><a href="#">Flipping position, horizontal</a></h3>
    <p>We can put the image on the right in horizontal cards too.</p>
  </article>
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
</ca-card>

Jumbo card

Use as hero banner?

California poppy flower

Big card

Might be useful for featured content. There's no specific code for this. We can do this as a natural consequence of the way our cards size themselves.

<ca-card fit="cover" direction="large:horizontal" image-min-size="large">
  <img src="https://live.staticflickr.com/8628/16622486169_087756b818_b.jpg" alt="California poppy flower">
  <article>
    <h3><a href="#">Big card</a></h3>
    <p>Might be useful for featured content. There's no specific code for this. We can do this as a natural consequence of the way our cards size themselves.</p>
  </article>
</ca-card>