Một trang web tĩnh — không có animation hay hiệu ứng — sẽ trông nhàm chán. Nhưng thêm hiệu ứng động nhẹ nhàng sẽ làm trang web trở nên sống động, chuyên nghiệp hơn. CSS Transform và Transition cho phép bạn tạo những hiệu ứng này mà không cần JavaScript.
Bài này sẽ dạy bạn cách sử dụng transform và transition để tạo các hiệu ứng động mượt mà: zoom, xoay, dịch chuyển…
Transform là gì?
Transform cho phép bạn thay đổi hình dạng, kích thước, hoặc vị trí của phần tử mà không ảnh hưởng đến layout (không dịch chuyển các phần tử khác).
- 🔄 Rotate: Xoay phần tử
- 📏 Scale: Phóng to/thu nhỏ
- ➡️ Translate: Dịch chuyển
- 🔀 Skew: Nghiêng
Transform: Translate – Dịch chuyển
translate() dịch chuyển phần tử theo trục X (ngang) và Y (dọc).
/* Dịch chuyển ngang và dọc */
.box {
transform: translate(50px, 100px);
/* X: 50px sang phải, Y: 100px xuống dưới */
}
/* Chỉ dịch chuyển ngang */
.box {
transform: translateX(50px); /* 50px sang phải */
}
/* Chỉ dịch chuyển dọc */
.box {
transform: translateY(100px); /* 100px xuống dưới */
}
/* Dùng phần trăm (tương đối với kích thước phần tử) */
.box {
transform: translate(50%, 50%); /* Dịch bằng nửa kích thước của nó */
}
/* Ứng dụng: Canh giữa phần tử */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* Dịch lùi nửa kích thước để canh giữa */
}Transform: Scale – Phóng to/Thu nhỏ
scale() phóng to hoặc thu nhỏ phần tử. Giá trị: 1 = bình thường, 2 = gấp đôi, 0.5 = nửa kích thước.
/* Phóng to cả chiều rộng và cao */
.box {
transform: scale(1.5); /* Gấp 1.5 lần */
}
/* Phóng to chỉ chiều rộng */
.box {
transform: scaleX(2); /* Rộng gấp đôi, cao bình thường */
}
/* Phóng to chỉ chiều cao */
.box {
transform: scaleY(0.5); /* Cao nửa lại, rộng bình thường */
}
/* Phóng to riêng từng trục */
.box {
transform: scale(2, 0.5); /* Rộng gấp đôi, cao nửa lại */
}Transform: Rotate – Xoay
rotate() xoay phần tử theo góc (độ hoặc radian). Giá trị dương = xoay theo chiều kim đồng hồ, âm = xoay ngược.
/* Xoay 45 độ */
.box {
transform: rotate(45deg);
}
/* Xoay -90 độ (ngược chiều kim đồng hồ) */
.box {
transform: rotate(-90deg);
}
/* Xoay quanh trục X (3D) */
.box {
transform: rotateX(45deg); /* Xoay từ trên xuống */
}
/* Xoay quanh trục Y (3D) */
.box {
transform: rotateY(45deg); /* Xoay từ trái sang phải */
}
/* Xoay quanh trục Z (bình thường, 2D) */
.box {
transform: rotateZ(45deg); /* Giống rotate(45deg) */
}Transform: Skew – Nghiêng
skew() nghiêng phần tử theo trục X và Y.
/* Nghiêng theo cả X và Y */
.box {
transform: skew(20deg, 30deg);
}
/* Nghiêng chỉ trục X */
.box {
transform: skewX(45deg); /* Nghiêng sang trái-phải */
}
/* Nghiêng chỉ trục Y */
.box {
transform: skewY(20deg); /* Nghiêng lên-xuống */
}Transform-origin – Điểm gốc xoay
Mặc định, transform dựa trên tâm phần tử. Dùng transform-origin để thay đổi điểm gốc.
/* Xoay từ góc trên-trái */
.box {
transform-origin: top left;
transform: rotate(45deg);
}
/* Xoay từ góc dưới-phải */
.box {
transform-origin: bottom right;
transform: rotate(45deg);
}
/* Xoay từ điểm cụ thể (pixels) */
.box {
transform-origin: 100px 100px;
transform: rotate(45deg);
}Kết hợp nhiều Transform
/* Kết hợp nhiều transform */
.box {
transform: translate(50px, 100px) scale(1.2) rotate(45deg);
/* Vừa dịch chuyển, vừa phóng to, vừa xoay */
}
/* Hoặc viết riêng (kém hiệu quả) */
.box {
transform: translate(50px, 100px);
}
.box:hover {
transform: translate(50px, 100px) scale(1.2) rotate(45deg);
}Transition – Hiệu ứng chuyển tiếp
Transition làm cho thay đổi CSS diễn ra từ từ thay vì tức thì. Nó tạo ra chuyển động mượt mà giữa hai trạng thái.
/* Transition đơn giản */
.box {
background-color: blue;
transition: background-color 0.3s;
/* Thay đổi background-color trong 0.3 giây */
}
.box:hover {
background-color: red;
/* Khi hover, background-color thay đổi từ từ (0.3s) */
}Các thuộc tính Transition
| Thuộc tính | Chức năng | Giá trị mặc định | Ví dụ |
|---|---|---|---|
transition-property | Thuộc tính CSS nào sẽ transition | all | transition-property: transform; |
transition-duration | Thời gian transition | 0s | transition-duration: 0.3s; |
transition-timing-function | Tốc độ chuyển tiếp (linear, ease, ease-in…) | ease | transition-timing-function: ease-out; |
transition-delay | Trễ trước khi bắt đầu | 0s | transition-delay: 0.1s; |
Timing Functions (Tốc độ chuyển tiếp)
| Giá trị | Mô tả | Khi nào dùng |
|---|---|---|
linear | Tốc độ đều (bắt đầu nhanh, cuối cùng chậm) | Animations lặp lại |
ease (mặc định) | Bắt đầu chậm, nhanh giữa, cuối cùng chậm | Hầu hết trường hợp |
ease-in | Bắt đầu chậm, cuối nhanh | Hoạt động đầu vào |
ease-out | Bắt đầu nhanh, cuối chậm | Hoạt động kết thúc |
ease-in-out | Bắt đầu chậm, nhanh giữa, cuối chậm | Hoạt động đầu-cuối |
/* Transition với timing function */
.box {
transition: transform 0.3s ease-out;
/* transform thay đổi trong 0.3s, tốc độ ease-out */
}
.box:hover {
transform: scale(1.2);
}Shorthand Transition
/* Cách dài */
.box {
transition-property: transform;
transition-duration: 0.3s;
transition-timing-function: ease-out;
transition-delay: 0.1s;
}
/* Shorthand */
.box {
transition: transform 0.3s ease-out 0.1s;
/* property duration timing-function delay */
}
/* Transition tất cả thuộc tính */
.box {
transition: all 0.3s ease;
}Ví dụ hoàn chỉnh – Thẻ sản phẩm với hiệu ứng
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transform & Transition Demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Sản phẩm</h1>
<div class="products-grid">
<!-- Product Card 1 -->
<div class="product-card">
<div class="product-image">
<img src="product1.jpg" alt="Sản phẩm 1">
</div>
<div class="product-info">
<h3>Sản phẩm 1</h3>
<p class="price">$29.99</p>
<button class="btn-add">Thêm vào giỏ</button>
</div>
</div>
<!-- Product Card 2 -->
<div class="product-card">
<div class="product-image">
<img src="product2.jpg" alt="Sản phẩm 2">
</div>
<div class="product-info">
<h3>Sản phẩm 2</h3>
<p class="price">$39.99</p>
<button class="btn-add">Thêm vào giỏ</button>
</div>
</div>
<!-- Product Card 3 -->
<div class="product-card">
<div class="product-image">
<img src="product3.jpg" alt="Sản phẩm 3">
</div>
<div class="product-info">
<h3>Sản phẩm 3</h3>
<p class="price">$49.99</p>
<button class="btn-add">Thêm vào giỏ</button>
</div>
</div>
</div>
<!-- Button với transform -->
<div class="button-demo">
<button class="btn-hover">Hover me!</button>
</div>
</body>
</html>/* FILE: styles.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
padding: 40px 20px;
}
h1 {
text-align: center;
margin-bottom: 40px;
color: #2c3e50;
}
/* Products Grid */
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
max-width: 1200px;
margin: 0 auto;
}
/* Product Card */
.product-card {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease; /* Transition tất cả thuộc tính */
}
.product-card:hover {
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
transform: translateY(-10px); /* Dịch lên 10px */
}
/* Product Image */
.product-image {
width: 100%;
height: 200px;
overflow: hidden;
background-color: #f0f0f0;
}
.product-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease; /* Transition chỉ transform */
}
.product-card:hover .product-image img {
transform: scale(1.1); /* Phóng to ảnh khi hover card */
}
/* Product Info */
.product-info {
padding: 20px;
}
.product-info h3 {
color: #2c3e50;
margin-bottom: 10px;
font-size: 18px;
}
.price {
color: #e74c3c;
font-size: 20px;
font-weight: bold;
margin-bottom: 15px;
}
/* Add Button */
.btn-add {
width: 100%;
padding: 12px;
background-color: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s ease;
}
.btn-add:hover {
background-color: #2980b9;
transform: scale(1.05);
}
.btn-add:active {
transform: scale(0.98); /* Nút bấm nhỏ lại khi click */
}
/* Button Demo */
.button-demo {
display: flex;
justify-content: center;
margin-top: 60px;
}
.btn-hover {
padding: 15px 40px;
font-size: 18px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 50px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: bold;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.btn-hover:hover {
transform: translateY(-3px) scale(1.05);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}
.btn-hover:active {
transform: translateY(-1px) scale(0.98);
}Hiệu ứng hover phổ biến
/* 1. Scale & Shadow (phóng to + bóng) */
.scale-shadow:hover {
transform: scale(1.1);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}
/* 2. Translate Up (dịch lên) */
.translate-up:hover {
transform: translateY(-10px);
}
/* 3. Rotate & Scale (xoay + phóng to) */
.rotate-scale:hover {
transform: rotate(5deg) scale(1.05);
}
/* 4. Skew (nghiêng) */
.skew:hover {
transform: skewX(-10deg);
}
/* 5. Rotate Full (xoay 360 độ) */
.rotate-full:hover {
transform: rotate(360deg);
transition: transform 0.6s ease;
}
/* 6. Background Color Change (thay đổi màu nền) */
.color-change {
background-color: blue;
transition: background-color 0.3s ease;
}
.color-change:hover {
background-color: red;
}3D Transform (Nâng cao)
/* Perspective - tạo hiệu ứng 3D */
.container {
perspective: 1000px; /* Khoảng cách camera từ phần tử */
}
/* Xoay 3D */
.box-3d {
width: 200px;
height: 200px;
background: linear-gradient(45deg, blue, purple);
transform: rotateX(45deg) rotateY(45deg);
}
/* Flip card effect (thẻ lật) */
.flip-card {
position: relative;
width: 300px;
height: 200px;
perspective: 1000px;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
.flip-card:hover .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
font-weight: bold;
}
.flip-card-front {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.flip-card-back {
background: #ecf0f1;
color: #2c3e50;
transform: rotateY(180deg);
}Tóm tắt
- ✅ Transform: Thay đổi hình dạng, kích thước, vị trí (scale, rotate, translate, skew)
- ✅ Translate: Dịch chuyển (translateX, translateY, translateZ)
- ✅ Scale: Phóng to/thu nhỏ (scaleX, scaleY, scaleZ)
- ✅ Rotate: Xoay (rotateX, rotateY, rotateZ)
- ✅ Skew: Nghiêng (skewX, skewY)
- ✅ Transform-origin: Điểm gốc xoay
- ✅ Transition: Hiệu ứng chuyển tiếp mượt mà
- ✅ Transition-duration: Thời gian chuyển tiếp
- ✅ Timing-function: Tốc độ (linear, ease, ease-in, ease-out)
- ✅ Transition-delay: Trễ trước khi bắt đầu
- ✅ 3D Transform: Perspective, rotateX, rotateY (nâng cao)
🎯 Bài tập thực hành
Bài tập 1: Tạo thẻ sản phẩm (product card) với hiệu ứng hover:
- Card có ảnh, tên, giá, nút mua
- Khi hover:
- Card dịch lên 10px (translateY)
- Ảnh phóng to (scale 1.1)
- Bóng tăng (box-shadow)
- Nút mua đổi màu
- Tất cả transition: 0.3s ease
- Ít nhất 3 cards trong grid
Bài tập 2: Tạo nút (button) với hiệu ứng hover:
- Button có gradient background, bo tròn, bóng
- Khi hover:
- Scale 1.05 (phóng to nhẹ)
- TranslateY -3px (dịch lên)
- Bóng tăng
- Khi active (click):
- Scale 0.98 (nhỏ lại)
- Bóng giảm
- Transition 0.3s ease-out
Bài tập 3: Tạo thẻ lật (flip card) 3D:
- Mặt trước: Ảnh, tên sản phẩm
- Mặt sau: Mô tả, giá, nút mua
- Khi hover: Thẻ lật 180 độ (rotateY)
- Dùng transform-style: preserve-3d
- Transition 0.6s ease
- Ít nhất 3 thẻ flip
Chúc bạn thành công! 🚀