DEV Community

Mohamed Idris
Mohamed Idris

Posted on

Dim Other Cards on Hover with Pure CSS

You've probably seen this effect before — you hover over one card, and all the other cards fade out a little, making the hovered one stand out.

Before hover:             While hovering card B:

┌──────┐ ┌──────┐ ┌──────┐     ┌──────┐ ┌──────┐ ┌──────┐
│  A   │ │  B   │ │  C   │     │  A   │ │  B   │ │  C   │
└──────┘ └──────┘ └──────┘     └──────┘ └──────┘ └──────┘
 100%     100%     100%          dim      bright    dim
Enter fullscreen mode Exit fullscreen mode

It's clean, it draws attention to the right place, and it takes about 5 lines of CSS.

The HTML

Nothing special here — a wrapper div and some cards inside it.

<div class="cards">
  <div class="card">Card A</div>
  <div class="card">Card B</div>
  <div class="card">Card C</div>
</div>
Enter fullscreen mode Exit fullscreen mode

The CSS

.cards:has(.card:hover) .card:not(:hover) {
  opacity: 0.5;
}
Enter fullscreen mode Exit fullscreen mode

That's it. Let's break it down:

  • .cards:has(.card:hover) — targets the wrapper when any card inside it is being hovered
  • .card:not(:hover) — selects all cards except the one being hovered
  • opacity: 0.5 — dims them

So in plain English: "If something inside .cards is hovered, dim every .card that isn't the hovered one."

Add a smooth transition

The snap between full and dimmed opacity can feel abrupt. Add a transition to the cards:

.card {
  transition: opacity 0.3s ease;
}

.cards:has(.card:hover) .card:not(:hover) {
  opacity: 0.5;
}
Enter fullscreen mode Exit fullscreen mode

Now it fades in and out smoothly.

Works across columns too

This approach works even when your cards are split across multiple columns (like a masonry layout), because the selector targets by class anywhere inside the wrapper — not just direct children.

<div class="cards">
  <div class="column">
    <div class="card">Card A</div>
    <div class="card">Card C</div>
  </div>
  <div class="column">
    <div class="card">Card B</div>
    <div class="card">Card D</div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

The same CSS still works — hover card A, and B, C, D all dim regardless of which column they're in.

Browser support

The :has() selector is supported in all modern browsers. Just keep in mind it doesn't work in Firefox versions before 121 or older browsers, so add a graceful fallback if you need wide coverage (e.g. just skip the effect entirely for those browsers — it's purely visual).


Simple, no JavaScript, no extra libraries. Just CSS doing what it's good at.

Top comments (0)