Explore CSS 3D Transforms, transformation matrices, setting viewport depth with perspective, and card flip implementations using preserve-3d and backface-visibility.
This lesson is currently only available in Vietnamese. Please switch the language toggle in the menu to Vietnamese to read the full guide and take the interactive quiz.
Hầu hết giao diện trang web được thiết kế phẳng trên không gian 2D trục $X$ (ngang) và $Y$ (dọc). Tuy nhiên, CSS hiện đại cho phép chúng ta phá vỡ giới hạn này bằng cách bổ sung trục $Z$ (sâu thẳng về phía mắt người nhìn), biến trình duyệt thành một không gian đồ họa 3 chiều chân thực.
Trong bài này, chúng ta sẽ đi sâu vào toán học của các phép biến đổi ma trận (Transform Matrices), cơ
chế phối cảnh Perspective và các thuộc tính dựng hình 3D nâng cao như preserve-3d và
backface-visibility.
1. Hệ tọa độ 3D trong CSS & Ma trận biến đổi
Hệ tọa độ 3D của CSS được định nghĩa như sau:
- Trục X: Hướng nằm ngang, tăng từ trái sang phải.
- Trục Y: Hướng dọc, tăng từ trên xuống dưới (đặc thù đồ họa máy tính).
- Trục Z: Hướng chiều sâu, tăng từ màn hình hướng về phía mắt người xem.
Mọi phép biến đổi 3D (dịch chuyển, xoay, co giãn) thực chất là các phép nhân ma trận đối với tọa độ điểm trong không gian thuần nhất. CSS biểu diễn chúng bằng một ma trận biến đổi $4 \times 4$:
Ví dụ, ma trận dịch chuyển 3D (3D Translation Matrix) với độ dời $(t_x, t_y, t_z)$:
\[\begin{bmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix}\] \[\begin{bmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}\]matrix() và matrix3d() trong CSS, bạn có thể tham khảo các nguồn uy tín
sau:
- MDN Web Docs - Toán học ma trận cho Web Designer : Hướng dẫn cơ bản dễ hiểu cách dịch chuyển, xoay, co giãn, nghiêng hệ tọa độ bằng nhân ma trận.
- W3C CSS Transforms Level 2 - Mathematics : Định nghĩa đặc tả toán học chính thức từ W3C cho việc biểu diễn và nhân ma trận 3D trong CSS.
- Khan Academy - Matrix Transformations : Các bài giảng trực quan về toán học ma trận chuyển đổi hình học trong môn Đại số tuyến tính.
- 3Blue1Brown - Essence of Linear Algebra : Chuỗi video trực quan hóa cực kỳ nổi tiếng giải thích trực giác hình học của phép nhân ma trận và biến đổi tuyến tính.
2. Perspective — Phối cảnh và Khoảng cách điểm nhìn
Nếu bạn xoay một phần tử 3D quanh trục $Y$ nhưng không thiết lập phối cảnh (Perspective), bạn sẽ không thấy bất kỳ chiều sâu nào cả. Phần tử chỉ trông như bị dẹt lại theo chiều ngang. Đó là bởi vì chưa có phép chiếu góc nhìn lên màn hình.
Thuộc tính perspective xác định khoảng cách từ mắt người xem (điểm nhìn) đến mặt phẳng
$Z=0$ (màn hình), ký hiệu là $d$. Công thức phối cảnh toán học để tính tọa độ được chiếu $(x', y')$ từ
tọa độ gốc $(x, y, z)$ là:
- Gán perspective lên thẻ CHA: Thiết lập một điểm nhìn duy nhất (Single Viewpoint) cho toàn bộ không gian. Phù hợp để làm các cảnh nhiều phần tử (như các mặt của khối rubik) vì góc chiếu lên các con sẽ xiên lệch tự nhiên tùy theo vị trí của chúng.
- Gán transform: perspective(d) lên phần tử CON: Mỗi phần tử tự sở hữu một điểm nhìn độc lập nằm ngay tâm của nó. Các phần tử sẽ được chiếu thẳng góc, không có sự xiên lệch tự nhiên giữa các phần tử cạnh nhau.
3. preserve-3d và backface-visibility
Khi thiết kế các khối 3D phức tạp chứa các mặt phẳng con lồng nhau, ta bắt buộc phải cấu hình:
-
transform-style: preserve-3d; Chỉ định cho trình duyệt bảo toàn không gian 3D của
các phần tử con. Nếu để mặc định (
flat), các con sẽ bị ép dẹt phẳng (flattened) lên mặt phẳng của thẻ cha. - backface-visibility: hidden; Ẩn mặt sau của phần tử khi nó quay lưng về phía người xem. Rất hữu dụng khi làm hiệu ứng lật thẻ 2 mặt (để mặt trước không bị nhìn xuyên thấu ngược qua mặt sau).
Sân chơi tương tác: 3D Graphics Lab
Sân chơi tương tác dưới đây mô phỏng hiệu ứng Lật thẻ 3D hai mặt (Card Flip). Bạn hãy thay đổi các góc xoay $X, Y$, tiêu cự góc nhìn $d$ (perspective) và bật/tắt các thuộc tính 3D để trực quan hóa cách trình duyệt render chiều sâu đồ họa:
Thiết lập Không gian 3D
<div class="card-scene">
<div class="card-3d">
<!-- Mặt trước -->
<div class="card-face card-face-front">
<div class="chip"></div>
<div class="number">4000 1234 5678 9010</div>
</div>
<!-- Mặt sau -->
<div class="card-face card-face-back">
<div class="secret">ACCESS GRANTED</div>
</div>
</div>
</div>
Trắc nghiệm ôn tập
Câu 1: Điều gì xảy ra đối với các phần tử 3D lồng nhau nếu thuộc tính transform-style của thẻ cha được gán là 'flat'?
Trắc nghiệm ôn tập
Câu 2: Điểm khác biệt cốt lõi khi khai báo 'perspective: 500px' trên thẻ CHA so với 'transform: perspective(500px)' trên thẻ CON là gì?