Cách dùng iframe
<iframe> hiển thị một trang khác bên trong trang của bạn. Đặt địa chỉ trang đó vào src, một title mô tả nó, và một kích thước:
<iframe src="https://example.com/" title="Example site" width="600" height="400"></iframe>
Khung tải trang như một tài liệu riêng, có style và script riêng. Các ví dụ trên trang này dùng srcdoc thay cho src, tức là đặt HTML của khung ngay trong thuộc tính, nên chúng chạy được mà không cần tải trang web khác:
Đoạn văn bên ngoài có màu xanh và in đậm; đoạn văn bên trong khung thì không, dù trang có cùng một quy tắc p. Style không bao giờ vượt qua ranh giới của khung, theo cả hai chiều. Viền mặc định và kích thước mặc định 300×150 do trình duyệt đặt; các thuộc tính width và height ghi đè kích thước đó.
Nhúng video YouTube hoặc bản đồ
Các trang video và dịch vụ bản đồ cho bạn sẵn đoạn code iframe. Trên YouTube, bấm Chia sẻ, rồi Nhúng:
<iframe width="560" height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
Với Google Maps, mở địa điểm, bấm Chia sẻ, rồi Nhúng bản đồ, và sao chép iframe theo cùng cách. Giữ title (trình đọc màn hình đọc nó khi đi vào khung) và thay kích thước cố định bằng CSS responsive bên dưới. Thuộc tính allow cấp cho khung các tính năng như tự động phát hay toàn màn hình, vốn bị tắt mặc định với trang được nhúng.
Kích thước, viền và iframe responsive
Các đoạn code nhúng sao chép về dùng kích thước pixel cố định, nên tràn ra ngoài trên điện thoại. width: 100% cùng aspect-ratio khiến khung lấp đầy khối chứa và giữ nguyên tỷ lệ, còn border: 0 bỏ viền inset mặc định:
Đổi max-width: 480px sang giá trị khác và khung vẫn giữ tỷ lệ 16:9 ở mọi chiều rộng. Bỏ border: 0 để thấy viền mặc định của trình duyệt. Các thuộc tính cũ frameborder, scrolling và marginheight đã lỗi thời; hãy dùng CSS.
sandbox: giới hạn những gì khung được làm
Một khung có thể chạy script, gửi form và mở popup như mọi trang khác. Thuộc tính sandbox lấy đi những quyền đó; sandbox để trống chặn gần như mọi thứ, và mỗi từ khóa trả lại một quyền. Cả hai khung bên dưới nhận cùng một đoạn HTML có một script nhỏ:
Khung thứ nhất giữ nguyên chữ giữ chỗ vì script của nó không bao giờ chạy (console của Chrome ghi thông báo "Blocked script execution" cho nó). Hãy dùng sandbox mỗi khi bạn nhúng nội dung mà bạn không hoàn toàn tin tưởng, như HTML do người dùng viết, và chỉ thêm những từ khóa nó cần:
| Từ khóa | Cho phép |
|---|---|
allow-scripts | Chạy JavaScript |
allow-forms | Gửi form |
allow-popups | window.open và liên kết target="_blank" |
allow-modals | alert(), confirm() và prompt() |
allow-same-origin | Coi nội dung theo đúng origin thật của nó (cookie, bộ nhớ lưu trữ) |
allow-top-navigation | Điều hướng cả tab rời khỏi trang của bạn |
Đừng bao giờ kết hợp allow-scripts và allow-same-origin cho nội dung từ chính origin của bạn: khi đó script trong khung có thể tự gỡ bỏ sandbox của nó.
Giao tiếp với khung: postMessage
Trang bên ngoài và khung là hai tài liệu riêng. Khi origin của chúng khác nhau, chúng không thể chạm vào DOM của nhau, nhưng có thể gửi tin nhắn. Gõ một tin nhắn và gửi nó vào khung:
Trong code thực tế, hãy truyền đúng origin của khung (như 'https://maps.example.com') thay cho '*', và kiểm tra e.origin ở phía nhận, để tin nhắn chỉ đi tới và đến từ trang web bạn mong đợi.
Hiệu năng và khi trang web từ chối
- Lazy loading. Thêm
loading="lazy"cho các khung nằm xa phía dưới trang; trình duyệt chỉ tải chúng khi người đọc cuộn tới gần. Mỗi iframe là một lần tải trang đầy đủ, nên một trang có nhiều nội dung nhúng sẽ chậm nếu thiếu nó. - "Refused to connect". Nhiều trang web (ngân hàng, phần lớn mạng xã hội, Google tìm kiếm) gửi header
X-Frame-Optionshoặcframe-ancestorscấm việc nhúng vào khung, và trình duyệt hiện lỗi trong khung. Trang của bạn không thể ghi đè điều này. Hãy dùng URL nhúng chính thức của trang web, hoặc một liên kết. - Khả năng truy cập. Luôn đặt
title. Đó là cách trình đọc màn hình gọi tên khung, và một trang có nhiều khung không có tiêu đề rất khó di chuyển.
Lỗi thường gặp
- Thiếu
title. Trình đọc màn hình đọc khung là không có tên. - Chiều rộng cố định từ code nhúng sao chép về. Thay bằng
width: 100%vàaspect-ratio. - Nhúng một tệp video thông thường bằng iframe. Với tệp
.mp4của riêng bạn, hãy dùng phần tử video; iframe dành cho trang web. - Tin tưởng nội dung trong khung. Thêm
sandboxcho mọi thứ không phải do bạn viết. - Nghĩ rằng CSS bên ngoài định dạng được khung. Hãy định dạng trang trong khung từ bên trong nó.
Câu hỏi thường gặp
iframe trong HTML là gì?
<iframe> (inline frame) là một khung hiển thị một trang web riêng bên trong trang hiện tại. Nó có tài liệu, style và script riêng, vì vậy nó được dùng để nhúng video, bản đồ, quảng cáo và bản xem trước code.
Làm sao nhúng video YouTube bằng iframe?
Trên YouTube, chọn Chia sẻ, rồi Nhúng, và sao chép đoạn code. Đó là một iframe có src là https://www.youtube.com/embed/ cộng với id của video. Giữ các thuộc tính title và allowfullscreen, và dùng CSS aspect-ratio: 16 / 9 với width: 100% để iframe responsive.
Vì sao iframe báo trang web từ chối kết nối?
Trang web đó gửi header X-Frame-Options hoặc Content-Security-Policy: frame-ancestors cấm các trang khác nhúng nó vào khung. Nhiều trang web làm vậy để chống clickjacking. Bạn không thể ghi đè điều này từ trang của mình; hãy dùng URL nhúng chính thức của trang web nếu có.
Làm sao bỏ viền của iframe?
Đặt border: 0 trong CSS. Thuộc tính cũ frameborder="0" đã lỗi thời, dù nhiều đoạn code nhúng sao chép về vẫn còn nó.
Làm sao để iframe responsive?
Cho nó width: 100% và một aspect-ratio trong CSS, ví dụ aspect-ratio: 16 / 9 cho video, và bỏ chiều cao cố định. Khi đó iframe co giãn theo khối chứa và giữ nguyên tỷ lệ.
Thuộc tính sandbox của iframe có tác dụng gì?
Thuộc tính sandbox để trống sẽ chặn script, việc gửi form, cửa sổ popup và nhiều thứ khác bên trong khung, và coi nội dung của khung như đến từ một origin riêng biệt. Sau đó bạn chỉ cho phép những gì nội dung nhúng cần bằng các từ khóa như allow-scripts hoặc allow-forms.