5 Responsive ảnh bằng HTML
Responsive (tính từ): nghĩa là khả năng thích ứng, tùy chỉnh.
Trong lĩnh vực web, responsive là khả năng thay đổi giao diện tùy theo kích thước màn hình. Ý tưởng là bạn sẽ viết mã nguồn sao cho, tùy theo người dùng đang sử dụng thiết bị duyệt web là điện thoại (smartphone), máy tính bản (tablet), máy tính, hay TV thì trang web sẽ có giao diện tương ứng với từng loại, phù hợp, đẹp, dễ đọc.
Đối với hình ảnh, nếu người dùng đang sử dụng màn hình nhỏ, mà trang web lại thực hiện tải về một hình ảnh lớn thì sẽ làm chậm quá trình hiển thị, lãng phí tài nguyên thiết bị; ngược lại nếu người dùng đang sử dụng màn hình lớn mà lại tải về một hình ảnh nhỏ, độ phân giải thấp thì sẽ làm cho hình ảnh bị mờ, không đẹp.
Kỹ thuật hay được sử dụng để responsive là dùng CSS. Tuy nhiên, phần này sẽ giới thiệu kỹ thuật responsive hình ảnh bằng HTML.
Ý tưởng của responsive hình ảnh bằng HTML là bạn sẽ tạo ra nhiều hình ảnh cho nhiều kích thước màn hình khác nhau; khi hiển thị trang web, trình duyệt sẽ tự động chọn hình ảnh cho phù hợp, dựa vào các yếu tố như kích thước, độ phân giải của màn hình, tốc độ đường truyền, có lưu bộ đệm hay không.
Để responsive hình ảnh, cần chuẩn bị cho bốn tình huống sau:
– Cung cấp ảnh chất lượng cho các màn hình có độ phân giải cao
– Cung cấp một bộ ảnh với kích thước (dimension) đa dạng cho các loại màn hình có kích thước khác nhau
– Cung cấp nhiều phiên bản của một ảnh với nội dung và các kiểu dáng (portrait, landscape) khác nhau
– Cung cấp các định dạng khác nhau của một ảnh với dung lượng nhỏ
Hiển thị ảnh cho màn hình có độ phân giải cao
Mọi thứ bạn thấy trên màn hình đều được tạo ra từ các tia sáng màu, hình vuông, kích thước rất nhỏ, gọi là phần tử ảnh (picture element), thường gọi là pixel. Các pixel do thiết bị tạo ra nên gọi là device pixel (hoặc hardware pixel, physical pixel).
Trên các màn hình hiện tại, số device pixel trên một inch thường là 72, 96, 109, 160, 326, và cao hơn.
Số device pixel trên một inch được gọi là độ phân giải của màn hình (pixel per inch), được gọi tắt là ppi.
Ảnh có định dạng kiểu bitmap (jpeg, png, gif) cũng được tạo ra từ các phần tử ảnh (pixel), các pixel được tổ chức theo kiểu lưới (grid).
Trước đây, các pixel của ảnh (cũng như pixel trong CSS) có tỉ lệ 1:1 với pixel trên thiết bị, nghĩa là với một ảnh có độ rộng 100 pixel sẽ được đặt tương ứng trên 100 pixel của thiết bị. Mọi chuyện thật đơn giản.
Device-pixel-ratios
Tuy nhiên, các thiết bị hiện nay có độ phân giải cao, nghĩa là số pixel/inch lớn, nếu đặt ảnh vào màn hình theo tỉ lệ 1:1 thì sẽ thấy ảnh bị thu nhỏ lại. Bạn thử tưởng tượng, bình thường 100 pixel ảnh sẽ tạo được một khối ảnh dài một inch trên màn hình, nhưng cũng 100 pixel ảnh ấy chỉ tạo được một khối ảnh có chiều dài 0.3 inch trên màn hình thôi, nghĩa là kích thước của ảnh trên màn hình đã giảm đi gần ba lần.
Để giải quyết tình trạng không tương thích về độ phân giải giữa ảnh và thiết bị, người ta đưa ra thêm một đơn vị để xác định độ phân giải của thiết bị là “pixel tham chiếu” (reference pixel) hay pixel CSS. Mục đích của pixel tham chiếu là để sử dụng trong quá trình hiển thị nội dung ra giao diện (layout).
Pixel tham chiếu còn có tên gọi khác là point (PT) trong iOS, hoặc device independent pixel (DP, DiP) trong Android hoặc CSS pixel trong CSS.
Ví dụ, iPhone 8 có kích thước màn hình tính theo device pixel là 750 x 1334, nhưng nó lại dùng lưới hiển thị (layout grid, có thể hiểu là “màn hình giả”) theo point (hay CSS pixel) là 375 x 667. Nghĩa là tỉ lệ giữa đơn vị đo device pixel và CSS pixel là 2:1 (hay 2x); hay nói cách khác, một CSS pixel của ảnh sẽ được đặt vào hai device pixel trên màn hình. Vậy, một cái hộp có độ rộng 100 pixel trong CSS khi hiển thị trên màn hình iPhone 8 sẽ được đặt trong 200 pixel. Tương tự, iPhone X có kích thước màn hình tính theo device pixel là 1125 x 2436, dùng lưới hiển thị (layout grid) là 375 x 812. Vậy, tỉ lệ giữa đơn vị đo device pixel và CSS pixel là 3:1 (hay 3x); nghĩa là một CSS pixel của ảnh sẽ được đặt vào ba device pixel trên màn hình. Kết quả là một cái hộp có độ rộng 100 pixel trong CSS khi hiển thị trên màn hình iPhone X sẽ được đặt trong 300 pixel.
Tỉ lệ giữa device pixel và CSS pixel được gọi là device-pixel-ratios. Với các thiết bị cầm tay, device-pixel-ratios thường là 1.325x, 1.5x, 1.7x, 2.4x, 3x, thậm chí 4.x (ký hiệu ‘x’ được ngầm hiểu là device-pixel-ratios, gọi là x-descriptor).
Xem hình minh họa về device-pixel-ratios,
Kết luận rút ra ở đây là nếu bạn muốn hiển thị một ảnh có độ rộng 200px trên một thiết bị có device-pixel-ratios là 1x thì bạn cần chuẩn bị một ảnh 200px, nhưng nếu hiển thị trên các thiết bị có device-pixel-ratios là 2x, 3x, thì bạn phải chuẩn bị ảnh có độ rộng là 400px và 600px tương ứng, nếu không ảnh sẽ bị mờ. Như vậy, tùy theo độ phân giải của màn hình, bạn cần lựa chọn ảnh phù hợp để tải xuống thiết bị.
Thuộc tính srcset
Để lựa chọn ảnh phù hợp cho từng độ phân giải của màn hình, bạn sẽ sử dụng thuộc tính srcset cùng với phần tử img. Sử dụng thuộc tính srcset để liệt kê một danh sách các tập tin ảnh, khi thực thi mã HTML, trình duyệt sẽ lựa chọn ảnh phù hợp từ danh sách này.
Giá trị của thuộc tính srcset gồm các cặp image-URL và x-descriptor, mỗi cặp ngăn cách nhau bằng dấu phẩy (,). Ví dụ:
srcset="image-URL #x, image-URL #x"
Trong phần tử img, vẫn có thuộc tính src, đây là đường dẫn của ảnh cho trường hợp giá trị device-pixel-ratios của thiết bị là 1x. Thuộc tính alt cũng bắt buộc phải có. Ví dụ,
<img src="image-URL" alt="" srcset="image-URL #x, image-URL #x">
Ví dụ sau sẽ hiển thị ảnh có tên là turkey, rộng 200px trên thiết bị. Nếu thiết bị ở chế độ phân giải chuẩn (1x) thì sẽ hiển thị ảnh turkey-200px.jpg, nếu màn hình có độ phân giải cao hơn thì sẽ tải ảnh turkey-400px.jpg (cho 2x) và tải ảnh turkey-600px.jpg (cho 3x).
<img src="/images/turkey-200px.jpg" alt=""
srcset="/images/turkey-400px.jpg 2x, /images/turkey-600px.jpg 3x" >
Có thể viết lại mã nguồn cho dễ nhìn,
<img
src="/images/turkey-200px.jpg" alt=""
srcset="/images/turkey-400px.jpg 2x,
/images/turkey-600px.jpg 3x" >
Chạy đoạn mã trên, với máy laptop Dell-15”, thì ảnh turkey-400px.jpg sẽ xuất hiện trên màn hình. Kiểm tra thì thấy x-descriptor của màn hình là 1.75. Đây là đoạn mã JavaScript để kiểm tra x-descriptor,
<script>
var scale = window.devicePixelRatio;
console.log(scale);
</script>
Khi nào thì nên dùng x-descriptor
Dựa vào giá trị của x-descriptor, trình duyệt sẽ kiểm tra độ phân giải của màn hình để lựa chọn ảnh phù hợp, mà nó không quan tâm tới kích thước của màn hình (dài, rộng) cũng như kích thước của cửa sổ trình duyệt.
Vì vậy, chỉ nên sử dụng x-descriptor đối với các ảnh nhỏ, có kích thước cố định và không ảnh hưởng nhiều đến bố cục chung của trang web, như logo, biểu tượng mạng xã hội.
Việc chỉ dựa vào độ phân giải của màn hình để lựa chọn ảnh trong thực tế là chưa tối ưu. Tình huống responsive hay được sử dụng là lựa chọn ảnh dựa vào kích thước của màn hình, với màn hình nhỏ thì hiển thị ảnh nhỏ, màn hình lớn thì hiển thị ảnh lớn.
Phần tiếp theo sẽ tìm hiểu về w-descriptor, để hiển thị ảnh theo kích thước của màn hình.
w-descriptor
Để lựa chọn ảnh theo kích thước của cửa sổ trình duyệt (browser viewport) hay kích thước của màn hình (screen) (từ đây gọi chung là cửa sổ trình duyệt) bạn sẽ sử dụng thuộc tính srcset kết hợp với giá trị w-descriptor. w-descriptor là độ rộng của cửa sổ tính bằng pixel (actual pixel width). Kĩ thuật này được gọi là lựa chọn hình ảnh theo kích thước khung nhìn (viewport-based selection).
Trình duyệt sẽ kiểm tra độ rộng của cửa sổ trình duyệt, so khớp nó với giá trị w-descriptor trong thuộc tính srcset để lựa chọn hình ảnh cho phù hợp.
Ví dụ sau đưa ra bốn hình ảnh ứng với bốn kích thước của cửa sổ trình duyệt,
srcset="strawberries-480.jpg 480w,
strawberries-960.jpg 960w,
strawberries-1280.jpg 1280w,
strawberries-2400.jpg 2400w"
Đoạn mã JavaScript để xuất độ rộng của cửa sổ trình duyệt,
<script>
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
console.log(vw);
</script>
Sử dụng thuộc tính sizes
Khi sử dụng giá trị w-descriptor thì bạn cần sử dụng thuộc tính sizes để báo cho trình duyệt biết ảnh sẽ chiếm bao nhiêu % kích thước của cửa sổ trình duyệt. Mục đích của việc này là để giúp trình duyệt có thông tin về kích thước ảnh sẽ hiển thị trên trang, nhằm tăng tốc độ xây dựng layout.
Ví dụ sau sẽ luôn hiển thị ảnh chiếm 100% kích thước cửa sổ trình duyệt,
<img src="strawberries-640.jpg"
alt="baskets of ripe strawberries"
srcset="strawberries-480.jpg 480w,
strawberries-960.jpg 960w,
strawberries-1280.jpg 1280w,
strawberries-2400.jpg 2400w"
sizes="100vw">
Đơn vị đo của sizes là vw (viewport width), 100vw tương đương với 100%, 50vw tương đương 50% kích thước cửa sổ trình duyệt. Ví dụ sau sẽ hiển thị ảnh chiếm 50% cửa sổ trình duyệt,
<img src="strawberries-640.jpg"
alt="baskets of ripe strawberries"
srcset="strawberries-480.jpg 480w,
strawberries-960.jpg 960w,
strawberries-1280.jpg 1280w,
strawberries-2400.jpg 2400w"
sizes="50vw">
Thuộc tính sizes có thể dùng ở dạng phức tạp hơn, tùy theo độ rộng của cửa sổ trình duyệt để lựa chọn giá trị size tương ứng, ví dụ,
<img src="strawberries-640.jpg" alt="baskets of ripe strawberries"
srcset="strawberries-240.jpg 240w,
strawberries-480.jpg 480w,
strawberries-672.jpg 672w"
sizes="(max-width: 480px) 100vw,
(max-width: 960px) 70vw,
240px">
Ở đoạn mã trên, nếu độ rộng cửa sổ trình duyệt bằng hoặc nhỏ hơn 480px thì hiển thị 100% độ rộng của cửa sổ, từ 481px đến 960px thì hiển thị 70%, các trường hợp còn lại hiển thị ảnh với độ rộng đúng bằng 240px.
Art direction (phần tử picture)
Ở các phần trên, chúng ta đã thực hiện lựa chọn hình ảnh dựa vào độ phân giải của màn hình và kích thước của cửa sổ trình duyệt. Cả hai trường hợp này các ảnh chỉ khác nhau ở kích thước, trong khi nội dung của ảnh không thay đổi.
Trong một số trường hợp, việc thay đổi kích thước ảnh không có nhiều ý nghĩa, ví dụ một ảnh lớn với nhiều chi tiết, nếu hiển thị ở màn hình rộng thì bạn có thể nhìn rõ các chi tiết; tuy nhiên, khi hiển thị ở màn hình nhỏ thì bạn không thể phân biệt được các chi tiết, hiệu quả của hình ảnh không cao. Trong trường hợp này, bạn chỉ muốn hiển thị một điểm nhấn nào đó trong ảnh. Hoặc bạn cũng muốn hiển thị ảnh ở dạng đứng (portrait) và dạng nằm ngang (landscape) là hai ảnh khác nhau.
Ví dụ dưới đây là ảnh ở màn hình rộng (nguồn lấy từ ebook),
Tuy nhiên, khi hiển thị ở màn hình nhỏ thì rất mờ nhạt (hình bên trái), và hình ấn tượng hơn nhờ có điểm nhấn (hình bên phải) (nguồn lấy từ ebook),
Để chọn ảnh theo độ rộng của cửa sổ trình duyệt, bạn sử dụng phần tử picture với cú pháp sau,
<picture>
<source media="(min-width: 1024px)" srcset="icecream-large.jpg">
<source media="(min-width: 760px)" srcset="icecream-medium.jpg">
<img src="icecream-small.jpg" alt="hand holding ice cream cone and
text that reads Savor the Summer">
</picture>
Ở đoạn mã trên, nếu cửa sổ trình duyệt có kích thước từ 1024px trở lên thì dùng ảnh icecream-large.jpg, nếu cửa sổ trình duyệt có kích thước từ 760 px tới 1023px thì dùng ảnh icecream-medium.jpg, nhỏ hơn thì dùng icecream-small.jpg.
Tóm lại để responsive bằng HTML, bạn có thể sử dụng thuộc tính srcset, sizes và phần tử picture.




0 Nhận xét