Hôm nay chúng ta sẽ nói về hình ảnh web responsive, một chủ đề rất phổ biến và khá nhiều vấn đề.

Nếu bạn tìm kiếm chủ đề này, bạn sẽ tìm thấy vô số bài viết với đủ loại giải thích, tuy nhiên tôi sẽ không lặp lại những điều đó mà dạy bạn theo cách khác.

Tải hình ảnh đúng cách, tăng thứ hạng SEO và mang lại trải nghiệm người dùng tốt hơn cho trang web của bạn.

Hình ảnh responsive là gì?

Hình ảnh responsive sẽ (nên) tự động điều chỉnh để phù hợp với kích thước màn hình. Nhưng… đó có phải là cách làm đúng không? Vâng, vừa có vừa không. Nếu bạn tìm trên Google hoặc xem các framework hiện đại như Bootstrap, bạn sẽ nhận thấy định nghĩa “hình ảnh responsive” của họ là một CSS đơn giản tương tự như:

1max-width: 100%;
2height: auto;

Mặc dù điều này “hoạt động”, nhưng không hoàn toàn đúng. Có nhiều lý do, nhưng quan trọng nhất là kích thước hình ảnh. Tôi không nói về “chiều rộng/chiều cao” của hình ảnh, tôi đang nói về kích thước thực tế của hình ảnh tính bằng kilobyte/megabyte.

Hầu hết các trang web (khoảng 80% các trang web tôi đã thấy trong tất cả những năm qua) sử dụng hình ảnh cực kỳ lớn và đơn giản “co giãn” chúng lên xuống. Một hình ảnh như vậy thường từ 1000px đến thậm chí 4000px và tôi thậm chí đã thấy 8000px!!! (điên rồ biết bao).

Những hình ảnh này thường rất nặng, từ 1 MB đến 10 và thậm chí 20 MB. Tôi rất hiếm khi thấy người ta nén hình ảnh khi xuất. Với điều đó, hãy tưởng tượng khi bạn có một trang web nhiều hình ảnh gồm 5, 10, 20 hoặc nhiều hình hơn và người dùng truy cập trang web trên Điện thoại. Ngay cả trên 5G, đó là rất nhiều dữ liệu cần tải chỉ cho hình ảnh, chưa kể phần còn lại.

Cách tạo hình ảnh responsive?

Trình duyệt hỗ trợ chúng ta với image source set (srcset). Với tính năng này chúng ta có thể hiệu quả có nhiều phiên bản hình ảnh ở các kích thước khác nhau và trình duyệt sẽ chọn đúng cái dựa trên kích thước màn hình. Đó mới là responsive!

Tuy nhiên, hầu hết mọi người không thể xử lý image source set vì nhiều lý do, từ “Tôi không biết” đến “Tôi không hiểu” và nhiều lý do khác.

Khi công nghệ phát triển, chúng ta có thể sử dụng các công cụ trực tuyến và API để tạo các source set này tự động. Nhưng đừng vội, tạo tự động không có nghĩa là bạn có thể đơn giản sao chép kết quả và mong đợi nó hoạt động đúng.

Từ tất cả công việc và kiểm thử của tôi, không có giải pháp “vạn năng” và luôn cần thêm công việc.

Chọn thẻ HTML phù hợp cho hình ảnh

Đây là điều đầu tiên và quan trọng nhất bạn phải hiểu. Bạn có thể sử dụng thẻ <img /> truyền thống hoặc thẻ <picture> hiện đại.

Mỗi loại đều có nhược điểm riêng, nhưng từ kinh nghiệm của tôi <picture> luôn thắng. Thẻ này được hỗ trợ rộng rãi bởi trình duyệt nên không phải là vấn đề.

Không có cách tự động để tạo kích thước chính xác (theo tôi biết) cho một trang web động. Ví dụ WordPress nổi tiếng, nó sẽ tạo kích thước không đều và sai tùy thuộc vào hình ảnh bạn tải lên và đặt ở đâu.

Sử dụng thẻ img

Thẻ img có trên đa số trang web; cho hình ảnh responsive thẻ <img /> được kết hợp với thuộc tính srcset, nhưng tôi có thể tự tin nói rằng không cái nào hoạt động đúng.

Một trong những vấn đề là thẻ <img /> không hoạt động đúng trên một số trình duyệt, ví dụ Chrome. Tôi thực sự có một câu hỏi mở trên stackoverflow.com về vấn đề này mà không có giải thích tại sao.

