Hình ảnh thích ứng

Văn bản trên web tự động xuống dòng ở cạnh màn hình để không bị tràn. Mặt khác, hình ảnh có kích thước nội tại. Nếu một hình ảnh rộng hơn màn hình, hình ảnh sẽ tràn và người dùng phải cuộn theo chiều ngang để xem toàn bộ hình ảnh.

May mắn thay, CSS cung cấp cho bạn các công cụ để ngăn chặn việc này xảy ra.

Giới hạn hình ảnh

Trong trang tính kiểu, bạn có thể sử dụng max-inline-size để khai báo rằng hình ảnh không bao giờ được kết xuất ở kích thước lớn hơn phần tử chứa hình ảnh.

Browser Support

  • Chrome: 57.
  • Edge: 79.
  • Firefox: 41.
  • Safari: 12.1.

Source

img {
  max-inline-size: 100%;
  block-size: auto;
}

Bạn cũng có thể áp dụng quy tắc tương tự cho các loại nội dung nhúng khác, chẳng hạn như video và iframe.

img,
video,
iframe {
  max-inline-size: 100%;
  block-size: auto;
}

Khi áp dụng quy tắc này, trình duyệt sẽ tự động điều chỉnh tỷ lệ hình ảnh cho vừa với màn hình.

Hai ảnh chụp màn hình; ảnh đầu tiên cho thấy hình ảnh mở rộng ra ngoài chiều rộng của trình duyệt; ảnh thứ hai cho thấy cùng một hình ảnh bị ràng buộc trong khung nhìn của trình duyệt.
Việc ràng buộc hình ảnh sẽ giúp người dùng xem được toàn bộ hình ảnh mà không cần cuộn.

Việc thêm giá trị block-sizeauto có nghĩa là trình duyệt sẽ giữ nguyên tỷ lệ khung hình của hình ảnh khi thay đổi kích thước hình ảnh.

Đôi khi, kích thước của hình ảnh được đặt bởi hệ thống quản lý nội dung (CMS) hoặc hệ thống phân phối nội dung khác. Nếu thiết kế của bạn yêu cầu tỷ lệ khung hình khác với tỷ lệ khung hình mặc định của CMS, bạn có thể sử dụng thuộc tính aspect-ratio để giữ nguyên thiết kế của trang web:

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
}

Rất tiếc, điều này thường có nghĩa là trình duyệt phải làm méo hoặc kéo giãn hình ảnh để vừa với không gian dự kiến.

Hình chân dung một chú chó đẹp trai trông vui vẻ đang ngậm quả bóng trong miệng, nhưng hình ảnh bị méo.
Việc thay đổi tỷ lệ khung hình của hình ảnh sẽ khiến hình ảnh đó trông bị vỡ hoặc bị kéo giãn.

Để ngăn tình trạng nén và kéo giãn, hãy sử dụng thuộc tính object-fit.

Browser Support

  • Chrome: 32.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 10.

Source

Giá trị object-fitcontain sẽ yêu cầu trình duyệt giữ nguyên tỷ lệ khung hình của hình ảnh, để lại khoảng trống xung quanh hình ảnh nếu cần.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: contain;
}

Giá trị object-fitcover sẽ cho trình duyệt biết cần duy trì tỷ lệ khung hình của hình ảnh, cắt hình ảnh nếu cần.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
}
Chân dung một chú chó đẹp trai trông vui vẻ đang ngậm quả bóng trong miệng; có không gian thừa ở hai bên hình ảnh. Chân dung một chú chó đẹp trai trông rất vui vẻ, đang ngậm một quả bóng trong miệng; hình ảnh đã được cắt ở đầu và cuối.
Cùng một hình ảnh với hai giá trị khác nhau cho thuộc tính "object-fit". Ảnh đầu tiên có giá trị "object-fit" là "contain". Ảnh thứ hai có giá trị "object-fit" là "cover".

Bạn có thể thay đổi vị trí của phần cắt hình ảnh bằng cách sử dụng thuộc tính object-position. Thao tác này sẽ điều chỉnh tiêu điểm của phần cắt, nhờ đó bạn có thể đảm bảo phần quan trọng nhất của hình ảnh vẫn hiển thị.

