CSCI 4513 - Advanced Web Programming
Week 8, Lecture 16
Key Benefit: Transforms occur during composition phase
This makes them cheaper and more performant than many other CSS properties
Hardware Accelerated: Transforms can use the device's GPU for better performance
The transform property takes CSS transform functions as values
.element {
transform: rotate(45deg);
transform: scale(1.5);
transform: translate(100px, 50px);
}
⚠️ Cannot be applied to:
.element {
transform: rotate(45deg);
}
Original
Rotated
Positive values = clockwise, Negative values = counter-clockwise
.element {
transform: scaleX(1.5); /* Scale width only */
transform: scaleY(0.5); /* Scale height only */
transform: scale(2); /* Scale both uniformly */
}
1x
1.5x
.element {
transform: translateX(50px); /* Move right */
transform: translateY(-30px); /* Move up */
transform: translate(50px, -30px); /* Both */
}
💡 Tip: Translate moves the element without affecting document flow
Unlike margin or position, other elements don't shift to fill the space
.element {
transform: skewX(20deg); /* Skew horizontally */
transform: skewY(10deg); /* Skew vertically */
transform: skew(20deg, 10deg); /* Both */
}
Original
Skewed
Add multiple transform functions separated by spaces
.red-box {
transform: rotate(45deg) translate(200%);
}
.blue-box {
transform: translate(200%) rotate(45deg);
}
⚠️ Order Matters!
Transforms are applied from right to left
The red box translates first, then rotates around the origin
The blue box rotates in place, then translates
Sets the distance from the user to the z = 0 plane
.element {
transform: perspective(500px) rotateY(45deg);
}
Critical Rule: perspective must be declared first (leftmost) when chaining transforms
Think of it like this: Perspective tells the browser "render as if we're viewing from this distance"
.element {
transform: rotateX(45deg); /* Rotate on X-axis */
transform: rotateY(45deg); /* Rotate on Y-axis */
transform: rotateZ(45deg); /* Same as rotate() */
transform: rotate3d(1, 1, 0, 45deg); /* Custom axis */
}
Remember: Without perspective, 3D transforms won't look 3D!
Best Practice: Stick to transform and opacity for animations when performance matters
Transitions animate changes from an element's initial state to an end state
button {
background: white;
transition: background-color 0.5s ease;
}
button:hover {
background: black;
}
button {
transition-property: background-color;
transition-duration: 1s;
transition-timing-function: ease-out;
transition-delay: 0.25s;
}
/* Shorthand */
button {
transition: background-color 1s ease-out 0.25s;
}
transition-property: What CSS property to transition
transition-duration: How long the transition takes
transition-timing-function: Speed curve (ease, linear, ease-in, ease-out)
transition-delay: Delay before transition starts
Transitions require a trigger to start
// JavaScript trigger example
button.addEventListener('click', () => {
dropdown.classList.add('open'); // Triggers transition
});
Definition: 3D conceptualization of HTML elements along the z-axis (depth dimension)
z-index controls how far back or forward an element appears
But z-index only works within a stacking context!
Several CSS properties create new stacking contexts:
⚠️ Performance Impact: Multiple stacking contexts can cause repaints of all stacked elements during transitions
<article id="container3"> <!-- z-index: 4 -->
<section id="container4"> <!-- z-index: 6 -->
<section id="container5"> <!-- z-index: 1 -->
</article>
Think of z-index values as "version numbers":
Section #5 (4.1) stacks above Section #4 (4.6) within their parent,
but Article #3 (4.x) as a whole stacks based on its parent's context!
Best Practice: Test transitions in browser DevTools performance tab
Animations provide more control than transitions
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-50px); }
}
.ball {
animation: bounce 2s infinite;
}
Use transitions for: Hover effects, focus states, simple state changes
Use animations for: Complex sequences, loading spinners, continuous effects
.element {
animation-name: slide-in;
animation-duration: 2s;
animation-timing-function: ease-in-out;
animation-delay: 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-fill-mode: forwards;
}
/* Shorthand */
.element {
animation: slide-in 2s ease-in-out 0.5s infinite alternate forwards;
}
animation-name: References @keyframes name
animation-duration: How long one cycle takes
animation-timing-function: Speed curve (ease, linear, etc.)
animation-delay: Wait time before starting
animation-iteration-count: How many times (or infinite)
animation-direction: normal, reverse, alternate, alternate-reverse
animation-fill-mode: What happens before/after (forwards, backwards, both)
Defines the animation sequence
@keyframes change-color {
from {
background-color: red;
}
to {
background-color: green;
}
}
/* Or use percentages */
@keyframes change-color {
0% {
background-color: red;
}
100% {
background-color: green;
}
}
from = 0% and to = 100%
@keyframes complex-animation {
0% {
transform: translateX(0) scale(1);
background-color: red;
}
33% {
transform: translateX(100px) scale(1.2);
background-color: blue;
}
66% {
transform: translateX(100px) rotate(180deg);
background-color: green;
}
100% {
transform: translateX(0) scale(1);
background-color: red;
}
}
You can define as many keyframes as you need at any percentage!
.element {
animation: slide-in 2s;
animation-iteration-count: 1; /* Runs once */
}
.loader {
animation: spin 1s;
animation-iteration-count: infinite; /* Loops forever */
}
.bounce {
animation: bounce-up 0.5s;
animation-iteration-count: 3; /* Runs 3 times */
}
Important: One iteration = one complete cycle from 0% to 100%
With alternate direction, it goes forward then backward
normal: Plays forward (0% → 100%), then resets
reverse: Plays backward (100% → 0%), then resets
alternate: Forward, then backward, then forward...
alternate-reverse: Backward, then forward, then backward...
.smooth-bounce {
animation: bounce 2s infinite alternate;
}
/* Plays forward for 2s, then backward for 2s, repeat */
none: Default - no styles applied before/after
forwards: Keeps the final keyframe styles after completion
backwards: Applies first keyframe styles during delay
both: Applies both forwards and backwards rules
.fade-in {
opacity: 0;
animation: fadeIn 1s forwards;
/* Stays at opacity: 1 after animation */
}
@keyframes fadeIn {
to { opacity: 1; }
}
/* Loading spinner */
.spinner {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-10px);
}
.card.loading {
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
💡 Tip: You can use transitions for interactive states and animations for continuous effects on the same element!
Different CSS properties trigger different browser operations:
transform, opacity
color, background
width, height, margin
Resource: Check csstriggers.com for detailed property information
1. Button Hover: Scale up 10% and change color on hover
2. Loading Spinner: Continuously rotating circle
3. Fade In: Element fades in from opacity 0 to 1
4. Slide In: Element slides in from left using transform
5. Bounce: Element bounces up and down infinitely
Challenge: Use only transform and opacity for best performance!
📖 Read: MDN - Using CSS Transitions
📖 Read: MDN - Using CSS Animations
📖 Read: Josh Comeau - The World of CSS Transforms
🔗 Explore: CSS Triggers website
💻 Complete: CSS Exercises - Animation folder
❓ What are the four main 2D transform functions?
❓ How do you chain multiple transforms?
❓ What's required for 3D transforms to look 3D?
❓ What's the difference between transitions and animations?
❓ What does animation-iteration-count: infinite do?
❓ What are the most performant CSS properties to animate?
❓ What is stacking context and how is it created?
✅ Transforms change appearance without affecting document flow
✅ Transitions animate simple state changes smoothly
✅ Animations provide complex, multi-step sequences
✅ Stacking context controls z-axis layering
✅ Performance matters - use transform and opacity
✅ @keyframes define animation sequences at percentages
📱 Media queries and breakpoints
🖥️ Mobile-first design
📐 Responsive units and layouts
🎨 Flexible images and typography
See you Thursday!