Carmen Ansio PRO
Design Engineer at LottieFiles
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
button:hover {
transform: scale(1.2);
}
@carmenansio
@carmenansio
@carmenansio
<a href="https://es.wikipedia.org/wiki/The_Legend_of_Zelda:_The_Wind_Waker" alt="Zelda Wind Waker card" target="_blank">
<div class="card">
<div class="wrapper">
<img src="https://assets.codepen.io/527512/zelda_cover-image.webp" class="cover-image" />
</div>
<img src="https://assets.codepen.io/527512/zelda_title.webp" class="title" />
<img src="https://assets.codepen.io/527512/zelda_character.webp" class="character" />
</div>
</a>
@carmenansio
@carmenansio
:root {
--card-height: 300px;
--card-width: calc(var(--card-height) / 1.5);
}
@carmenansio
.card {
width: var(--card-width);
height: var(--card-height);
perspective: 2500px;
}
@carmenansio
.wrapper {
transition: all 0.5s;
position: absolute;
z-index: -1;
}
.card:hover .wrapper {
transform: perspective(900px) translateY(-5%) rotateX(25deg);
box-shadow: 2px 35px 32px -8px rgba(0, 0, 0, 0.75);
}
@carmenansio
.card:hover .title {
transform: translate3d(0%, -50px, 100px);
}
.card:hover .character {
opacity: 1;
transform: translate3d(0%, -30%, 100px);
}
@carmenansio
@carmenansio
@carmenansio
<p>
Design
<span>Design</span>
<span>Design</span>
<span>Engineer</span>
</p>
@carmenansio
@carmenansio
.card:has(button:hover) {
transform: scale(1.02);
}
:has()
= contextual motion@carmenansio
@carmenansio
@property --glow {
syntax: "<color>";
inherits: true;
initial-value: transparent;
}
@layer
+ @property
= smoother control@carmenansio
@carmenansio
nav a:nth-child(1) { transition-delay: 0ms; }
nav a:nth-child(2) { transition-delay: 50ms; }
nav a:nth-child(3) { transition-delay: 100ms; }
@carmenansio
@carmenansio
transition: all 0.4s cubic-bezier(.33, 1, .68, 1);
@carmenansio
@carmenansio
.card {
width: 200px;
height: 300px;
background: linear-gradient(45deg, #ff6b6b, #ffde59);
transition: transform 0.6s cubic-bezier(0.25, 1, 0.5, 1), background 0.4s ease,
box-shadow 0.4s ease;
cursor: pointer;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
@carmenansio
@carmenansio
a hover effect on the image (with :has()
)
a subtle background shift when the card becomes :focus-within
a transition-delay
to let text fade in just a touch later
@carmenansio
@carmenansio
@carmenansio
<article class="blog-card">
<div class="gradient-border"></div>
<div class="card-content">
<figure class="image-container">
<img src="..." alt="The Future of AI" />
</figure>
<section class="content">
<header class="content-text">
<h2>Title</h2>
<p>Description</p>
</header>
<footer class="card-footer">
<span class="author">John Doe</span>
<div class="arrow-container">
<svg class="arrow-icon">...</svg>
</div>
</footer>
</section>
</div>
</article>
@carmenansio
.gradient-border {
position: absolute;
inset: 0;
z-index: 0;
border-radius: 24px;
background: linear-gradient(45deg, var(--gradient-1), var(--gradient-2), var(--gradient-3), var(--gradient-4));
background-size: 300% 300%;
opacity: 0;
transition: opacity 0.3s ease;
}
.blog-card:hover .gradient-border {
opacity: 1;
animation: gradientFlow 3s linear infinite;
}
@carmenansio
.image-container img {
transition: transform 0.5s ease;
}
.blog-card:hover .image-container img {
transform: scale(1.05);
}
@carmenansio
.author {
background: linear-gradient(to right, #92ff38, #e5ff00);
-webkit-background-clip: text;
color: transparent;
}
.arrow-container, .arrow-icon {
transition: all 0.3s ease;
}
.blog-card:hover .arrow-container {
border-color: #92ff38;
}
.blog-card:hover .arrow-icon {
color: #92ff38;
}
@carmenansio
@carmenansio
@carmenansio
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #222;
}
.box {
position: relative;
width: 400px;
height: 300px;
}
@carmenansio
.box::before,
.box::after {
content: "";
position: absolute;
inset: 0;
background: repeating-conic-gradient(
from var(--a),
#0f0, #ff0, #0ff, #f0f, #0ff
);
animation: rotating 4s linear infinite;
border-radius: 20px;
}
.box::after {
filter: blur(40px);
opacity: 0.75;
}
@carmenansio
@property --a {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@keyframes rotating {
0% { --a: 0deg; }
100% { --a: 360deg; }
}
@carmenansio
@carmenansio
@carmenansio
body {
background: #0e1217;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
@carmenansio
.button.border {
box-shadow: inset 0 0 0 2px #fff;
position: relative;
color: #fff;
}
@carmenansio
.border::before,
.border::after {
position: absolute;
width: 0;
height: 0;
border: 0 solid transparent;
content: "";
}
.border:hover::before,
.border:hover::after {
border-color: #16bdca;
width: 100%;
height: 100%;
}
@carmenansio
Better performance
Fewer dependencies
More accessible interactions
Less JS to maintain
@carmenansio
@carmenansio
@carmenansio
@carmenansio
.fade-in {
opacity: 1;
transition: opacity 0.5s;
@starting-style {
opacity: 0;
}
}
@starting-style
@carmenansio
button {
translate: 0 0;
scale: 1;
rotate: 0deg;
transition: scale 0.3s ease,
rotate 0.5s ease;
}
button:hover {
scale: 1.2;
rotate: 10deg;
}
translate
, scale
, rotate
@carmenansio
@carmenansio
.box {
transform: translateX(0);
transition: transform 2s linear(
0, 0.03, 0.15 5%, 0.45, 0.82 15%, 1.05, 1
);
}
.box:hover {
transform: translateX(100px);
}
@carmenansio
.section {
animation: fadeMove 1s ease forwards;
animation-timeline: view();
}
@keyframes fadeMove {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@carmenansio
@carmenansio
@carmenansio
li {
height: 0;
transition: height 0.3s ease;
}
li.open {
height: calc-size(auto);
}
@carmenansio
@carmenansio
html,
body {
display: grid;
min-height: 100%;
background: #121212;
}
.wrap {
--d: clamp(5em, 16vw, 15em);
place-self: center;
overflow-x: scroll;
scroll-snap-type: x mandatory;
padding: var(--d) 0;
max-width: calc(6 * var(--d));
perspective: calc(3 * var(--d));
white-space: nowrap;
scrollbar-color: crimson #212121;
}
@carmenansio
.move {
display: inline-block;
transform-style: preserve-3d;
}
figure {
display: inline-block;
scroll-snap-align: center;
margin: 0;
transform-style: preserve-3d;
}
img {
width: var(--d);
aspect-ratio: 1;
-webkit-box-reflect: below 0.5em linear-gradient(#0000, #0004);
animation: ry 1s cubic-bezier(0.32, 0, 0.68, 0) both,
tz 1s ease-in both;
animation-timeline: view(inline);
}
@carmenansio
@keyframes ry {
0% {
rotate: y -90deg;
}
50% {
rotate: y 0deg;
animation-timing-function: cubic-bezier(0.32, 1, 0.68, 1);
}
100% {
rotate: y 90deg;
}
}
@keyframes tz {
0% {
translate: -50% 0;
}
50% {
translate: 0 0 calc(1.5 * var(--d));
animation-timing-function: ease-out;
}
100% {
translate: 50% 0;
}
}
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
@carmenansio
By Carmen Ansio
Pre CSS Day 2025 Meetup