Inhalte in HTML einbetten: iframe, object, video und picture

Inhalte in HTML einbetten: iframe, object, video und picture

Ein YouTube-Video, eine Karte, ein PDF oder ein Bild in drei Formaten: Fremde und eigene Inhalte in eine Seite einzubauen gehört zum Alltag, und für jeden Fall gibt es in HTML ein eigenes Element. Wer das falsche wählt, bezahlt mit Ladezeit, Sicherheitslücken oder Ärger beim Datenschutz. Hier steht, welches Element wofür gedacht ist und wie es heute korrekt ausgezeichnet wird.

Framesets: wie HTML 4.01 Seiten zusammensetzte

HTML 4.01 kannte eine eigene Dokumentart für Frames. Ein Frameset-Dokument ersetzte BODY durch FRAMESET, teilte das Fenster über rows und cols in Bereiche und lud in jeden FRAME ein separates Dokument. NOFRAMES lieferte Ersatzinhalt, über target öffneten Links ihr Ziel in einem benannten Frame. Dafür brauchte es eine eigene DTD mit dem Bezeichner -//W3C//DTD HTML 4.01 Frameset//EN. Das Inline-Frame IFRAME war ebenfalls schon definiert.

Im heutigen HTML Living Standard sind frameset, frame und noframes vollständig obsolet. Die Spezifikation empfiehlt stattdessen iframe mit CSS oder serverseitig zusammengesetzte Seiten. Das ist auch inhaltlich richtig: Framesets zeigten in der Adresszeile immer dieselbe URL, einzelne Unterseiten ließen sich schlecht verlinken, und wer über eine Suchmaschine kam, landete oft in einem Inhaltsframe ohne Navigation. Wer heute noch ein Frameset betreibt, sollte Kopf, Menü und Inhalt per Template oder Include zu vollständigen Einzelseiten zusammenführen.

iframe richtig auszeichnen

Das iframe lädt ein vollständiges fremdes Dokument in einen Rahmen. Vier Attribute verdienen Aufmerksamkeit:

<iframe
  src='https://www.example.com/widget/'
  title='Öffnungszeiten-Kalender der Bibliothek'
  width='600' height='400'
  loading='lazy'
  sandbox='allow-scripts allow-popups'
  allow='fullscreen'
  referrerpolicy='strict-origin-when-cross-origin'>
</iframe>
AttributWirkungEmpfehlung
titleScreenreader kündigen damit den Rahmen animmer setzen, kurz den Inhalt beschreiben
loading='lazy'lädt erst, wenn der Rahmen in die Nähe des sichtbaren Bereichs kommtfür alles unterhalb des ersten Bildschirms
sandboxleer gesetzt: alle Einschränkungen aktiv, Token heben einzelne aufso wenige Token wie möglich
allowPermissions Policy, etwa für Kamera, Mikrofon, Vollbildnur freigeben, was der Inhalt braucht

Laut web.dev beherrschen Chrome ab 77, Edge ab 79, Firefox ab 121 und Safari ab 16.4 das verzögerte Laden von iframes. Bei einem YouTube-Video spart das nach Angaben von web.dev rund 500 KB beim ersten Seitenaufruf. Ohne aktiviertes JavaScript laden Browser lazy-iframes übrigens sofort, das ist laut MDN eine Schutzmaßnahme gegen Tracking.

Die gefährliche sandbox-Kombination

MDN warnt ausdrücklich davor, allow-scripts und allow-same-origin gemeinsam zu setzen, wenn das eingebettete Dokument von derselben Herkunft stammt wie die Seite. Dann kann das Dokument das sandbox-Attribut einfach entfernen, und die Sandbox ist wirkungslos. Die Attribute frameborder, scrolling und marginheight sind obsolet, Rahmen und Abstände gehören ins Stylesheet: iframe { border: 0; }.

object und embed: nur noch für Sonderfälle

object und embed stammen aus der Zeit der Browser-Plug-ins wie Flash und Java-Applets. Beide sind im HTML Standard weiterhin gültig, viele ihrer alten Attribute aber nicht mehr: classid, codebase und archive an object sind obsolet, applet ist ganz gestrichen. Die Spezifikation nennt den einzigen echten Unterschied: object erlaubt Ersatzinhalt, embed nicht.

<object data='/dateien/lageplan.pdf' type='application/pdf'
        width='800' height='600'>
  <p>Ihr Browser zeigt das PDF nicht an.
     <a href='/dateien/lageplan.pdf'>Lageplan herunterladen (PDF)</a></p>
</object>

Praktisch brauchen die meisten Seiten keines der beiden Elemente. Für Video und Audio gibt es eigene Elemente, für Bilder img und picture, für fremde Seiten iframe. Ein PDF ist mit einem gut beschrifteten Download-Link oft besser bedient als mit einem eingebetteten Viewer, der auf dem Smartphone ohnehin kaum lesbar ist. Wie man solche Links sauber beschriftet, zeigt der Beitrag zu Links, Ankern und IDs in HTML.

video und audio ohne Fremdanbieter

