DEV Community

Cover image for Small Tips for Styling Card Components
Mads Stoumann
Mads Stoumann

Posted on

Small Tips for Styling Card Components

The other day, I stumbled upon an "About Us"-page for an agency, I used to work for. Not only were the team member images in irregular and different sizes — the grid had unnecessary many levels of <div>-soup:

DIV Soup

We can do better! A "team-member card" can be as simple as:

<div class="card">
  <img src="srj.jpg" alt="Samantha Richardson-Jackson" width="200" height="200" loading="lazy">
  <h2>Samantha Richardson-Jackson</h2>
  <small>Senior Digital Program & Project Manager</small>
</div>
Enter fullscreen mode Exit fullscreen mode

The CSS is a simple grid. We add a row-gap, align the content to start, and add an aspect-ratio to the image.

We then set a background-color on the image, so it looks nice while loading. I've chosen the system color GrayText, so it looks nice in both light and dark mode:

.card {
  align-content: start;
  display: grid;
  row-gap: 1ch;
  & h2 {
    line-height: 1.3;
    margin: 0;
    text-wrap: pretty;
  }
  & img {
    aspect-ratio: 1;
    background: GrayText;
    height: auto;
    object-fit: cover;
    width: 100%;
  }
}
Enter fullscreen mode Exit fullscreen mode

For the name, <h2>, we use the new text-wrap: pretty — and we get:

Simple Card

The job-title looks a bit unbalanced, let's add text-wrap: balance to it:

Text Wrap Blance

Now, let's add a wrapper — another grid — with auto-fill, so we don't need to worry about breakpoints and responsive design:

.card-grid {
  column-gap: 2em;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  row-gap: 3em;
}
Enter fullscreen mode Exit fullscreen mode

The grid will be filled with cards with a minimum width of 200px, which will automatically break to a new line, when the space has been used up:

Grid


Using subgrid

If you can live without the auto-fill, you can align the text in multiple cards using subgrid.

Add this to the .card CSS:

.card {
  grid-row: 1 / 4;
  grid-template-rows: subgrid;
}
Enter fullscreen mode Exit fullscreen mode

… and — voilà — the name and job title align:

Subgrid


Adding a background color

Without changing the markup, let's add a background-color and adjust the text accordingly:

.card {
  background: color-mix(in srgb, Canvas 90%, CanvasText 10%);
  & h2, small { padding-inline: .66rem; }
  & small { padding-block-end: 1rem; }
}
Enter fullscreen mode Exit fullscreen mode

Background

The color-mix blends two System Colors, so we don't have to do anything about dark mode:

Dark Mode


Rounded

If we want rounded borders, we can add border-radius: .5em:

Border Radius

— But that doesn't seem to work for the image … we need to set:

.card {
  border-radius: .5em;
  & img {
    border-start-start-radius: inherit;
    border-start-end-radius: inherit;
  }
}
Enter fullscreen mode Exit fullscreen mode

OR we can use clip-path:

.card {
  clip-path: inset(0 round .5em);
}
Enter fullscreen mode Exit fullscreen mode

Border Radius and clippath

The result is the same, but clip-path will also cut off box-shadows and borders, should you need them.

And that concludes this tutorial! As you can see, a card-component can be super simple, with a lot of flexibility through the power of CSS grids.


Demo

Here's a CodePen. Open it in full and resize to see auto-fill in action. The last four cards have background-color, the final two border-radius:


All team member images by ThisPersonDoesNotExist — names by chatGPT.

Top comments (2)

Collapse
 
anthitariel profile image
Anfisa Domashova

Nife job, Mads. I like your approach. 👍

Collapse
 
madsstoumann profile image
Mads Stoumann

Thanks!