Bạn đã biết cách dùng đơn vị % trong CSS chưa? Bạn có gặp phải vấn đề gì khi dùng phần trăm trong CSS? Hãy cùng Quantrimang.com tìm hiểu nhé!
Cách đây không lâu, chúng ta hoàn toàn dựa vào việc dùng phần trăm cho chiều rộng và cao. Dùng phần trăm có nghĩa bố cục và các phần tử của bạn có thể có chiều cao và rộng dựa trên chế độ xem. Thế nhưng, CSS hiện đại liên tục phát triển, thậm chí giờ lập trình viên không nhất thiết phải dùng tới đơn vị %.
Hãy cùng Quantrimang.com tìm hiểu về những vấn đề bạn sẽ gặp phải khi dùng phần trăm và các kỹ thuật CSS hiện đại thay thế cho phần trăm. Chúng sẽ cho bạn kết quả tương tự mà không gặp phải bất kỳ trở ngại nào.
Ví dụ một mẫu grid (kẻ ô) đơn giản
Để minh họa vấn đề với đơn vị phần trăm, cân nhắc bố cục HTML này:
<div class="container my-grid">
<div class="grid-item">
</div>
<div class="grid-item">
</div>
</div>
Phần tử bên ngoài là một container div cơ bản với hai div con bên trong. Mỗi con có một class grid-item. Để biến container này thành grid với 2 cột (hai hộp), bạn cần áp dụng code CSS sau:
body {
background-color: black;
align-items: center;
justify-content: flex-start;
}
.my-grid {
display: grid;
grid-template-columns: 50% 50%;
margin: 3rem;
border: 2px solid gold;
padding: 1rem;
}
.grid-item {
border: 3px solid gold;
padding: 10rem 0;
background: blue;
}
Vì thế, mỗi cột (mục grid) đều có màu nền vàng. Trên class cấp cha, đặt grid-template-column sang 50% cho mỗi cột. Kết quả, cả hai box chiếm 50% tổng chiều rộng của phần tử container.
Kết quả:
Thế nhưng có vấn đề xảy ra với sự sắp xếp này. Đầu tiên, nếu bạn quyết định thêm một khoảng trống vào grid cấp cha, phần tử con có thể bị tràn ra bên ngoài. Ví dụ, nếu đã thêm gap: 3px vào khối .my-grid trong CSS, bố cục của nó trông sẽ như sau:
Như bạn có thể thấy ở hình ảnh trên, box bên phải đã được chuyển ra ngoài container. Thỉnh thoảng, bạn có thể không nhận ra nó bởi khoảng cách đủ nhỏ để gây ra lỗi căn chỉnh kỳ lạ. Thế nhưng, nếu có khoảng cách lớn hơn, sự chồng chéo trở nên khá rõ ràng.
Bất cứ khi nào bạn đang dùng phần trăm và thêm lề hoặc khoảng cách, khả năng cao bạn sẽ gặp phải những lỗi như thế. Thế nhưng, tại sao lỗi đó lại xảy ra?
Nguyên nhân bởi mỗi cột chiếm 50% của phần tử cha. Ví dụ trên có 50% cộng 50% khoảng cách đó (3px), đẩy hộp ra ngoài container.
Lưu ý rằng lỗi này không chỉ xảy ra với tỷ lệ 50-50. Bạn có thể đặt cột đầu tiên là 75%, cột thứ hai là 25% và lỗi vẫn sẽ xảy ra. Đây là lí do tại sao bạn cần dùng giải pháp sau thường xuyên hơn.
Giải pháp với các giá trị phân số
Giải pháp ở đây là dùng giá trị phân số thay cho phần trăm. Vì thế, thay vì đặt cột đầu tiên sang 75% và thứ hai sang 50%, bạn có thể đặt cột đầu tiên sang 3fr và cột thứ hia là 1fr:
grid-template-columns: 3fr 1fr
Diều này duy trì tỷ lệ giống như ở ví dụ đầu tiên. Thế nhưng ưu điểm của việc dùng các đơn vị fr là sử dụng phân số của khoảng cách sẵn có. Trong trường hợp này, cột đầu tiên sẽ chiếm 3 phần khoảng cách, còn cột thứ hai sẽ chiếm một phần, không bao gồm khoảng cách.
Ưu điểm khác của việc dùng frs trên phần trăm hoặc đơn giản tuyệt đối khác như px hoặc rem là bạn có thể kết hợp chúng với các giá trị cố định. Ví dụ:
grid-template-columns: 1fr 10rem;
Với code trên, bạn sẽ có một giá trị cố định chưa từng thay đổi theo kích thước màn hình. Đó là do cột ở bên phải sẽ luôn duy trì ở mức 10rem, còn cột bên trái sẽ chiếm phần không gian còn lại (trừ đi khoảng cách).
Đôi khi, bạn không cần dùng phần trăm. Nhưng bạn phải sử dụng chúng theo cách thông minh, sao cho vẫn đáp ứng được tình huống này. Điều đó thường có nghĩa ghép cặp chúng với một giá trị fr.
Ví dụ thực tế khác
Hãy tưởng tượng bạn có một trang bao gồm vùng nội dung chính và một trang phụ (cho bài viết liên quan). Nội dung chính chiếm 3 phần của màn hình, còn phụ chiếm phần không gian còn lại trừ đi khoảng cách:
.container {
width: 100%;
display: grid;
grid-template-columns: 3fr 1fr;
gap: 1.5rem;
}
.card {
background-color: #5A5A5A;
padding: 10px;
margin-bottom: .5rem;
}
Kết quả:
Thông thường, bạn sẽ di chuyển thanh bên sườn tới phần dưới cùng (hoặc trên) của trang khi màn hình trở nên quá nhỏ. Điều này có nghĩa thiết lập các truy vấn media xếp chồng mọi thứ lên nhau khi chế độ xem đạt tới điểm ngắt nhất định.
Đây là cách bạn có thể xếp chồng mọi thứ thành một cột khi chế độ xem đạt 55em hoặc ít hơn:
@media(max-width: 55em) {
.container {
display: flex;
flex-direction: column;
}
}
Kết quả:
Giờ bạn không muốn mỗi thẻ mở rộng chiều dài của toàn bộ chế độ xem. Thay vì để thẻ hiển thị lần lượt. Cách tốt nhất để đạt được điều này là dùng các grid CSS. Thế nhưng thay vì đặt các giá trị chiều rộng cố định (như 50%) cho grid-template-column, dùng hàm repeat() như sau:
.sidebar-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
align-content: start;
gap: 2rem;
}
CSS này đặt kích thước tối thiểu là 25rem và tối đa là 1fr. Phương pháp tiếp cận này tốt hơn nhiều so với việc đặt chiều rộng cố định bởi nó dựa vào kích thước nội tại. Nói cách khác, nó cho phép trình duyệt tìm ra mọi thứ dựa trên các tham số sẵn có.
Giờ khi giảm cửa sổ trình duyệt xuống chiều rộng cụ thể, box grid sẽ tự động điều chỉnh lại thành hai box mỗi dòng.
Khi màn hình nhỏ hơn, nó còn một box mỗi dòng. Vì thế, trình duyệt này xếp chồng mọi thứ lên trên những thứ khác. Tất cả điều này xảy ra khi bạn chỉnh lại kích thước cửa sổ. Bạn có thể dùng tính năng trình duyệt như Chrome DevTools để hiểu cách CSS hoạt động ở đây cũng như việc chỉnh lại kích thước cửa sổ thay đổi bố cục như thế nào.
Phần tuyệt nhất ở đây là bạn không cần một truy vấn container hoặc bất kỳ thứ gì lạ mắt để làm nhân tố phản hồi. Chỉ cần đặt một lưới và dùng min-max() để đặt các giá trị phân số thay cho các kích thước cố định.
Trên đây là lựa chọn thay thế cho đơn vị phần trăm trong CSS. Hi vọng bài viết hữu ích với các bạn.