Bạn có biết Responsive Images trong CSS là gì và tại sao cần sử dụng nó trên website không? Hãy cùng Code Tốt khám phá cách thức làm chủ công nghệ này nhé.
Responsive Images là gì?
Khái niệm “Responsive images” chứa từ “responsive” tương tự như “responsive website” mà chúng ta hay thấy. Ta có thể tạm dịch là công nghệ “ảnh tương thích nhiều màn hình”.
Responsive Images trong code CSS
Responsive images được biết đến từ năm 2014 với các thuộc tính “srcset” và “sizes” trong markup HTML của thẻ <img>
và <picture>
. Tuy nhiên, bài viết này sẽ tìm hiểu cách thức responsive images có thể hoạt động tương đồng trong file style giao diện CSS như thế nào.
srcset
trong CSS
Trong HTML, srcset
thường trông như thế này:
<img srcset=" images/[email protected] 1x, images/[email protected] 2x " alt="Intro Image">
Ảnh [email protected]
là ảnh cho các màn hình bình thường, và ảnh [email protected]
là ảnh cho các màn hình retina (thông thường là Macbook). Nếu ta muốn làm như vậy bằng CSS, ta sẽ viết như sau:
.img { background-image: url('images/[email protected]'); } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .img { background-image: url('images/[email protected]'); } }
Bạn thấy đấy, trông có sự khác nhau phải không? srcset
dường như mang lại gợi ý cho trình duyệt, và bản thân trình duyệt quyết định sẽ chọn ảnh nào phù hợp. Cách thức CSS cũng là tương tự. Các thuộc tính trong CSS @media
thì đã được các trình duyệt hỗ trợ rồi.
Ngoài ra, trong CSS ta có thể sử dụng image-set()
như sau:
.img { background-image: url(examples/images/image-384.jpg); background-image: image-set( url('images/[email protected]') 1x, url('images/[email protected]') 2x, ); }
Tất nhiên, tính đến sự hỗ trợ của trình duyệt của image-set()
thì không phổ thông lắm. Mặc dù trông nó có vẻ giống srcset
của HTML, nhưng nó cũng không dễ dàng gì thay thế thuộc tính này.
Thuộc tính sizes
trong CSS
Bạn có biết thuộc tính sizes
trong markup HTML được thể hiện như thế nào không? Dưới đây là ví dụ:
<img sizes="(min-width: 40em) 80vw, 100vw" srcset=" ... " alt="…">
Và trông nó sẽ có vẻ giống như thế này trong CSS:
img.image { width: 100%; } @media (min-width: 40em) { .parent-image-block { width: 80%; } }
Nhưng sizes
nếu không sử dụng srcset
thì thực ra không làm gì cả. Chẳng hạn, để sizes
làm việc, markup HTML cần viết như sau:
<img sizes="(min-width: 400px) 80vw, 100vw" srcset="images/small.jpg 375w, images/big.jpg 1500w" alt="…">
Markup ở trên cung cấp cho trình duyệt thông tin để lựa chọn file ảnh tốt nhất, chẳng hạn:
Nếu viewport trình duyệt là 320px và không phải retina, tức là ảnh sẽ hiển thị ở 100vw
. Trình duyệt sẽ làm phép tính tỷ lệ để lấy ra ảnh tốt nhất:
- Ảnh 1: 375 / 320 = 1.17
- Ảnh 2: 1500 / 320 = 4.69
Vì 1.17 gần với 1 (do không phải màn hình retina 2x), nên ảnh nào xác định 375w
trong srcset
sẽ được chọn.
Giờ hãy thử lấy ví dụ với màn hình retina, trình duyệt sẽ nhẩm như sau:
- Ảnh 1: 375 / 640 = 0.59
- Ảnh 2: 1500 / 640 = 2.34
Như vậy ảnh 2 có tỷ lệ sát với 2 nên được chọn.
Với logic dạng này, thật khó để diễn giải và sử dụng nó tương đồng trong CSS. Ta tạm thời cắt nghĩa và dịch nôm phần logic ra như sau:
- Nếu trình duyệt có viewport nhỏ hơn 375px, sử dụng ảnh
375w
. - Nếu trình duyệt có viewport lớn hơn 375px, nhưng nhỏ hơn 400px, sử dụng ảnh
1500w
. - Ở khung 400px, ảnh chuyển sang kích thước
80vw
, tức là vẫn có thể sử dụng ảnh375w
. - Trên 468px, chỉ dùng ảnh
1500w
.
Như vậy, bằng CSS, ta thể hiện như sau:
img { background-image: url(small.jpg); } @media (min-width: 375px) and (max-width: 400px), (min-width: 468px) { .parent-image-block { background-image: url(large.jpg); } }
Trong cụ thể tình huống ví dụ ở trên, ở khung hình retina, mặc dù có khung hình 300px thì vẫn cần ảnh có kích thước là 600px, nên ta thêm vào logic thành:
img.image { background-image: url('small.jpg'); } @media (min-width: 375px) and (max-width: 400px), (min-width: 468px), (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .parent-image-block { background-image: url('large.jpg'); } }
Sự thay đổi này làm tăng các điểm thay đổi hình ảnh. Dù vậy, nó không phải phương án hoàn hảo và cũng có thể ảnh hưởng tới các yếu tố tốc độ web, ví dụ như băng thông tải về trình duyệt.
Kết luận
Qua sự phân tích về cách ta sử dụng hai thuộc tính srcset
và sizes
trong markup HTML và chuyển đổi nó qua logic của CSS, mình hi vọng các bạn nắm được cách thức ta sử dụng trong CSS. Dẫu vậy, bạn vẫn nên cân nhắc sử dụng markup HTML thay vì trong CSS để dễ dàng thiết lập các yếu tố giúp trình duyệt lựa chọn phương án tối ưu hơn.
Bài viết lược dịch từ CSS-Trick.
Giám đốc tại Công ty CP CODE TỐT. Quản lý ngôn ngữ bản địa tiếng Việt tại WordPress. Là tác giả chính tại codetot.net, Khôi muốn ghi lại một sốvấn đề kỹ thuật trong quá trình phát triển các dự án website với khách hàng.