Vấn đề khác là việc thiết lập đúng thuộc tính sizes rất khó khăn. Có rất nhiều bài viết với giải thích rất mơ hồ và không đầy đủ mà thực sự tôi thấy rất bực bội.

Với những điều trên, tôi sẽ không thảo luận việc sử dụng <img /> cho hình ảnh responsive vì nó vô nghĩa (theo ý kiến của tôi).

Sử dụng thẻ picture

Thẻ picture là tốt nhất theo quan điểm của tôi, cho phép chúng ta điều khiển và hướng dẫn trình duyệt tải hình ảnh mà chúng ta muốn.

Nó cũng hỗ trợ nhiều tính năng khác như chỉ định art direction, định dạng hình ảnh thay thế và nhiều hơn nữa. Với bộ khả năng tuyệt vời này chúng ta có thể đạt được mục tiêu.

Không vấn đề gì, đã đến lúc trình duyệt này chết trong năm nay .

Tạo kích thước hình ảnh responsive

Như đã đề cập ở trên, chúng ta có thể sử dụng nhiều công cụ trực tuyến để thay đổi kích thước và tạo hình ảnh đúng cùng mã nguồn chỉ với vài cú nhấp chuột.

Tôi khuyên bạn sử dụng công cụ này: https://responsivebreakpoints.com/ làm điểm bắt đầu. Công cụ sẽ thay đổi kích thước hình ảnh và tạo các breakpoint để có hình ảnh responsive.

Ví dụ bức ảnh con chó trên trang web của họ sẽ có nhiều hình ảnh được thay đổi kích thước khác nhau và mã HTML tương ứng:

 1<picture>
 2
 3<source
 4		media="(max-width: 767px)"
 5		sizes="(max-width: 1534px) 100vw, 1534px"
 6		srcset="
 7		dog_ar_1_1,c_fill,g_auto__c_scale,w_200.jpg 200w,
 8		dog_ar_1_1,c_fill,g_auto__c_scale,w_493.jpg 493w,
 9		dog_ar_1_1,c_fill,g_auto__c_scale,w_707.jpg 707w,
10		dog_ar_1_1,c_fill,g_auto__c_scale,w_877.jpg 877w,
11		dog_ar_1_1,c_fill,g_auto__c_scale,w_1032.jpg 1032w,
12		dog_ar_1_1,c_fill,g_auto__c_scale,w_1108.jpg 1108w,
13		dog_ar_1_1,c_fill,g_auto__c_scale,w_1259.jpg 1259w,
14		dog_ar_1_1,c_fill,g_auto__c_scale,w_1353.jpg 1353w,
15		dog_ar_1_1,c_fill,g_auto__c_scale,w_1468.jpg 1468w,
16		dog_ar_1_1,c_fill,g_auto__c_scale,w_1534.jpg 1534w">
17<source
18		media="(min-width: 768px) and (max-width: 991px)"
19		sizes="(max-width: 1983px) 70vw, 1388px"
20		srcset="
21		dog_ar_4_3,c_fill,g_auto__c_scale,w_538.jpg 538w,
22		dog_ar_4_3,c_fill,g_auto__c_scale,w_793.jpg 793w,
23		dog_ar_4_3,c_fill,g_auto__c_scale,w_1004.jpg 1004w,
24		dog_ar_4_3,c_fill,g_auto__c_scale,w_1198.jpg 1198w,
25		dog_ar_4_3,c_fill,g_auto__c_scale,w_1238.jpg 1238w,
26		dog_ar_4_3,c_fill,g_auto__c_scale,w_1384.jpg 1384w,
27		dog_ar_4_3,c_fill,g_auto__c_scale,w_1388.jpg 1388w">
28<source
29		media="(min-width: 992px) and (max-width: 1199px)"
30		sizes="(max-width: 2400px) 60vw, 1440px"
31		srcset="
32		dog_ar_16_9,c_fill,g_auto__c_scale,w_596.jpg 596w,
33		dog_ar_16_9,c_fill,g_auto__c_scale,w_877.jpg 877w,
34		dog_ar_16_9,c_fill,g_auto__c_scale,w_1086.jpg 1086w,
35		dog_ar_16_9,c_fill,g_auto__c_scale,w_1314.jpg 1314w,
36		dog_ar_16_9,c_fill,g_auto__c_scale,w_1440.jpg 1440w">
37<img
38		sizes="(max-width: 7000px) 40vw, 2800px"
39		srcset="
40		dog_c_scale,w_480.jpg 480w,
41		dog_c_scale,w_713.jpg 713w,
42		dog_c_scale,w_1036.jpg 1036w,
43		dog_c_scale,w_1180.jpg 1180w,
44		dog_c_scale,w_1313.jpg 1313w,
45		dog_c_scale,w_1433.jpg 1433w,
46		dog_c_scale,w_1606.jpg 1606w,
47		dog_c_scale,w_1748.jpg 1748w,
48		dog_c_scale,w_1884.jpg 1884w,
49		dog_c_scale,w_2015.jpg 2015w,
50		dog_c_scale,w_2133.jpg 2133w,
51		dog_c_scale,w_2260.jpg 2260w,
52		dog_c_scale,w_2377.jpg 2377w,
53		dog_c_scale,w_2345.jpg 2345w,
54		dog_c_scale,w_1871.jpg 1871w,
55		dog_c_scale,w_2800.jpg 2800w"
56		src="dog_c_scale,w_2800.jpg"
57		alt="">
58</picture>