Browser Support

  • Chrome: 32.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 10.

Source

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
  object-position: top center;
}
Chân dung một chú chó đẹp trai trông vui vẻ đang ngậm quả bóng; hình ảnh chỉ bị cắt ở phần dưới cùng.
Bạn có thể đặt object-position để chỉ cắt một bên hình ảnh.

Phân phối hình ảnh

Các quy tắc CSS đó cho trình duyệt biết cách bạn muốn hiển thị hình ảnh. Bạn cũng có thể cung cấp gợi ý trong HTML về cách trình duyệt xử lý những hình ảnh đó.

Gợi ý về cách định cỡ

Nếu bạn biết kích thước của hình ảnh, hãy luôn thêm các thuộc tính widthheight. Ngay cả khi hình ảnh được kết xuất ở kích thước khác do quy tắc max-inline-size, trình duyệt vẫn biết tỷ lệ chiều rộng trên chiều cao và có thể dành ra đúng không gian. Điều này giúp nội dung khác của bạn không bị nhảy xung quanh khi hình ảnh tải.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
>
Video đầu tiên cho thấy một bố cục không có kích thước hình ảnh được xác định. Hãy lưu ý cách văn bản nhảy khi hình ảnh tải. Trong video thứ hai, kích thước hình ảnh đã được cung cấp, vì vậy, trình duyệt sẽ để lại không gian cho hình ảnh và văn bản không bị nhảy xung quanh khi hình ảnh tải.

Gợi ý tải

Sử dụng thuộc tính loading để cho trình duyệt biết liệu có nên trì hoãn việc tải hình ảnh cho đến khi hình ảnh đó nằm trong hoặc gần khung nhìn hay không. Đối với hình ảnh bên dưới màn hình, hãy sử dụng giá trị lazy. Trình duyệt sẽ không tải hình ảnh tải từng phần cho đến khi người dùng cuộn xuống đủ xa để hình ảnh sắp xuất hiện. Nếu người dùng không bao giờ cuộn, hình ảnh sẽ không bao giờ tải.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
>
Hình ảnh tải từng phần sẽ chờ tải cho đến khi người dùng sắp cuộn đến hình ảnh đó.

Đối với hình ảnh chính ở đầu trang, đừng sử dụng loading. Nếu trang web của bạn tự động áp dụng thuộc tính loading="lazy", thì bạn thường có thể đặt loading thành giá trị mặc định là eager để ngăn tải hình ảnh từng phần:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
>

Mức độ ưu tiên tìm nạp

Đối với các hình ảnh quan trọng (chẳng hạn như hình ảnh LCP), bạn có thể ưu tiên tải thêm bằng cách sử dụng Mức độ ưu tiên tìm nạp bằng cách đặt thuộc tính fetchpriority thành high:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 fetchpriority="high"
>

Thao tác này sẽ yêu cầu trình duyệt tìm nạp hình ảnh ngay lập tức và ở mức độ ưu tiên cao, thay vì đợi đến khi trình duyệt hoàn tất bố cục và tìm nạp hình ảnh như bình thường.

Tuy nhiên, khi bạn yêu cầu trình duyệt ưu tiên tải một tài nguyên xuống, chẳng hạn như hình ảnh, trình duyệt phải giảm mức độ ưu tiên của một tài nguyên khác như tập lệnh hoặc tệp phông chữ. Chỉ đặt fetchpriority="high" trên hình ảnh nếu hình ảnh đó thực sự quan trọng.

Gợi ý về việc tải trước

Tốt nhất là bạn nên tránh tải trước bất cứ khi nào có thể bằng cách đưa tất cả hình ảnh vào tệp HTML ban đầu. Tuy nhiên, một số hình ảnh có thể không có sẵn, chẳng hạn như hình ảnh do JavaScript thêm vào hoặc hình nền CSS.

