Trong thế giới thiết kế web hiện đại, việc tạo ra một giao diện không chỉ đẹp mắt mà còn tương tác mượt mà là yếu tố then chốt để giữ chân người dùng. Các hiệu ứng chuyển tiếp tinh tế khi người dùng tương tác với các phần tử trên trang, như di chuột qua một nút bấm hay mở một menu, ngày càng được ưa chuộng để nâng cao trải nghiệm người dùng một cách đáng kể. Tuy nhiên, nhiều người mới bắt đầu làm quen với CSS vẫn còn cảm thấy bối rối và gặp khó khăn khi cố gắng triển khai các hiệu ứng này bằng thuộc tính transition. Họ không biết bắt đầu từ đâu hay làm thế nào để kiểm soát các chuyển động một cách chính xác. Bài viết này của AZWEB sẽ là kim chỉ nam của bạn, giải thích cặn kẽ định nghĩa transition trong CSS, đi sâu vào các thuộc tính cơ bản và cung cấp hướng dẫn chi tiết từng bước. Đầu tiên, bạn sẽ hiểu rõ về khái niệm transition và các thuộc tính chính của nó, sau đó là những ví dụ minh họa trực quan, và cuối cùng là các mẹo hữu ích và lưu ý quan trọng để bạn có thể tự tin áp dụng vào dự án của mình.
Định nghĩa Transition trong CSS
Transition là gì?
Transition, hay hiệu ứng chuyển tiếp, là một thuộc tính trong CSS cho phép bạn thay đổi giá trị của các thuộc tính khác một cách mượt mà và từ từ trong một khoảng thời gian nhất định. Thay vì một sự thay đổi diễn ra ngay lập tức, đột ngột và khô cứng, transition tạo ra một hiệu ứng chuyển động uyển chuyển giữa trạng thái ban đầu và trạng thái cuối của một phần tử.

Hãy tưởng tượng bạn có một nút bấm, ban đầu có màu xanh. Khi bạn di chuột qua, bạn muốn nó đổi sang màu đỏ. Nếu không có transition, sự thay đổi màu sắc sẽ xảy ra trong nháy mắt. Nhưng khi áp dụng transition, bạn có thể khiến màu xanh mờ dần và chuyển thành màu đỏ trong vòng nửa giây, tạo cảm giác mềm mại và dễ chịu hơn cho mắt người dùng. Về cơ bản, transition đóng vai trò là cầu nối, giúp lấp đầy các “khung hình” trung gian giữa hai trạng thái CSS, biến một sự thay đổi đột ngột thành một chuỗi chuyển động liền mạch và hấp dẫn.
Tại sao nên dùng transition?
Sử dụng transition không chỉ là một lựa chọn về mặt thẩm mỹ, mà còn là một chiến lược quan trọng để cải thiện trải nghiệm người dùng (UX). Bộ não con người có xu hướng cảm thấy thoải mái hơn với những chuyển động tự nhiên, có gia tốc và diễn ra từ từ, thay vì những thay đổi đột ngột. Khi một phần tử trên trang web thay đổi trạng thái (ví dụ: kích thước, màu sắc, vị trí) ngay lập tức, nó có thể gây ra sự khó chịu và mất phương hướng cho người dùng.
Transition giúp giải quyết vấn đề này bằng cách thay thế các hiệu ứng “nhảy cóc” hoặc chuyển đổi đột ngột bằng những chuyển động mềm mại và có chủ đích. Điều này mang lại nhiều lợi ích. Thứ nhất, nó giúp hướng sự chú ý của người dùng một cách tự nhiên đến phần tử vừa thay đổi. Thứ hai, nó cung cấp phản hồi trực quan, xác nhận rằng hành động của người dùng (như nhấp chuột, di chuột) đã được ghi nhận. Cuối cùng, một giao diện với các hiệu ứng chuyển tiếp được thiết kế tốt sẽ tạo cảm giác chuyên nghiệp, hiện đại và tinh tế hơn, góp phần xây dựng sự tin tưởng và yêu thích của người dùng đối với trang web của bạn.
Các thuộc tính cơ bản của Transition
Để điều khiển hiệu ứng chuyển tiếp một cách chính xác, CSS cung cấp bốn thuộc tính con của transition. Hiểu rõ từng thuộc tính này là chìa khóa để bạn có thể tạo ra mọi hiệu ứng chuyển động theo ý muốn.
transition-property
Thuộc tính transition-property đóng vai trò xác định “cái gì” sẽ được chuyển tiếp. Nói một cách đơn giản, bạn dùng nó để chỉ định chính xác thuộc tính CSS nào sẽ nhận hiệu ứng chuyển động mượt mà khi giá trị của nó thay đổi. Bạn có thể chọn một thuộc tính duy nhất, nhiều thuộc tính cách nhau bởi dấu phẩy, hoặc sử dụng giá trị all để áp dụng hiệu ứng cho tất cả các thuộc tính có khả năng chuyển tiếp.

