Site icon Ampersand Tutorials

Materialize CSS Cards: Layouts, Hover and Elevation

Quick answer: A Materialize card is a div.card containing card-image (media), card-content (title and text) and card-action (links) — the framework supplies the white surface, rounded corners and hover elevation, you supply the content. Responsive card grids need no custom CSS: wrap cards in a row and give each a col s12 m6 l4 so they stack on phones, sit two-across on tablets and three-across on desktops. The three customizations you will actually want — hover lift, gradient overlays and responsive image ratios — are shown below with copy-paste code.

The anatomy of a Materialize card

<div class="card">
  <div class="card-image">
    <img src="photo.jpg">
    <a class="btn-floating halfway-above waves-effect waves-light red">
      <i class="material-icons">favorite</i>
    </a>
  </div>
  <div class="card-content">
    <span class="card-title">Card Title</span>
    <p>Everything inside card-content gets the framework's padding and typography.</p>
  </div>
  <div class="card-action">
    <a href="#">First link</a>
    <a href="#">Second link</a>
  </div>
</div>

Each region has one job: card-image bleeds media to the card edges and hosts the floating action button, card-content carries the padded text block, and card-action is the flat footer strip for links. You never need all three — a text-only card is just card-content, and all three together is the classic blog-card pattern above.

Responsive card grids without custom CSS

Cards become a grid through the standard 12-column system: each card takes a column class, and the breakpoints do the stacking. This is the pattern from the grid system guide, applied to cards — if you have not built a Materialize page yet, the Materialize CSS tutorial gets you to this point in one afternoon:

Classes per cardPhone (<600px)Tablet (600–992px)Desktop (>992px)
col s12 m6 l41 per row2 per row3 per row
col s12 m41 per row3 per row3 per row
col s12 m6 l31 per row2 per row4 per row
col s62 per row2 per row2 per row
<div class="row">
  <div class="col s12 m6 l4">
    <div class="card"> ... </div>
  </div>
  <div class="col s12 m6 l4">
    <div class="card"> ... </div>
  </div>
  <div class="col s12 m6 l4">
    <div class="card"> ... </div>
  </div>
</div>

The three customizations worth stealing

1. Hover lift with deeper shadow. Materialize’s hoverable class adds the lift in one word — put it on the card: <div class="card hoverable">. The shadow grows from the default elevation to a higher one, which is the framework doing its own design system rather than you inventing one.

2. Image titles over a gradient. White text on a photo needs a scrim. Overlay a gradient from transparent to black at 70% opacity and place the title in card-content with negative top margin — this is exactly what the gradient color cards recipe does, and it keeps text readable over any image.

3. Consistent image ratios. Cards in a row look ragged when images have different heights. Force uniformity with a fixed height and object-fit:

.card-image img {
  height: 200px;
  object-fit: cover; /* crops instead of squashing */
}

Card variants and when to use them

VariantClassesUse it for
StandardcardDefault: white surface, subtle shadow
Horizontalcard horizontalImage left, content right — article teasers on narrow lists
Smallcard smallTight spaces where the title dominates the media
Medium / Large imagecard medium / largeMedia-first cards for galleries and portfolios
Sticky actioncard sticky-actionAction button pinned to the card footer, separate from content
Panelcard-panelFlat, edge-to-edge info block — dashboards, callouts, no hover

card-panel is the one people confuse with card: it has no image region, no radius emphasis and no hover elevation — it is a surface, not an object. Use it for statistics strips and notices; use card for anything with a title, media or links. For click feedback on the whole card, add waves-effect to the container so taps ripple across the surface, and see the card animation guide for scroll-in entrance effects.

The fastest way to internalize this is to rebuild a real layout — a pricing page or article feed — from cards alone. That is how Ampersand Academy teaches front-end development one-to-one: you build, someone experienced reviews every line, and the grid finally clicks.

Frequently asked questions

How do I make Materialize cards equal height?

Cards inside the same row flex to equal height automatically because the row uses flexbox. The common fix for ragged looks is the image, not the card — set a fixed height with object-fit cover on card-image so every card starts evenly.

How do I put a card in a 3-column grid?

Wrap each card in a row div and give each wrapper col s12 m6 l4. On desktop you get three cards per row, two on tablets and one per row on phones, with no media queries of your own.

Why is my Materialize card image too tall?

Images render at their natural height unless constrained. Add height with object-fit cover to card-image img so the image crops to your box instead of stretching it.

What is the difference between card and card-panel?

card is an object: radius, image regions, hover elevation. card-panel is a flat surface: no image area, no hover, edge-to-edge padding — meant for dashboards, stats and callouts rather than repeated content items.

How do I make a whole card clickable?

Wrap the card in an anchor or attach a click handler to the card div, and add waves-effect for tap feedback. Keep the inner card-action links stop-propagation if the outer card also navigates.

Exit mobile version