Bạn có thể sử dụng tính năng tải trước để yêu cầu trình duyệt tìm nạp trước những hình ảnh quan trọng này. Đối với những hình ảnh thực sự quan trọng, bạn có thể kết hợp tính năng tải trước này với thuộc tính fetchpriority:

<link rel="preload" href="hero.jpg" as="image" fetchpriority="high">

Xin nhắc lại, hãy sử dụng các thuộc tính này một cách tiết kiệm để tránh ghi đè quá thường xuyên phương pháp phỏng đoán ưu tiên của trình duyệt. Việc sử dụng quá nhiều các thành phần này có thể làm giảm hiệu suất.

Một số trình duyệt hỗ trợ tính năng tải trước hình ảnh thích ứng dựa trên srcset, sử dụng các thuộc tính imagesrcsetimagesizes. Ví dụ:

<link rel="preload" imagesrcset="hero_sm.jpg 1x hero_med.jpg 2x hero_lg.jpg 3x" as="image" fetchpriority="high">

Bằng cách loại trừ phương án dự phòng href, bạn có thể đảm bảo rằng các trình duyệt không hỗ trợ srcset vẫn tải trước hình ảnh chính xác.

Bạn không thể tải trước hình ảnh ở nhiều định dạng dựa trên khả năng hỗ trợ của trình duyệt đối với một số định dạng nhất định. Việc này có thể dẫn đến việc tải xuống thêm gây lãng phí dữ liệu của người dùng.

Giải mã hình ảnh

Bạn cũng có thể thêm thuộc tính decoding vào các phần tử img. Bạn có thể cho trình duyệt biết rằng hình ảnh có thể được giải mã không đồng bộ để trình duyệt có thể ưu tiên xử lý nội dung khác.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
>

Bạn có thể sử dụng giá trị sync nếu hình ảnh đó là nội dung quan trọng nhất cần ưu tiên.

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 decoding="sync"
>

Thuộc tính decoding không làm thay đổi tốc độ giải mã hình ảnh. Điều này chỉ ảnh hưởng đến việc trình duyệt có chờ quá trình giải mã hình ảnh này diễn ra trước khi hiển thị nội dung khác hay không.

Trong hầu hết các trường hợp, điều này không ảnh hưởng nhiều, nhưng đôi khi có thể giúp trình duyệt hiển thị hình ảnh hoặc nội dung khác nhanh hơn một chút. Ví dụ: đối với một tài liệu lớn có nhiều phần tử cần thời gian để hiển thị và với hình ảnh lớn cần nhiều thời gian để giải mã, việc đặt sync trên các hình ảnh quan trọng sẽ yêu cầu trình duyệt chờ hình ảnh và hiển thị cả hai cùng một lúc. Ngoài ra, bạn có thể đặt async để cho phép trình duyệt hiển thị nội dung nhanh hơn và không cần phải đợi hình ảnh giải mã.

Tuy nhiên, lựa chọn tốt hơn thường là cố gắng tránh kích thước DOM quá lớn và sử dụng hình ảnh thích ứng để giảm thời gian giải mã, thay vì sử dụng decoding.

Hình ảnh thích ứng bằng srcset

Nhờ nội dung khai báo max-inline-size: 100% đó, hình ảnh của bạn không thể thoát khỏi vùng chứa. Tuy nhiên, nếu người dùng có màn hình nhỏ và mạng có băng thông thấp, việc yêu cầu họ tải hình ảnh có cùng kích thước như người dùng có màn hình lớn sẽ lãng phí dữ liệu.

Để khắc phục vấn đề này, hãy thêm nhiều phiên bản của cùng một hình ảnh ở nhiều kích thước và sử dụng thuộc tính srcset để cho trình duyệt biết các kích thước này tồn tại và thời điểm sử dụng.

Nội dung mô tả chiều rộng

Bạn có thể xác định srcset bằng cách sử dụng danh sách các giá trị được phân tách bằng dấu phẩy. Mỗi giá trị là URL của một hình ảnh, theo sau là một dấu cách, rồi đến một số siêu dữ liệu về hình ảnh, được gọi là thông số mô tả.

