Focus Dim Siblings

Hovering one card lifts it slightly while the others fade and soften, so attention lands on a single choice.

  • CSS
  • Cards
  • Hover
  • Added

AI prompt

Create a card group where hovering one card dims its siblings, in pure CSS. Lay out three cards in a grid. Use :has() on the group: .group:has(.card:hover) .card:not(:hover) gets opacity 0.4, scale(0.97), and a 1px blur, while the hovered card gets translateY(-4px) and a stronger border. Do the same for :focus-within so keyboard focus behaves identically. Transition opacity, transform, and filter over 260ms with cubic-bezier(0.16, 1, 0.3, 1). Make each card a link or button so it can be focused. Under prefers-reduced-motion, keep the dimming but drop the scale, lift, and blur. The cards read "Starter", "Studio", and "Team".

Source

Demo.tsx
'use client'

import s from './demo.module.css'

export default function FocusDim({ labels }: { labels: Record<string, string> }) {
  const plans = [
    { name: labels.a, price: 0 },
    { name: labels.b, price: 12 },
    { name: labels.c, price: 29 },
  ]

  return (
    <div className={s.group}>
      {plans.map((p) => (
        <a key={p.name} href="#" className={s.card} onClick={(e) => e.preventDefault()}>
          <span className={s.name}>{p.name}</span>
          <span className={s.price}>${p.price}</span>
          <span className={s.per}>{labels.price}</span>
        </a>
      ))}
    </div>
  )
}
demo.module.css
.group {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  width: min(330px, 100%);
}

.card {
  display: grid;
  gap: 4px;
  padding: 14px 12px;
  border: 1px solid var(--stage-rule);
  border-radius: 12px;
  background: var(--stage-surface);
  color: var(--stage-ink);
  text-decoration: none;
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out), filter 260ms var(--ease-out), border-color 260ms;
}

.card:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

.group:has(.card:hover) .card:not(:hover),
.group:has(.card:focus-visible) .card:not(:focus-visible) {
  opacity: 0.4;
  transform: scale(0.97);
  filter: blur(1px);
}

.card:hover,
.card:focus-visible { transform: translateY(-4px); border-color: var(--stage-accent); }

.name { font: 500 var(--text-xs) / 1.2 var(--font-body); color: var(--stage-muted); }
.price { font: 700 var(--text-2xl) / 1 var(--font-display); }
.per { font: 500 0.625rem / 1 var(--font-mono); color: var(--stage-muted); text-transform: uppercase; }

@media (prefers-reduced-motion: reduce) {
  .card, .card:hover, .card:focus-visible,
  .group:has(.card:hover) .card:not(:hover),
  .group:has(.card:focus-visible) .card:not(:focus-visible) { transform: none; filter: none; }
}

Suggest an idea

Seen a motion or a theme you would like to find here? Describe it, and it opens as a prefilled GitHub issue for you to post.

What are you suggesting?

Needs a GitHub account. Suggestions are public.