Ví dụ, nếu bạn chỉ muốn màu nền thay đổi từ từ, bạn sẽ đặt transition-property: background-color;. Nếu bạn muốn cả chiều rộng và chiều cao của một khối thay đổi mượt mà, bạn sẽ viết transition-property: width, height;. Một số giá trị phổ biến thường được sử dụng với transition-property bao gồm background-color, width, height, opacity (độ trong suốt), color (màu chữ), và transform (các phép biến đổi như xoay, co giãn, di chuyển). Việc lựa chọn đúng thuộc tính giúp tối ưu hóa hiệu suất và đảm bảo hiệu ứng chỉ xảy ra ở nơi bạn muốn. Để hiểu sâu hơn về khái niệm CSS transition là gì bạn có thể tham khảo bài viết chi tiết của chúng tôi.
transition-duration
Nếu transition-property trả lời câu hỏi “cái gì”, thì transition-duration trả lời câu hỏi “trong bao lâu?”. Thuộc tính này cho phép bạn thiết lập tổng thời gian để hoàn thành một hiệu ứng chuyển tiếp. Thời gian được xác định bằng đơn vị giây (s) hoặc mili giây (ms). Ví dụ, 1s tương đương với 1000ms.

Tác động của thời gian tới cảm nhận của người dùng là rất lớn. Một transition-duration quá ngắn, ví dụ 0.1s, có thể khiến hiệu ứng trông gần như tức thời và không được chú ý. Ngược lại, một thời gian quá dài, chẳng hạn 3s, có thể làm người dùng cảm thấy khó chịu và phải chờ đợi, gây ảnh hưởng tiêu cực đến trải nghiệm. Thông thường, một khoảng thời gian từ 0.2s đến 0.5s được xem là lý tưởng cho hầu hết các tương tác trên giao diện người dùng, đủ nhanh để không gây chậm trễ nhưng cũng đủ chậm để mắt người có thể cảm nhận được sự mượt mà.
transition-timing-function
Thuộc tính transition-timing-function quyết định “tốc độ” của hiệu ứng chuyển tiếp trong suốt quá trình diễn ra. Nó không phải là một tốc độ không đổi, mà là một đường cong gia tốc, mô tả cách hiệu ứng tăng tốc và giảm tốc. Điều này giúp tạo ra các chuyển động tự nhiên và sống động hơn.
CSS cung cấp một số giá trị dựng sẵn phổ biến:
ease: Bắt đầu chậm, tăng tốc ở giữa, và kết thúc chậm. Đây là giá trị mặc định, mang lại cảm giác tự nhiên nhất cho nhiều trường hợp.linear: Tốc độ không đổi từ đầu đến cuối. Thích hợp cho các hiệu ứng như thanh tiến trình hoặc các chuyển động cơ học.ease-in: Bắt đầu chậm và tăng tốc dần cho đến khi kết thúc. Tạo cảm giác vật thể đang lấy đà.ease-out: Bắt đầu nhanh và giảm tốc dần về cuối. Phù hợp cho các phần tử xuất hiện trên màn hình, tạo cảm giác nhẹ nhàng.ease-in-out: Tương tựeasenhưng có đường cong mượt hơn ở cả điểm bắt đầu và kết thúc.
Việc lựa chọn transition-timing-function phù hợp giúp truyền tải đúng “tính cách” cho hiệu ứng của bạn, từ nhẹ nhàng, thanh lịch đến mạnh mẽ, dứt khoát.
transition-delay
Cuối cùng, transition-delay là thuộc tính cho phép bạn thiết lập một khoảng thời gian chờ trước khi hiệu ứng chuyển tiếp bắt đầu được thực thi. Tương tự như transition-duration, giá trị của nó cũng được xác định bằng giây (s) hoặc mili giây (ms).

