Bài viết được sự cho phép của tác giả Trần Anh Tuấn
Đối với Frontend Developer thì việc tối ưu giao diện Responsive là điều hiển nhiên rồi. Và chúng ta thông thường từ trước đến giờ là dùng Media Queries để làm việc đó. Đối với font-size thì mình đã giới thiệu cho các bạn cách làm ở bài viết sử dụng hàm clamp trong CSS rồi.
Vậy thì còn cách nào khác để làm Responsive cho giao diện mà không hoặc ít dùng tới Media Queries không ? Tất nhiên là có rồi, và mình rất háo hức giới thiệu cho các bạn ngay sau đây Container Queries.
Đầu tiên chúng ta phải hiểu rằng khi sử dụng MQ (Media queries) thì chúng ta sẽ dựa vào Viewport của màn hình sẽ có các breakpoints như 1024, 1280, 768…. Tuy nhiên khi sử dụng CQ (Container Queries) thì sẽ dựa vào độ rộng của Container. Container là gì thì mình sẽ ví dụ cho các bạn sau đây
Giao diện ở trên là Sidebar ở phía bên trái, còn bên phải là Main, trong Main chứa Card với cấu trúc HTML và CSS như sau:
<div class="wrapper"> <div class="sidebar"></div> <div class="main"> <div class="card"> <div class="card-image"> <img src="https://images.unsplash.com/" alt="" /> </div> <div class="card-conten <p class="card-city">New York</p> <h3 class="card-title"> New York City’s air pollution among the world’s worst as Canada wildfire smoke shrouds Northeast </h3> </div> </div> </div> </div>
.wrapper { display: grid; grid-template-columns: 250px minmax(0, 1fr); grid-gap: 20px; height: 100vh; } .sidebar { border-right: 1px solid #eee; } .main { padding: 20px; } .card { display: flex; gap: 20px; } .card-image { overflow: hidden; width: 100%; flex: 0 0 200px; } .card-image img { border-radius: 12px; width: 100%; height: 100%; object-fit: cover; } .card-content { padding: 20px 0; flex: 1; } .card-city { font-size: 14px; margin-bottom: 10px; color: #333; } .card-title { font-size: 18px; font-weight: bold; line-height: 1.5; }
Khi ở màn hình tầm < 900px thì giao diện sẽ hiển thị như sau
Các bạn sẽ thấy một vấn đề là .card
giao diện hiển thị như vầy nó không ổn một chút nào cả. Vì có thể kết quả mà chúng ta muốn là như dưới đây. Nếu vậy thì có thể chúng ta sẽ dùng MQ cho màn hình < 900px thay đổi flex-direction: column
là xong xuôi.
/* Media queries */ @media screen and (max-width: 900px) { .card { flex-direction: column; } }
Tuy nhiên chúng ta sẽ gặp một vấn đề nữa là khi màn hình < 800px thì Sidebar đã bị ẩn cho nên thằng Main sẽ tràn ra chiếm hết diện tích và lúc này thằng .card
nó bị như dưới thì lại xấu quá, đáng lẽ nó nên nằm ngang như ở màn hình máy tính thì có lẽ sẽ đẹp hơn.
/* Media queries */ @media screen and (max-width: 800px) { .sidebar { display: none; } .wrapper { display: block; } .card { flex-direction: row; } }
Để giải quyết nó thì chúng ta lại phải code thêm MQ cho một màn hình < 800px cho nó flex-direction: row
lại, rồi khi màn hình < 480px thì lại thiết lập flex-direction: column
lại nữa. Đọc thôi là thấy code rất chi là nhiều và rối rồi đó
@media screen and (max-width: 480px) { .card { flex-direction: column; } }
Dùng MQ phức tạp quá, nhưng không sao, Container Queries đến để giải cứu vấn đề này. Để sử dụng CQ, thì chúng ta sẽ code vào phần tử bao ngoài chứa phần tử bên trong mà chúng ta muốn xử lý giao diện. Đối với cấu trúc HTML ở trên thì thằng chúng ta muốn xử lý giao diện là .card
, và phần tử bao ngoài của nó(trong trường hợp này) là .main
Tham khảo việc làm CSS Hồ Chí Minh hấp dẫn trên TopDev
DÀNH CHO BẠN:
Mình có khoá học HTML CSS từ cơ bản tới nâng cao cho người mới, nếu bạn quan tâm thì bạn có thể học thử miễn phí bằng việc nhấn vào đây nha.
Lưu ý: Phần tử sử dụng Container Queries không nhất thiết phải là thằng gần nhất, tùy thuộc vào logic của giao diện.
/* container queries */ .main { container-name: card; container-type: inline-size; } @container card (max-width: 500px) { .card { flex-direction: column; } }
Như các bạn thấy đoạn code ở trên thì để sử dụng CQ, ở class .main
mình sử dụng đoạn container-name: card
và container-type: inline-size
. Container name là không bắt buộc, tuy nhiên mình khuyến khích các bạn đặt tên cho dễ nhận biết nhé
Để sử dụng thì các bạn viết như này, nhớ thay ContainerName thành tên nào tùy vào logic của các bạn nha.
.some-class{ container-name: ContainerName; container-type: inline-size; } @container ContainerName (min or max width, h // code }
Các bạn có thể xem trực tiếp kết quả của ví dụ từ nãy đến giờ dưới này hoặc nhấn vào đây để xem toàn trang nhé.
Lưu ý: Phần tử sử dụng Container Queries thì không áp dụng
@container
vào chính nó được, mà chỉ áp dụng vào phần tử con của nó như mình đã làm ví dụ ở trên. Một ví dụ sai ở dưới đây cho các bạn biết mà tránh.
.main { container-name: card; container-type: inline-size; } @container card (max-width: 500px) { .main { flex-direction: column; } }
Hi vọng thông qua kiến thức mới này sẽ giúp các bạn sẽ có thêm cách về việc xử lý giao diện Responsive một cách xịn xò hơn. Ngoài ra các bạn có thể nhấn vào đây để tham khảo thêm nhiều giao diện có sử dụng Container Queries cực xịn xò của tác giả IShadeed. Cuối cùng mấu chốt để hiểu và làm tốt đó chính là thực hành nhiều vào các bạn nhé.
Bài viết gốc được đăng tải tại evondev.com
Có thể bạn quan tâm:
- Sử dụng Sqlite trong Android như thế nào hiệu quả nhất?
- Một số nguyên tắc thiết kế UI/UX website
- Nên sử dụng đơn vị EM hay REM?
Xem thêm Việc làm IT hấp dẫn trên TopDev