Hãy xem nó bao phủ bao nhiêu kích thước màn hình cho chúng ta, tuyệt vời phải không? Nhưng liệu nó có đủ tốt để sao chép lên trang web của bạn? KHÔNG.

Vấn đề lớn nhất với các image source set này là thuộc tính sizesmedia. Khá phức tạp để hiểu và còn phức tạp hơn để làm cho nó hoạt động đúng.

Với điều đó, bạn cần làm cho mã ngắn hơn và dễ hiểu hơn. Trên trang web của tôi (trang bạn đang đọc), tôi đã sử dụng các breakpoint responsive chung do Bootstrap cung cấp và tạo các bộ của riêng mình.

Tự tạo kích thước hình ảnh responsive

Giải pháp tốt nhất (và thực sự là duy nhất) là tự tạo các thẻ hình ảnh.

Điều này hoạt động tốt khi bạn phát triển trang web tùy chỉnh từ đầu, nhưng khi bạn có thứ gì đó như WordPress thì lại là câu chuyện khác và sẽ có bài viết khác về điều đó.

Làm điểm bắt đầu, tôi cần cách rõ ràng và đơn giản để hiểu các breakpoint thiết bị; vì vậy tôi đã sử dụng các breakpoint do Bootstrap cung cấp, cực kỳ đáng tin cậy:

BreakpointThiết bịKích thước
X-SmallThiết bị nhỏ (điện thoại dọc, dưới 576px)<576px
SmallThiết bị nhỏ (điện thoại ngang, từ 576px)≥576px
MediumThiết bị trung bình (máy tính bảng, từ 768px)≥768px
LargeThiết bị lớn (máy tính bàn, từ 992px)≥992px
Extra largeThiết bị lớn (máy tính lớn, từ 1200px)≥1200px
Extra extra largeThiết bị lớn (máy tính lớn hơn, từ 1400px)≥1400px

Với các breakpoint trên, tôi đã tạo image source set “riêng” tải hình ảnh phù hợp theo kích thước thiết bị:

 1<picture>
 2
 3<source srcset="" media="(min-width: 1400px)">
 4<source srcset="" media="(min-width: 1200px)">
 5<source srcset="" media="(min-width: 992px)">
 6<source srcset="" media="(min-width: 768px)">
 7<source srcset="" media="(min-width: 576px)">
 8<source srcset="" media="(min-width: 320px)">
 9<img src="" width="" height="" class="" alt="" >
10</picture>

Điều này cho tôi cái nhìn rõ ràng và hiểu biết về những gì nên xảy ra và như thế nào. Nói cách khác, tôi biết hình ảnh nào nên tải trên mỗi thiết bị và nó sẽ hoạt động như vậy.

Mặc dù có vẻ sẵn sàng sử dụng, nhưng chưa hoàn toàn sẵn sàng. Tải các hình ảnh này trên một thiết bị cụ thể chưa đủ tốt vì hình ảnh có thể vẫn quá lớn.

Ví dụ 1:

  • Trên thiết bị lớn (máy tính lớn, 1200px trở lên) container nơi bạn nhúng bộ hình ảnh có kích thước cố định 800px
  • Trình duyệt sẽ xem viewport của bạn là 1920px chẳng hạn, nó sẽ tải hình ảnh 1400px (trong khi thực tế bạn cần kích thước 768px…)