Trong ví dụ này, siêu dữ liệu mô tả chiều rộng của mỗi hình ảnh bằng đơn vị w. Một w là chiều rộng của một pixel.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
>

Thuộc tính srcset bổ sung cho thuộc tính src thay vì thay thế thuộc tính đó. Bạn vẫn cần có thuộc tính src hợp lệ, nhưng trình duyệt có thể thay thế giá trị của thuộc tính này bằng một trong các tuỳ chọn được liệt kê trong srcset. Để tiết kiệm băng thông, trình duyệt chỉ tải hình ảnh lớn hơn xuống nếu cần.

Kích thước

Nếu đang sử dụng chỉ số mô tả chiều rộng, bạn cũng phải sử dụng thuộc tính sizes để cung cấp thêm thông tin cho trình duyệt. Điều này cho trình duyệt biết kích thước mà bạn muốn hình ảnh hiển thị trong nhiều điều kiện. Các điều kiện đó được chỉ định trong truy vấn nội dung nghe nhìn.

Thuộc tính sizes sẽ lấy một danh sách truy vấn nội dung nghe nhìn và chiều rộng hình ảnh được phân tách bằng dấu phẩy.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
 sizes="(min-width: 66em) 33vw,
  (min-width: 44em) 50vw,
  100vw"
>

Trong ví dụ này, bạn đang cho trình duyệt biết rằng trong một khung nhìn có chiều rộng trên 66em, trình duyệt sẽ hiển thị hình ảnh không rộng hơn một phần ba màn hình (ví dụ: bên trong bố cục ba cột).

Đối với chiều rộng khung nhìn từ 44em đến 66em, hãy hiển thị hình ảnh ở một nửa chiều rộng màn hình (như trong bố cục hai cột).

Đối với mọi hình ảnh hẹp hơn 44em, hãy hiển thị hình ảnh ở chiều rộng đầy đủ của màn hình.

Điều này có nghĩa là hình ảnh lớn nhất không nhất thiết phải được sử dụng cho màn hình rộng nhất. Cửa sổ trình duyệt rộng có thể hiển thị bố cục nhiều cột sử dụng hình ảnh vừa với một cột, có thể nhỏ hơn hình ảnh dùng cho bố cục một cột trên màn hình hẹp hơn.

Sử dụng phần mô tả kích thước để thay đổi cách bố trí trang của bạn trên nhiều kích thước màn hình.

Chỉ số mô tả mật độ pixel

Bạn cũng có thể sử dụng nội dung mô tả để cung cấp phiên bản thay thế của hình ảnh hiển thị trên màn hình có mật độ điểm ảnh cao, nhằm đảm bảo hình ảnh trông sắc nét ở độ phân giải cao hơn mà màn hình cung cấp.

Hai phiên bản của cùng một hình ảnh một chú chó đẹp trai trông vui vẻ với quả bóng trong miệng, một hình ảnh trông sắc nét và hình ảnh còn lại trông mờ.
Hình ảnh có mật độ pixel thấp hơn có thể trông mờ.

Sử dụng chỉ số mô tả mật độ để mô tả mật độ pixel của hình ảnh liên quan đến hình ảnh trong thuộc tính src. Chỉ số mật độ là một số theo sau là chữ cái x, như trong 1x hoặc 2x.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 1x,
  medium-image.png 2x,
  large-image.png 3x"
>

Nếu small-image.png có kích thước 300x200 pixel và medium-image.png có kích thước 600x400 pixel, thì medium-image.png có thể có 2x sau đó trong danh sách srcset.

Bạn không bắt buộc phải sử dụng số nguyên. Nếu một phiên bản khác của hình ảnh có kích thước 450 x 300 pixel, bạn có thể mô tả phiên bản đó bằng 1.5x.

Hình ảnh trình bày

Hình ảnh trong HTML là nội dung. Đó là lý do bạn thêm thuộc tính alt cùng với nội dung mô tả hình ảnh cho trình đọc màn hình và công cụ tìm kiếm.

Nếu nhúng một hình ảnh trang trí mà không có nội dung có ý nghĩa nào, bạn có thể sử dụng thuộc tính alt trống.

