Elevate hover/focus effect - multiple transitions
<div class="repos">
<li class="card" tabindex="0">
<h3>Fetching</h3>
<img class="logo" src="img/fetching.webp" alt="Fetching logo">
<p>A collection of *fetching* unicode art for the terminal.</p>
<div class="language language-shell">Shell</div>
<div class="stars">
<img src="img/star.svg" alt="stars" eleventy:ignore />
<div class="count">173k</div>
</div>
</li>
<li class="card" tabindex="0">
<h3>Snippets Ranger</h3>
<img class="logo" src="img/snippets-ranger.svg" alt="Snippets Ranger logo" width="1600" style="aspect-ratio: 400 / 400;" loading="eager" decoding="async" eleventy:ignore>
<p>View and edit all of your snippets in one purty place! Yee-haw!!</p>
<div class="language language-javascript">JavaScript</div>
<div class="stars">
<img src="img/star.svg" alt="stars" eleventy:ignore />
<div class="count">105k</div>
</div>
</li>
</div> :root {
--color-text: hsl(0, 0%, 95%);
--color-border: hsl(220deg 12% 40%);
--color-background: hsl(0, 0%, 6%);
--color-card-background: hsl(0, 0%, 10%);
--color-card-background-focused: hsl(0, 0%, 16%);
}
* {
box-sizing: border-box;
}
body {
height: 100dvh;
margin: 0;
background-color: var(--color-background);
color: var(--color-text);
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
font-size: 1.1rem;
display: grid;
place-items: center;
}
.repos {
width: 88%;
max-width: 600px;
display: flex;
flex-direction: column;
gap: 2rem;
list-style-type: none;
}
.card {
background-color: var(--color-card-background);
--ease-bounce-2: linear(
0,
0.004,
0.016,
0.035,
0.063,
0.098,
0.141 15.1%,
0.25,
0.391,
0.562,
0.765,
1,
0.892 45.2%,
0.849,
0.815,
0.788,
0.769,
0.757,
0.753,
0.757,
0.769,
0.788,
0.815,
0.85,
0.892 75.2%,
1 80.2%,
0.973,
0.954,
0.943,
0.939,
0.943,
0.954,
0.973,
1
);
transition: background-color 300ms ease-in, scale 400ms var(--ease-bounce-2);
width: 100%;
height: min-content;
padding: 1.5rem 0.75rem;
display: grid;
grid-template-columns: min-content auto 1fr;
grid-template-rows: repeat(3, min-content);
column-gap: 0.75rem;
row-gap: 1rem;
border: 0.1rem solid var(--color-border);
border-radius: 0.25rem;
h3 {
margin: 0;
font-size: 1.3rem;
grid-column: span 2;
}
p {
margin: 0;
grid-column: 2 / -1;
}
.logo {
--size: 3.5em;
width: var(--size);
height: var(--size);
grid-column: 1;
grid-row: 1 / -1;
align-self: center;
border-radius: inherit;
aspect-ratio: 1 / 1;
filter: saturate(0);
transition: filter 300ms ease-in-out;
}
.language {
grid-column: 2;
font-size: 0.9em;
}
/* circle marker */
.language::before {
content: "";
display: inline-block;
width: 0.5em;
margin: 0.1em 0;
margin-inline-end: 0.4em;
aspect-ratio: 1/1;
vertical-align: baseline;
border-radius: 50%;
background-color: var(--color-text);
filter: saturate(0.4);
transition: filter 300ms ease-in-out;
}
.language-javascript::before {
background-color: hsl(53deg 84% 65%);
}
.language-shell::before {
background-color: hsl(97deg 70% 60%);
}
.stars {
grid-column: 3;
display: flex;
flex-direction: row;
align-items: center;
gap: 0.2rem;
img {
width: 1.1rem;
aspect-ratio: 1 / 1;
padding-block-end: 0.1rem;
}
.count {
font-size: 0.9em;
}
}
}
.card:where(:hover, :focus-visible) {
background-color: var(--color-card-background-focused);
scale: 1.1;
.logo {
filter: saturate(1);
}
.language::before {
filter: saturate(1);
}
} Description
Using transitions on multiple elements in hover/focus effects can create more nuanced and beautiful effects. This demo has cards that when they are hovered over or recieve focus, they pop up and brighten up. The card is scaled up and its background color changes, the image and the circle marker for the language change are saturated fully from a desaturated state.
The effect uses the :hover and :focus-visible pseudo-classes to change the appearance of the card when it is interacted with. I made the card a focusable element by adding tabindex="0", for purposes of this demo only. Usually, a card has a link that serves in this capacity. I excluded links to avoid errant clicks/taps navigating away from the demo, which can be frustrating when you play with it!
I discuss the code in more detail in this article.