Wer Videos selbst hostet, braucht kein iframe und keinen Drittanbieter:

<video controls preload='metadata' poster='/video/vorschau.jpg'
       width='640' height='360'>
  <source src='/video/montage.webm' type='video/webm'>
  <source src='/video/montage.mp4' type='video/mp4'>
  <track kind='captions' src='/video/montage.de.vtt'
         srclang='de' label='Deutsch' default>
  <a href='/video/montage.mp4'>Video herunterladen (MP4)</a>
</video>
  • preload='metadata' lädt nur Länge und Eckdaten, nicht die ganze Datei. Der Wert ist laut MDN ein Hinweis, kein Befehl.
  • autoplay funktioniert in aktuellen Browsern nur zusammen mit muted. autoplay='false' schaltet nichts ab, schon das bloße Attribut startet die Wiedergabe.
  • Untertitel kommen als WebVTT-Datei über track, das hilft Gehörlosen und allen, die ohne Ton schauen.
  • audio funktioniert nach demselben Muster.

Der Haken ist die Bandbreite: Bei viel genutzten Videos wird das eigene Hosting teuer, YouTube oder Vimeo übernehmen dagegen Transkodierung und Auslieferung. Für kurze Produktclips, Anleitungen und Hintergrundvideos lohnt sich das eigene video-Element trotzdem fast immer.

picture und srcset für Bilder

Für Bilder in mehreren Auflösungen genügt srcset mit sizes direkt am img. picture lohnt sich, wenn der Browser zwischen Formaten wie AVIF und WebP wählen soll oder wenn auf schmalen Bildschirmen ein anderer Bildausschnitt erscheinen soll:

<picture>
  <source srcset='/bilder/team.avif' type='image/avif'>
  <source srcset='/bilder/team.webp' type='image/webp'>
  <img src='/bilder/team.jpg' alt='Das Werkstatt-Team vor der Halle'
       width='1200' height='800' loading='lazy'>
</picture>

Das img ist Pflicht: Es trägt alt, width und height und dient als Rückfall, wenn keine Quelle passt. Der Browser nimmt die erste source, deren Format er kennt, deshalb steht das effizienteste Format oben. picture funktioniert laut MDN seit März 2016 in allen gängigen Browsern. Wie das in WordPress ohne Handarbeit klappt, beschreibt der Beitrag Bilder in WordPress einfügen.

Datenschutz bei YouTube, Karten und anderen Drittinhalten

Jedes iframe von einem fremden Server löst beim Laden eine Anfrage an diesen Server aus. Der Anbieter erhält dabei mindestens die IP-Adresse und in der Regel die Domain der einbettenden Seite, und er kann Cookies setzen oder lesen. Für Letzteres verlangt § 25 des Telekommunikation-Digitale-Dienste-Datenschutz-Gesetzes (TDDDG) grundsätzlich eine Einwilligung, es sei denn, der Zugriff ist für den ausdrücklich gewünschten Dienst unbedingt erforderlich. Für die Verarbeitung der übrigen Daten gilt die DSGVO. Dieser Abschnitt ist keine Rechtsberatung, im Zweifel klärt das der Datenschutzbeauftragte oder eine Fachanwältin.

youtube-nocookie.com allein reicht nicht

YouTube bietet einen erweiterten Datenschutzmodus: Statt www.youtube.com steht www.youtube-nocookie.com in der Einbettungs-URL. Laut YouTube-Hilfe wird die Wiedergabe dann nicht zur Personalisierung von YouTube oder von Werbung genutzt. Dass beim Laden keine Daten an Google fließen, sagt die Hilfeseite nicht. Die Verbindung zu Googles Servern entsteht weiterhin, sobald das iframe lädt.

Zwei-Klick-Lösung als robuste Variante

Datenschutzfreundlich und schnell zugleich ist ein Platzhalter: Die Seite zeigt ein lokal gespeichertes Vorschaubild mit Hinweis, das iframe entsteht erst nach einem Klick. Ein minimales Beispiel:

<div class='video-platzhalter' data-id='VIDEO-ID'>
  <p>Beim Abspielen werden Daten an YouTube (Google) übertragen.</p>
  <button type='button'>Video laden</button>
</div>



<script>
document.querySelectorAll('.video-platzhalter button').forEach(function (btn) {
  btn.addEventListener('click', function () {
    var box = btn.parentElement;
    var f = document.createElement('iframe');
    f.src = 'https://www.youtube-nocookie.com/embed/' + box.dataset.id + '?autoplay=1';
    f.title = 'YouTube-Video';
    f.width = 640; f.height = 360;
    f.allow = 'autoplay; fullscreen';
    box.replaceWith(f);
  });
});
</script>

Dasselbe Prinzip funktioniert für Google Maps, OpenStreetMap-Karten, Social-Media-Beiträge und Like-Buttons. Bei Letzteren zeigt der Beitrag zum Facebook-Like-Button und Datenschutz, warum schon das bloße Laden heikel ist. Der Platzhalter spart nebenbei Ladezeit, weil die schweren Skripte des Anbieters nur bei Bedarf kommen.

Quellen