<img
 src="flourish.png"
 alt=""
 width="400"
 height="50"
>

Bạn phải luôn thêm thuộc tính alt, ngay cả khi thuộc tính này trống. Thuộc tính alt trống cho trình đọc màn hình biết rằng hình ảnh đó là hình ảnh trình bày. Thuộc tính alt bị thiếu sẽ không cung cấp thông tin đó.

Tốt nhất là bạn nên thêm hình ảnh trình bày hoặc trang trí vào CSS thay vì HTML. HTML dùng để tạo cấu trúc. CSS dùng để trình bày.

Hình nền

Sử dụng thuộc tính background-image trong CSS để tải hình ảnh trình bày.

element {
  background-image: url(flourish.png);
}

Bạn có thể chỉ định nhiều hình ảnh đề xuất bằng cách sử dụng hàm image-set cho background-image.

Hàm image-set trong CSS hoạt động giống như thuộc tính srcset trong HTML. Cung cấp danh sách hình ảnh có chỉ số mô tả mật độ pixel cho từng hình ảnh.

element {
  background-image: image-set(
    small-image.png 1x,
    medium-image.png 2x,
    large-image.png 3x
  );
}

Trình duyệt sẽ chọn hình ảnh phù hợp nhất với mật độ pixel của thiết bị.

Có nhiều yếu tố cần cân nhắc khi thêm hình ảnh vào trang web, bao gồm:

  • Đặt trước không gian phù hợp cho mỗi hình ảnh.
  • Xác định số kích thước bạn cần.
  • Quyết định xem hình ảnh đó là nội dung hay hình ảnh trang trí.

Bạn nên dành thời gian để xử lý hình ảnh đúng cách. Chiến lược hình ảnh không hiệu quả có thể gây khó chịu và bực bội cho người dùng. Một chiến lược hình ảnh hiệu quả sẽ giúp trang web của bạn trông nhanh chóng và sắc nét, bất kể thiết bị hoặc kết nối mạng của người dùng.

Còn một phần tử HTML nữa trong bộ công cụ của bạn để giúp bạn kiểm soát nhiều hơn đối với hình ảnh: phần tử picture.

Kiểm tra mức độ hiểu biết

Kiểm tra kiến thức của bạn về hình ảnh.

Bạn phải thêm kiểu để hình ảnh vừa với khung nhìn.

Đúng
Hình ảnh không có vùng chứa sẽ có kích thước bằng kích thước tự nhiên.
Sai
Bạn phải có kiểu.

Khi chiều cao và chiều rộng của hình ảnh bị buộc vào một tỷ lệ khung hình không tự nhiên, kiểu nào có thể giúp điều chỉnh cách hình ảnh vừa với các tỷ lệ này?

object-fit
Chỉ định cách hình ảnh phù hợp với các từ khoá như containcover.
image-fit
Thuộc tính này không tồn tại, tôi đã tạo ra nó.
fit-image
Thuộc tính này không tồn tại, tôi đã tạo ra nó.
aspect-ratio
Điều này có thể gây ra hoặc giải quyết tỷ lệ hình ảnh không tự nhiên.

Việc đặt heightwidth trên hình ảnh sẽ ngăn CSS định kiểu hình ảnh theo cách khác.

Đúng
Hãy coi chúng giống như gợi ý hơn là quy tắc.
Sai
CSS có nhiều tuỳ chọn động để định cỡ hình ảnh, ngay cả khi chiều cao và chiều rộng nằm cùng dòng trên thẻ.

Thuộc tính srcset không _______ thuộc tính src mà _______ thuộc tính đó.

bổ sung, thay thế
srcset chắc chắn không thay thế thuộc tính src.
thay thế, bổ sung
Trình duyệt có thể chọn các tuỳ chọn bổ sung này (nếu có).

Thiếu alt trên hình ảnh cũng giống như alt trống.

Đúng
Thuộc tính alt trống cho trình đọc màn hình biết rằng hình ảnh này là hình ảnh trình bày.
Sai
Việc thiếu alt sẽ không gửi tín hiệu nào đến trình đọc màn hình.