Cards are quickly becoming a “goto” UI pattern, particularly on the mobile web. This is, in part, thanks to mainstream websites, such as Pinterest, Twitter, and Google Now featuring cards heavily. On Tuts+ you’ll also find courses and the the latest posts across the network on the front page using the card pattern.

In this tutorial, we are going to look into the cards component in Material Design Lite (MDL). According to the Material Design specification, a card is:
“A piece of paper with unique related data, that serves as an entry point to more detailed information.
A card may contain text, an image, a combination of both, and may also include other MDL components. In the context of the web we generally make use of a card interface to display lists of blog posts, news, videos, products and so on.
As ever in this series, before we are able to implement anything, we need to load the MDL libraries—the stylesheets and the JavaScript—in the head
of an HTML document.
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"><link href='http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,500,400italic,700,700italic' rel='stylesheet' type='text/css'><link rel="stylesheet" href="//storage.googleapis.com/code.getmdl.io/1.0.1/material.teal-red.min.css" /><script src="//storage.googleapis.com/code.getmdl.io/1.0.1/material.min.js"></script>
Once we have these files in place, we can start building the cards.
Go!
To create a Card, we start with a div
with the mdl-card
class, then the mdl-shadow--2dp
class to apply drop shadows to the card. Change the mdl-shadow--2dp
class number to 3, 4, 6, 8, or 16 to increase the shadow depth and spread as needed.
<div class="mdl-card mdl-shadow--2dp"></div>
As yet, the Card width is undefined. We can either set the width through CSS ourselves, or apply it in conjunction with the MDL grid component. I would our demo card to be responsive and tightly integrated with the MDL ecosystem, so we’ll opt for the latter. We wrap the mdl-card
with a grid container and set the card itself as the grid cell or column.
<div class="mdl-grid"><div class="mdl-card mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-shadow--2dp"></div></div>
Card Content
Now we need to determine the content. Let’s assume we want to use the card to display a blog post. Traditionally, this might consist of the post featured image, the post title, the excerpt, and a typical “Read More” button pointing to the full content.
We’ll begin with the title. To add one, create an empty div
with the mdl-card__title
class.
<div class="mdl-grid"><div class="mdl-card mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-shadow--2dp"><div class="mdl-card__title"></div></div></div>
Add a heading within the div
and apply the mdl-card__title-text
class; depending on your page structure and the content level of the card, you may add an h1
to h6
.
<div class="mdl-grid"><div class="mdl-card mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-shadow--2dp"><div class="mdl-card__title"><h2 class="mdl-card__title-text">Learning Web Design</h2></div></div></div>
Let’s now add the post excerpt—the summary of the post content. For that, we create another div
below the title container and apply the mdl-card__supporting-text
class. Then, wrap the excerpt with a paragraph element and add it within the div
.
<div class="mdl-grid"><div class="mdl-card mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-shadow--2dp"><div class="mdl-card__title"><h1 class="mdl-card__title-text">Learning Web Design</h1></div><div class="mdl-card__supporting-text"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam accusamus, consectetur.</p></div></div></div>
For the post featured image, we need to create another containing element (we’ll go for a figure
) above the title container, with the mdl-card__media
class. figure elements have some margin set by default, so let’s manually override that, like so:
.mdl-card__media { margin: 0; }
Finally, add an image.
...<div class="mdl-card mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-shadow--2dp"><figure class="mdl-card__media"><img src="/images/laptop.jpg" alt="" /></figure><div class="mdl-card__title"><h1 class="mdl-card__title-text">Learning Web Design</h1></div><div class="mdl-card__supporting-text"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam accusamus, consectetur.</p></div></div> ...
By default, MDL will not resize the image within the card media container. As the card is resized, the image width and the height is persistent. The media container is set to hide the overflowing image.
Lastly, the image is disproportionately tall, which doesn’t make the card look great.

If we want the image to resize, following the container, while keeping its ratio, we will need to add a few styles, setting the image max-width
to 100%
.
.mdl-card__media > img { max-width: 100%; }
The Card Action
A card should ideally contain an action relating to the card content. If the card is a tweet, for example, it may have a Retweet and a Follow button. Since our card is used to display a blog post, we will add a Read More button pointing to the full content of the post, along with a couple of buttons to like and share the post . We add these action buttons below the post excerpt, wrapped within a new div
with the mdl-card__actions
.
...<div class="mdl-card mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-shadow--2dp"><figure class="mdl-card__media"><img src="http://tfirdaus.github.io/mdl/images/laptop.jpg" alt="" /></figure><div class="mdl-card__title"><h1 class="mdl-card__title-text">Learning Web Design</h1></div><div class="mdl-card__supporting-text"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam accusamus, consectetur.</p></div><div class="mdl-card__actions mdl-card--border"><a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">Read More</a><div class="mdl-layout-spacer"></div><button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">favorite</i></button><button class="mdl-button mdl-button--icon mdl-button--colored"><i class="material-icons">share</i></button></div></div> ...
Note: MDL does not come with pre-defined styles that cover this scenario where we have three buttons in the Card action container. So we need to add a few more styles to properly align these buttons.
.mdl-card__actions { display: flex; box-sizing:border-box; align-items: center; } .mdl-card__actions > .mdl-button--icon { margin-right: 3px; margin-left: 3px; }
Now, add a few more cards to create a list of posts:
Wrapping Up
Displaying multiple blog posts is one of the most popular implementations of the card interface on websites. Saying that, the card component can actually be adapted to display any type of content, even a single image, a calendar widget, or maybe weather information.

However, the standard classes in the component specification do not include all styles for those specific scenarios. Be prepared to add custom class names and some extra style rules to customize the card appearance as per your needs. Let us see in the comments what you achieve!