Hiệu ứng động và chuyển tiếp là một phần quan trọng khi thiết kế web. Ở bài viết này, hãy cùng nhau học các mẹo dùng Animation trong CSS để thiết kế web thật đẹp nhé!
Chuyển đổi một phần tử khi trỏ chuột
Một thực hành thiết kế phổ biến là có một phần tử mở rộng khi được tương tác. Ví dụ, bạn có thể muốn dịch các nút lên trên một chút khi ai đó trỏ chuột qua nó. Bạn có thể đạt được điều này bằng cách dùng thuộc tính transform của CSS.
Giả sử bạn có nút bấm:
<button>
Click me
</button>
Bạn tạo kiểu phần thân (body) của tài liệu và nút bấm như sau:
/* Căn nút bấm ở giữa trang */
body {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
background-color: black;
}
/* Tạo kiểu nút bấm */
button {
padding: 1em 2em;
background: blue;
border: 0;
color: white;
border-radius: 0.25rem;
cursor: pointer;
font-size: 2rem;
transition: transform 500ms;
}
/* Trạng thái trỏ chuột */
button:hover,
button:focus {
transform: translateY(0.75rem) 500ms;
}
Với khối cuối cùng, bạn đặt trạng thái di chuột và tiêu điểm trên nút bấm. Ở cả hai trạng thái, bạn dịch nút bấm dọc theo trục Y khoảng 0.75rem. Nút bấm này sẽ trông như sau:
Khi trỏ chuột trên nút bấm, nó di chuyển theo hướng đi lên. Quá trình chuyển tiếp mất khoảng nửa giây để hoàn thành. Đây là một mẫu mà bạn có thể triển khai không chỉ trên nút bấm mà còn ở các phần tử khác (ví dụ: ảnh).
Khai báo nhiều keyframe bằng một khai báo
Mẫu phổ biến khác trong animation CSS là lặp đi lặp lại cùng một giá trị nhiều lần. Nó có thể là màu sắc, kích thước hoặc hướng. Bạn có thể đạt được điều này bằng cách dùng hiệu ứng keyframe CSS. Về cơ bản, bạn chỉ cần khai báo nhiều keyframe bằng một lần khai báo.
Xem xét nút bấm bạn đã tạo ở phần trước. Có thể bạn muốn lặp một số màu background khi click vào nút bấm, thậm chí cả cùng một màu ở các giai đoạn hoạt ảnh khác nhau. Hãy xem cách làm điều đó trong code.
Đầu tiên, bạn muốn tạo hiệu ứng nút bấm động chỉ khi được click nên đã tạo file script.js. Bạn truy cập nút bấm và bật một class trên nút bấm khi được click ở file này. Cụ thể:
const button = document.querySelector("button")
button.addEventListener("click", (e) => {
button.classList.toggle('party-time')
})
Ví dụ đã dùng querySelector để truy cập nút bấm từ trang web. Class party-time kích hoạt hiệu ứng động tên party:
.party-time {
animation: party 2000ms infinite;
}
Đối với animation này, bạn bắt đầu bằng màu đỏ và chuyển sang mầu vàng ở 25%. Sau đó, bạn quay lại màu đỏ ở 50% trước khi chuyển lại màu vàng ở 75%. Cuối cùng, ở mức 100%, bạn sẽ chọn màu xanh đậm:
@keyframes party {
0%, 50% {
background-color: red;
}
25%, 75% {
background-color: yellow;
}
100% {
background-color: hsl(200, 72%, 35%);
}
}
Phương pháp tiếp cận này khá hữu ích để xen kẽ giữa các màu nền. Vì bạn có thể lặp lại nhiều keyframe trong một biến nên việc dùng cùng một thuộc tính sẽ siêu dễ dàng ở các giai đoạn hiệu ứng động khác nhau.
Dùng @property để tạo hiệu ứng động cho các thuộc tính tùy biến
Có thể bạn đã biết, không phải tất cả thuộc tính trong CSS đều có thể tạo hoạt ảnh được. Nếu muốn tạo hiệu ứng động cho một thuộc tính không thể “animate”, giải pháp tốt nhất là dùng lệnh @property.
Bắt đầu bằng cách thay đổi màu nền của nút bấm sang gradient tuyến tính:
button {
// other CSS
background: linear-gradient(90deg, blue, green);
// other CSS
}
Kết quả:
Nhiều người thường muốn tạo hiệu ứng động cho gradient màu trên nút bấm. Dù có nhiều cách để di chuyển dải màu xung quanh nhưng thực tế không thể “animate” nó. Đó là do background (cả background-image) không phải thuộc tính có thể tạo hiệu ứng động. Đây là nơi cần dùng tới @property.
Lệnh @property cho phép bạn đăng ký các thuộc tính tùy biến. Khi dùng @property, bạn phải cung cấp 3 giá trị cho nó, bao gồm: syntax, inherits và initial-value:
@property --color-1 {
syntax: "<color>";
inherits: true;
initial-value: red;
}
@property --color-2 {
syntax: "<color>";
inherits: true;
initial-value: blue;
}
Đầu tiên là thuộc tính khởi đầu, thứ hai là thuộc tính đích. Giờ thay vì chuyển tiếp một ảnh background (mà bạn không thể chuyển tiếp), bạn sẽ chuyển tiếp từ --color-1 sang --color-2 (thuộc tính tùy biến) trong một giây:
button {
transition: --color-1 1000ms, --color-2 1000ms;
}
Kỹ thuật này hữu ích bởi bạn cũng có thể thêm các tùy biến khác. Ví dụ, bạn thêm độ trễ để cho nó trải nghiệm mượt mà hơn. Các khả năng đó là vô tận.
Dùng độ trễ animation phủ định
Độ trễ animation quan trọng với việc tạo hiệu ứng động mượt mà. Hãy cùng phân tích ví dụ bên dưới nếu muốn hiểu rõ hơn. Ở phần này, thêm phần tử div với 15 dot (chấm) ở phía trên đầu của nút bấm:
<div class="dots">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
Đây là một số kiểu cơ bản để biến đổi từ mỗi div con thành chấm:
.dots {
display: flex;
gap: .5rem;
margin-bottom: 20px;
}
.dot {
width: 10px;
aspect-ratio: 1;
background-color: red;
border-radius: 50%;
}
Ở đây dùng Flexbox để đặt các chấm theo đường nằm ngang. Bên trong script.js, thêm code kích hoạt hiệu ứng cho dấu chấm. Bạn đang bật class dance trên dot:
button.addEventListener("click", (e) => {
button.classList.toggle('party-time')
// Code mới
dots.forEach((dot) => {
dot.classList.toggle('dance')
})
})
Class dance kích hoạt hiệu ứng rise:
.dot.dance {
animation: rise 2000ms infinite alternate;
}
Đối với animation này, chỉ cần dịch các chấm -100px dọc theo trục Y:
@keyframes rise {
100% {
transform: translateY(-100px)
}
}
Giờ là lúc làm điều gì đó thú vị. Thay vì tăng đồng thời các chấm, bạn muốn tạo hiệu ứng chấm chuyển động như một cơn sóng? Để làm việc này, bạn thêm animation-delay cho các dot, tăng từng dot lên 100ms:
.dot:nth-child(1) {
animation-delay: 100ms;
}
.dot:nth-child(2) {
animation-delay: 200ms;
}
.dot:nth-child(3) {
animation-delay: 300ms;
}
.dot:nth-child(4) {
animation-delay: 400ms;
}
/* Tiếp tục cho tới khi có 15 dot */
Điều này tạo hình ảnh động mượt mà tại vị trí các chấm di chuyển lên và xuống theo dạng sóng. Ảnh sau ghi lại hình ảnh chấm ở giữa hiệu ứng:
Dùng prefers-reduced-motion để bật tùy chọn
Nhớ rằng, rất nhiều người không thích hiệu ứng dựa trên chuyển động. Thực tế, phần lớn người dùng đều có tùy chọn tắt chuyển động trong trình duyệt. Chuyển động có thể đánh lạc hướng các giác quan. Trong trường hợp nghiêm trọng, nó có thể khiến người xem chóng mặt.
Thật may, bạn có thể dễ dàng xử lý vấn đề này bằng cách gói hiệu ứng động bên trong truy vấn media no-preference như sau:
@media(prefers-reduced-motion: no-preference) {
.dot.dance {
animation: rise 2000ms infinite alternate;
}
}
Giờ nếu đã bật prefers-reduced-motion trong trình duyệt thì hiệu ứng động sẽ không chạy.
Trên đây là những mẹo và thủ thuật dùng CSS để tạo hiệu ứng động animation. Hi vọng bài viết hữu ích với các bạn.