Ví dụ 2:

  • Trên bất kỳ thiết bị nào, container nơi bạn nhúng bộ hình ảnh có kích thước cố định 400px (có thể là card hoặc box đơn giản)
  • Trình duyệt sẽ xem viewport của bạn là 1920px chẳng hạn, nó sẽ tải hình ảnh 1400px (trong khi thực tế bạn cần kích thước 320px…)

Vậy là bạn đang tải sai hình ảnh, điều này tốn phí cho bạn và người dùng. Đầu tiên bạn mất tốc độ (ảnh hưởng đến thứ hạng SEO nhân tiện) và sau đó người dùng phải đợi mãi cho hình ảnh tải nếu họ dùng di động hoặc băng thông chậm.

Giải pháp đúng là kiểm tra container nơi bạn nhúng hình ảnh và xác định kích thước phù hợp.

Bạn có thể làm điều này rất dễ dàng bằng cách kiểm tra trang và mô phỏng các thiết bị khác nhau, thường container giữ nguyên kích thước ít nhiều.

Vì vậy cho Ví dụ 1 ở trên, tôi đã sửa mã như sau:

1<picture>
2
3<source srcset="" media="(min-width: 1200px), (min-width: 1400px), (min-width: 2500px)">
4<source srcset="" media="(min-width: 992px)">
5<source srcset="" media="(min-width: 768px)">
6<source srcset="" media="(min-width: 576px)">
7<source srcset="" media="(min-width: 320px)">
8<img src="" width="" height="" class="" alt="">
9</picture>

Điều này có nghĩa gì? Khá rõ ràng nhưng tôi sẽ giải thích:

  • Trên thiết bị có chiều rộng tối thiểu 320px, tải hình ảnh 320px
  • Trên thiết bị có chiều rộng tối thiểu 576px, tải hình ảnh 576px
  • Trên thiết bị có chiều rộng tối thiểu 768px, tải hình ảnh 768px
  • Trên thiết bị có chiều rộng tối thiểu 992px, tải hình ảnh 992px
  • Trên thiết bị có chiều rộng tối thiểu 1200px HOẶC 1400px HOẶC 2500px tải hình ảnh 1200px

Dòng cuối đảm bảo trình duyệt không tải hình ảnh lớn hơn khi kích thước container chỉ 800px (hoặc 1200px trong trường hợp của tôi khi bạn nhấn mở rộng bài viết)

Tôi thấy cách trên gần như hoàn hảo về mặt tải đúng kích thước hình ảnh. Ngay cả Google Pagespeed cũng ưa thích và không tạo cảnh báo vì chúng ta đang tải đúng kích thước.

Kiểm thử hình ảnh responsive

Tôi khá chắc rằng sau khi đọc phần trên bạn có ý tưởng chung về cách kiểm tra hình ảnh có tải đúng không, tuy nhiên tôi vẫn sẽ giải thích.

Quá trình kiểm thử có thể nản lòng nếu bạn có nhiều hình ảnh, nhưng rất đáng để nỗ lực.

Những gì bạn cần làm rất đơn giản, chỉ tốn chút thời gian:

  • Mở trình duyệt mong muốn và tải trang
  • Mở công cụ phát triển và chuyển đến tab Network, chọn bộ lọc “Images”
  • Làm mới trang trên các thiết bị khác nhau (di động, máy tính bảng, v.v.) và xem hình ảnh nào được tải

Vậy thôi, không có gì phức tạp.

Mẹo và thủ thuật

  • Nếu bạn có nhiều hình ảnh (nhiều hơn một header), sử dụng thuộc tính loading=lazy. Bạn có thể đọc thêm tại đây .
  • Nếu bạn không thể tự xuất/thay đổi kích thước hình ảnh, bạn có thể sử dụng dịch vụ trực tuyến. Họ cũng cung cấp CDN tải hình ảnh cực nhanh. Tôi khuyên bạn dùng Cloudflare Images .
  • Đặt tên hình ảnh đúng cách, điều này rất quan trọng. Nếu bạn không đặt tên đúng (như image-small.jpg hoặc image-320.jpg), bạn không thể dễ dàng xác định hình ảnh nào đang tải khi kiểm thử.

Vậy đấy, tôi hy vọng bài viết này đã giúp ích cho bạn.