Nếu bạn không khai báo transition-delay, giá trị mặc định sẽ là 0s, nghĩa là hiệu ứng sẽ bắt đầu ngay khi có sự thay đổi trạng thái (ví dụ: khi người dùng di chuột vào). Tuy nhiên, thuộc tính này trở nên cực kỳ hữu ích khi bạn muốn tạo ra các hiệu ứng phức tạp hơn, có sự phối hợp hoặc tuần tự giữa nhiều phần tử. Ví dụ, bạn có thể làm cho một loạt các mục trong menu xuất hiện lần lượt từng cái một, mỗi cái cách nhau một khoảng thời gian ngắn, bằng cách đặt transition-delay tăng dần cho mỗi mục. Điều này tạo ra một chuỗi hiệu ứng đẹp mắt và có tổ chức thay vì tất cả cùng xuất hiện một lúc.
Cách sử dụng Transition để tạo hiệu ứng chuyển tiếp mượt mà
Sau khi đã nắm vững các thuộc tính cơ bản, việc áp dụng chúng vào thực tế khá đơn giản. Bạn có thể viết chúng một cách riêng lẻ hoặc sử dụng cú pháp gộp ngắn gọn để tiết kiệm thời gian và giúp mã nguồn sạch sẽ hơn.
Cấu trúc cú pháp cơ bản
Có hai cách để khai báo các thuộc tính của transition trong CSS.
Cách khai báo chi tiết (Longhand):
Bạn có thể viết từng thuộc tính một cách riêng biệt. Cách này rõ ràng và dễ đọc, đặc biệt khi bạn mới bắt đầu.
.box { transition-property: background-color; transition-duration: 0.5s; transition-timing-function: ease-out; transition-delay: 0.1s;}
Cách khai báo gộp (Shorthand):
Đây là cách phổ biến và hiệu quả hơn. Bạn có thể gộp tất cả bốn thuộc tính vào trong một thuộc tính duy nhất là transition. Thứ tự các giá trị thường là: property duration timing-function delay.
.box { transition: background-color 0.5s ease-out 0.1s;}
Lưu ý rằng, trình duyệt đủ thông minh để nhận diện giá trị nào thuộc về thuộc tính nào dựa trên đơn vị của nó (ví dụ, s hoặc ms luôn là duration hoặc delay). Nếu bạn chỉ khai báo một giá trị thời gian, nó sẽ được hiểu là transition-duration. Nếu có hai giá trị thời gian, giá trị đầu tiên là duration và giá trị thứ hai là delay.
Ví dụ minh họa áp dụng Transition trong CSS
Hãy cùng xem qua một vài ví dụ thực tế để hiểu rõ hơn cách transition hoạt động.
Ví dụ thay đổi màu nền khi hover
Đây là một trong những ứng dụng cơ bản và phổ biến nhất của transition. Chúng ta sẽ tạo một nút bấm đổi màu nền mượt mà khi người dùng di chuột qua.
HTML:
<button class="my-button">Di chuột vào đây</button>
CSS:
.my-button { background-color: #3498db; /* Màu nền ban đầu */ color: white; padding: 15px 25px; border: none; border-radius: 5px; cursor: pointer; /* Áp dụng transition cho thuộc tính background-color */ transition: background-color 0.4s ease;}
.my-button:hover { background-color: #2980b9; /* Màu nền khi hover */}
Giải thích step-by-step:
.my-button: Đây là lớp định nghĩa trạng thái ban đầu của nút. Chúng ta đặt màu nền là#3498db.transition: background-color 0.4s ease;: Dòng quan trọng nhất. Chúng ta báo cho trình duyệt rằng: “Hãy theo dõi thuộc tínhbackground-color. Nếu nó thay đổi, hãy thực hiện sự thay đổi đó trong vòng0.4giây theo đường cong tốc độease.”.my-button:hover: Đây là lớp giả (pseudo-class) xác định trạng thái của nút khi con trỏ chuột nằm trên nó. Chúng ta thay đổibackground-colorthành#2980b9.- Khi bạn di chuột vào nút, CSS phát hiện sự thay đổi giá trị
background-colorvà kích hoạt transition đã được định nghĩa ở trạng thái ban đầu, tạo ra hiệu ứng chuyển màu mượt mà. Khi bạn di chuột ra, nó lại chuyển ngược về màu ban đầu một cách mượt mà.
Ví dụ chuyển đổi kích thước và độ mờ của phần tử
Trong ví dụ này, chúng ta sẽ làm cho một hình ảnh mờ đi và phóng to nhẹ khi người dùng di chuột qua, tạo hiệu ứng tương tác bắt mắt.
HTML:
<div class="image-container">
<img src="your-image.jpg" alt="Một hình ảnh đẹp">
</div>

CSS:
.image-container img { width: 300px; border-radius: 10px; opacity: 1; /* Độ mờ ban đầu là 100% */ transform: scale(1); /* Kích thước ban đầu là 100% */ /* Áp dụng transition cho cả hai thuộc tính opacity và transform */ transition: opacity 0.3s linear, transform 0.3s ease-in-out;}
.image-container:hover img { opacity: 0.7; /* Giảm độ mờ xuống 70% */ transform: scale(1.1); /* Phóng to lên 110% */}
Giải thích step-by-step:
.image-container img: Định nghĩa trạng thái ban đầu của ảnh.opacity: 1nghĩa là ảnh hiển thị rõ nét, vàtransform: scale(1)là kích thước bình thường.transition: opacity 0.3s linear, transform 0.3s ease-in-out;: Ở đây chúng ta áp dụng transition cho hai thuộc tính cùng lúc, cách nhau bởi dấu phẩy.opacitysẽ thay đổi với tốc độlinear, trong khitransformsẽ thay đổi theo kiểuease-in-out. Cả hai đều diễn ra trong0.3giây..image-container:hover img: Khi di chuột vào thẻdivchứa ảnh, chúng ta thay đổiopacitycủa ảnh thành0.7và dùngtransform: scale(1.1)để phóng to nó lên một chút.- Nhờ có transition, sự thay đổi về độ mờ và kích thước sẽ diễn ra đồng thời và uyển chuyển, tạo ra một hiệu ứng tương tác tinh tế và chuyên nghiệp.
Common Issues/Troubleshooting
Khi làm việc với transition, đôi khi bạn sẽ gặp phải những vấn đề không mong muốn. Dưới đây là một số lỗi thường gặp và cách khắc phục chúng để đảm bảo hiệu ứng của bạn luôn hoạt động trơn tru.
Hiệu ứng transition không hoạt động
Đây là vấn đề phổ biến nhất đối với người mới bắt đầu. Nếu bạn đã viết code mà hiệu ứng không xuất hiện, hãy kiểm tra các nguyên nhân sau:
- Thuộc tính không hỗ trợ transition: Không phải tất cả các thuộc tính CSS đều có thể chuyển tiếp. Transition chỉ hoạt động với các thuộc tính có giá trị có thể tính toán được ở các điểm trung gian, chẳng hạn như số, phần trăm, hoặc màu sắc (ví dụ:
width,opacity,color). Các thuộc tính có giá trị rời rạc nhưdisplay(từnonesangblock) hoặcfont-familykhông thể được chuyển tiếp.- Cách xử lý: Thay vì chuyển tiếp
display: nonesangdisplay: block, hãy sử dụng kết hợpopacity(từ 0 đến 1) vàvisibility(từhiddensangvisible).
- Cách xử lý: Thay vì chuyển tiếp
- Sai cú pháp: Một lỗi nhỏ như quên đơn vị thời gian (
shoặcms), gõ sai tên thuộc tính, hoặc sai một dấu chấm phẩy cũng có thể làm cho toàn bộ khai báo transition bị vô hiệu.- Cách xử lý: Kiểm tra kỹ lại từng dòng code. Sử dụng công cụ kiểm tra (linting) trong trình soạn thảo code của bạn để phát hiện lỗi cú pháp tự động.
- Khai báo transition sai vị trí: Thuộc tính
transitionphải được đặt trên selector của trạng thái ban đầu, không phải trên selector của trạng thái thay đổi (như:hover,:focus). Trình duyệt cần biết về hiệu ứng trước khi sự thay đổi xảy ra.- Cách xử lý: Luôn đặt
transition: ...;trong khối CSS của phần tử gốc, ví dụ.buttonchứ không phải.button:hover.
- Cách xử lý: Luôn đặt
- Kiểm tra bằng Developer Tools: Sử dụng công cụ phát triển của trình duyệt (nhấn F12), chọn phần tử và xem tab “Computed” hoặc “Styles” để kiểm tra xem các thuộc tính transition có được áp dụng đúng cách hay không.
Hiệu ứng chuyển tiếp bị giật hoặc không mượt
Đôi khi hiệu ứng hoạt động nhưng lại bị giật, lag, đặc biệt là trên các thiết bị có cấu hình thấp. Nguyên nhân thường liên quan đến hiệu suất và cách trình duyệt render trang.
- Chuyển tiếp các thuộc tính ảnh hưởng đến layout: Các thuộc tính như
width,height,margin,left,topkhi thay đổi sẽ buộc trình duyệt phải tính toán lại bố cục (layout/reflow) của toàn bộ hoặc một phần trang. Đây là một tác vụ nặng nề và có thể gây ra hiện tượng giật, lag.- Hướng điều chỉnh: Ưu tiên sử dụng các thuộc tính được tăng tốc phần cứng (hardware-accelerated) là
transformvàopacity. Thay vì thay đổiwidth, hãy dùngtransform: scaleX(). Thay vì thay đổileft, hãy dùngtransform: translateX(). Các thuộc tính này không ảnh hưởng đến layout, giúp hiệu ứng mượt mà hơn rất nhiều.
- Hướng điều chỉnh: Ưu tiên sử dụng các thuộc tính được tăng tốc phần cứng (hardware-accelerated) là
- Thời gian
durationquá ngắn: Nếutransition-durationquá ngắn (ví dụ: dưới 100ms), hiệu ứng có thể xảy ra quá nhanh đến mức mắt người cảm nhận nó như một cái giật nhẹ thay vì một chuyển động mượt mà.- Hướng điều chỉnh: Tăng
durationlên một chút, trong khoảng0.2sđến0.4sđể chuyển động trở nên rõ ràng và dễ chịu hơn.
- Hướng điều chỉnh: Tăng
timing-functionkhông phù hợp: Sử dụnglinearcho mọi thứ đôi khi có thể tạo cảm giác máy móc và không tự nhiên.- Hướng điều chỉnh: Thử nghiệm với các giá trị khác như
ease-outhoặcease-in-outđể tạo ra các chuyển động có gia tốc, thường trông sẽ mượt mà và tự nhiên hơn trong mắt người dùng.
- Hướng điều chỉnh: Thử nghiệm với các giá trị khác như
Bằng cách nhận biết và xử lý những vấn đề này, bạn có thể đảm bảo các hiệu ứng transition của mình không chỉ đẹp mắt mà còn hoạt động hiệu quả trên mọi thiết bị.
Best Practices
Để sử dụng transition một cách hiệu quả và chuyên nghiệp, không chỉ cần biết cách viết code mà còn phải tuân theo các nguyên tắc thực hành tốt nhất. Điều này giúp đảm bảo hiệu ứng của bạn vừa đẹp mắt, vừa tối ưu về hiệu suất và mang lại trải hang hái nghiệm người dùng tốt nhất.
Chọn thuộc tính cần chuyển tiếp hợp lý
Đây là quy tắc quan trọng nhất. Như đã đề cập, không phải tất cả các thuộc tính đều được tạo ra như nhau về mặt hiệu suất. Hãy luôn ưu tiên sử dụng các thuộc tính được xử lý bởi GPU (bộ xử lý đồ họa) như transform (cho các thao tác di chuyển, xoay, co giãn) và opacity (cho độ mờ). Việc thay đổi các thuộc tính này không yêu cầu trình duyệt phải tính toán lại bố cục, giúp hiệu ứng chạy mượt mà ngay cả trên các thiết bị yếu. Hạn chế tối đa việc chuyển tiếp các thuộc tính như width, height, top, left, margin vì chúng gây ra reflow và repaint, ảnh hưởng đến hiệu suất. Bạn có thể tìm hiểu kỹ hơn về CSS Grid là gì và CSS Flexbox là gì để biết cách bố trí linh hoạt giúp giảm chuyển đổi kích thước một cách tối ưu.

Giữ duration vừa phải, tránh quá dài hoặc quá ngắn
Thời gian là yếu tố quyết định cảm nhận của người dùng. Một hiệu ứng quá nhanh (dưới 0.1s) sẽ không được chú ý, trong khi một hiệu ứng quá chậm (trên 1s) sẽ làm người dùng cảm thấy ứng dụng bị ì ạch, chậm chạp. Một nguyên tắc chung là giữ transition-duration trong khoảng từ 0.2s đến 0.5s cho hầu hết các tương tác trên giao diện. Thời gian này đủ để người dùng cảm nhận được sự chuyển động nhưng không gây ra sự chờ đợi khó chịu.
Sử dụng timing-function phù hợp với mục đích của hiệu ứng
Đường cong tốc độ có thể thay đổi hoàn toàn “cảm xúc” của một hiệu ứng. Hãy sử dụng chúng một cách có chủ đích. Ví dụ, ease-out (bắt đầu nhanh, kết thúc chậm) rất phù hợp cho các phần tử xuất hiện trên màn hình (như một modal hay menu), tạo cảm giác nhẹ nhàng, đáp ứng nhanh. Ngược lại, ease-in (bắt đầu chậm, kết thúc nhanh) có thể dùng cho các phần tử rời khỏi màn hình. ease-in-out mang lại cảm giác mượt mà, cân bằng cho các thay đổi trạng thái tại chỗ.
Không lạm dụng transition gây ảnh hưởng hiệu suất web
Transition rất hữu ích, nhưng lạm dụng chúng có thể gây tác dụng ngược. Một trang web với quá nhiều phần tử chuyển động cùng lúc có thể gây mất tập trung, rối mắt và làm giảm hiệu suất tổng thể. Hãy sử dụng transition một cách có chọn lọc, tập trung vào việc cung cấp phản hồi cho các tương tác quan trọng của người dùng (như hover, focus, click) và hướng sự chú ý của họ một cách tinh tế.
Kiểm thử trải nghiệm đa thiết bị và trình duyệt
Cuối cùng, đừng quên rằng người dùng của bạn truy cập trang web từ rất nhiều loại thiết bị và trình duyệt khác nhau. Một hiệu ứng chạy mượt trên máy tính để bàn cấu hình mạnh có thể bị giật lag trên điện thoại di động đời cũ. Luôn kiểm tra các hiệu ứng transition của bạn trên nhiều môi trường khác nhau để đảm bảo trải nghiệm người dùng nhất quán và chất lượng. Mặc dù các tiền tố nhà cung cấp (-webkit-, -moz-) ngày nay ít cần thiết hơn, việc kiểm tra vẫn là bước không thể bỏ qua để đảm bảo khả năng tương thích rộng rãi.
Conclusion
Qua bài viết này, chúng ta đã cùng nhau khám phá một cách toàn diện về transition trong CSS. Điểm mấu chốt cần nhớ là transition là một công cụ mạnh mẽ giúp tạo ra các hiệu ứng chuyển tiếp mượt mà và hấp dẫn, đóng vai trò quan trọng trong việc nâng cao trải nghiệm người dùng. Nó bao gồm bốn thuộc tính chính dễ sử dụng: transition-property để chọn đối tượng, transition-duration để xác định thời gian, transition-timing-function để điều chỉnh tốc độ, và transition-delay để tạo độ trễ. Bằng cách kết hợp khéo léo các thuộc tính này, bạn có thể biến một giao diện tĩnh, khô cứng trở nên sống động và tương tác hơn.

Giờ là lúc bạn hành động! Đừng ngần ngại, hãy thử áp dụng transition vào các dự án web của bạn ngay hôm nay. Bắt đầu với những hiệu ứng đơn giản như thay đổi màu sắc của một nút bấm, làm mờ một hình ảnh, hay di chuyển một biểu tượng. Bạn sẽ ngạc nhiên về sự khác biệt mà những chi tiết nhỏ này có thể mang lại cho cảm nhận tổng thể của người dùng. Để tiếp tục hành trình nâng cao kỹ năng thiết kế hiệu ứng, bạn có thể tìm hiểu thêm về các chủ đề nâng cao hơn như CSS Animation (@keyframes) để tạo các chuỗi chuyển động phức tạp và thuộc tính transform để mở khóa các khả năng biến đổi 2D và 3D. AZWEB chúc bạn thành công trên con đường chinh phục CSS.