CSS Transforms & Animation Reference Notes

Just a guy who loves to write code and watch anime.
Transform Properties
Traditional Chained Transforms
.element {
transform: translateY(10px) rotate(45deg) scale(1.2);
transform-origin: center; /* or specific coordinates like 12px 7px */
}
Individual Transform Properties
.element {
translate: 10px 20px; /* x y values */
rotate: 45deg;
scale: 1.2; /* or 1.2 1.5 for x y */
transform-origin: 12px 7px;
}
Key Difference: Individual properties don't cascade coordinate systems!
Transform-Origin Deep Dive
The Coordinate System Rule
transform-originuses the same coordinate system as your SVG/elementFor SVG lines: use the actual
x1, y1, x2, y2coordinate valuesNot some separate CSS coordinate system
Examples
<!-- SVG with viewBox="0 0 24 24" -->
<line x1="4" y1="7" x2="20" y2="7" /> <!-- Top line -->
<line x1="4" y1="12" x2="20" y2="12" /> <!-- Middle line -->
<line x1="4" y1="17" x2="20" y2="17" /> <!-- Bottom line -->
.top-line {
transform-origin: 12px 7px; /* SVG center-x, line's actual y */
}
.middle-line {
transform-origin: 12px 12px; /* SVG center-x, line's actual y */
}
.bottom-line {
transform-origin: 12px 17px; /* SVG center-x, line's actual y */
}
Result: All lines rotate around the visual center (12,12) of the SVG
Chained Transform Gotcha
/* ❌ Confusing -> coordinate system shifts */
.element {
transform: translateY(5px) rotate(45deg);
transform-origin: 12px 7px; /* Must account for the translate! */
}
/* ✅ Intuitive -> no coordinate cascading */
.element {
translate: 0 5px;
rotate: 45deg;
transform-origin: 12px 12px; /* Works as expected */
}
Sequenced Animations
Using Transitions with Individual Properties
.element {
transition-property: translate, rotate;
transition-duration: 0.2s, 0.2s;
transition-delay: 0s, 0.2s; /* translate first, then rotate */
}
.element.active {
translate: 0 5px;
rotate: 45deg;
transition-delay: 0.2s, 0s; /* reverse: rotate first, then translate */
}
Using Keyframes (Often Cleaner)
@keyframes open-animation {
40% {
translate: 0 5px;
} /* move first */
100% {
translate: 0 5px;
rotate: 45deg;
} /* then rotate */
}
@keyframes close-animation {
0% {
translate: 0 5px;
rotate: 45deg;
}
60% {
translate: 0 5px;
} /* rotate back first */
100% {
translate: 0 0;
} /* then move back */
}
CSS Attribute Selectors
State-Based Styling
/* Target elements by attribute values */
button[aria-pressed="true"] .icon {
rotate: 180deg;
}
input[type="email"] {
border: 2px solid blue;
}
div[data-state="loading"] {
opacity: 0.5;
}
Common Patterns
[hidden] {
display: none;
}
[disabled] {
opacity: 0.5;
}
[aria-expanded="true"] .chevron {
rotate: 180deg;
}
Common Patterns
Burger Menu Animation
.burger-line {
transition-property: translate, rotate;
transition-duration: 0.3s;
transition-delay: 0.15s, 0s; /* for closing: rotate first, then translate */
}
.burger.open .top-line {
translate: 0 5px;
rotate: 45deg;
transition-delay: 0s, 0.15s; /* for opening: translate first, then rotate */
transform-origin: 12px 7px; /* where the line actually sits */
}
.burger.open .bottom-line {
translate: 0 -5px;
rotate: -45deg;
transition-delay: 0s, 0.15s;
transform-origin: 12px 17px; /* where the line actually sits */
}
Hover Effects
.card {
translate: 0 0;
scale: 1;
transition: translate 0.2s, scale 0.2s;
}
.card:hover {
translate: 0 -4px;
scale: 1.02;
}
Pro Tips
Individual properties are usually cleaner for complex animations
Transform-origin coordinates match your SVG/element coordinates -> not CSS pixels
Keyframes give you full control over sequenced animations
Attribute selectors are powerful for state-based styling
Always test both directions of your animations (open/close, hover/unhover)






