t3n News Entwicklung

Responsive iFrames: So bringst du das HTML-Element ins Jahr 2015

Responsive iFrames: So bringst du das HTML-Element ins Jahr 2015

Responsive iFrames? Das klingt schon falsch – und ist auch ein schwieriges Pflaster. Grundsätzlich können iFrames responsiv sein, Voraussetzung ist natürlich, dass sich ihr Inhalt ebenfalls responsiv verhält. Es ist ja quasi ein Browserfenster im Browserfenster. Doch die Anpassung der Breite ist nicht das Problem, die Anpassung der Höhe macht es kompliziert.

Responsive iFrames: So bringst du das HTML-Element ins Jahr 2015

Responsive iFrames (Grafik: Shutterstock)

Ein prominentes Beispiel: Youtube-Video responsive einbinden

Der YouTube-iFrame soll folgendermaßen eingebunden werden:

<iframe width="560" height="315" src="https://www.youtube.com/embed/9T7eSyo7DRU" frameborder="0" allowfullscreen></iframe>

Die Breite des iFrames überschreibt man durch CSS wie auch bei Responsive Images:

img,
iframe {
max-width: 100%;
}

Die Breite passt sich immer dem Container an. Die Höhe wird leider nicht automatisch angepasst – im Beispiel bleibt die Höhe also bei 315 Pixel. Die Regel height: auto; hat hier leider keinen Einfluss auf unseren iFrame. Das Problem bleibt die relationale Höhenanpassung des iFrames, wenn sich die Breite verändert.

Für das reponsive iFrame-Video behelfen wir uns mit einem bekannten Trick. Den iFrame umschließen wir mit einem Container-DIV und erweitern den Container mit padding-bottom durch die prozentuale Höhe des Seitenverhältnisses des iFrames, genauso wie bei Lazy Loading.

Beispiel:

<div class="embed-container"><iframe width="560" height="315" src="https://www.youtube.com/embed/9T7eSyo7DRU" frameborder="0" allowfullscreen></iframe>>/div>
.embed-container {
  position: relative; 
  padding-bottom: 56.25%; /* ratio 16x9 */
  height: 0; 
  overflow: hidden; 
  width: 100%;
  height: auto;
}
.embed-container iframe {
  position: absolute; 
  top: 0; 
  left: 0; 
  width: 100%; 
  height: 100%; 
}
/* ratio 4x3 */
.embed-container.ratio4x3 {
  padding-bottom: 75%;
}

Jetzt wird die Video-Containerhöhe immer relational an die Breite angepasst. Je nach Seitenverhältnis kann man auch weitere Klassen im .embed-container verwenden, beispielsweise .ratio4x3 für ein Seitenverhälnis 4:3.

Bei einem externen Video mit festem Seitenverhältnis ist das recht einfach, schwieriger wird es mit interaktiven Inhalten, die eine dynamische Höhe haben.

iFrame-Interaktion

Wenn man im iFrame weitere Aktionen durchführen kann (Bestellformulare zum Beispiel) und die iFrame-Inhaltsseiten unterschiedlich lang sind, wird unter Umständen ein Scrollbalken angezeigt – oder man hat viel Weißraum. Dieses Verhalten ist verständlicherweise nicht gewollt. In einem Projekt sollte die Anwendung (Berechnung einer Versicherung) in Partnerwebseiten eingebunden werden, ohne dass auffällt, dass es eine externe Anwendung (ein externes Produkt) ist.

Das ist unlängst komplizierter, da iFrames insbesondere von verschiedenen Domains aus Sicherheitsgründen nicht so einfach miteinander kommunizieren dürfen (Same-Origin-Policy).

Same-Origin-iFrame

Wenn der iFrame von der gleichen Domain aus beispielsweise mit der ID „responsive-iframe“ eingebunden ist, kann man folgende jQuery-Funktion verwenden.

$(function(){
  $(window).on('load resize', adjustIframe);
});
function adjustIframe() {
  $(parent.document.getElementById("responsive-iframe")).css("height", $("").css("height"));
}

Erfolgt die Einbindung unter einer anderen Domain muss man eine andere Technik verwenden, damit die Kommunikation zwischen den Frames gewährleistet ist.

Cross-Origin-iFrame

In HTML5 ist postMessage eingeführt worden, das eine Kommunikation zwischen Browserfenstern erlaubt. Hiermit ist es möglich, die aktuelle Höhe des iFrame-Inhalts an die einbindende Seite zu übermitteln.

postMessage-Definition:

otherWindow.postMessage(message, targetOrigin, [transfer]);

JavaScript-Funktion für Cross-Origin-responsive-iFrames

iframe.html – Sender:

var rIframe = {};
rIframe.requestAnimFrame = (function(){

    return  window.requestAnimationFrame       ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame    ||
            window.oRequestAnimationFrame      ||
            window.msRequestAnimationFrame     ||
            function( callback ){
                window.setTimeout(callback, 1000 / 60);
            };
})();    
rIframe.windowHeight = 0;
rIframe.htmlElement = document.getElementsByTagName('html')[0];
rIframe.targetDomain = 'domain.tld';
rIframe.resizeFrame = function (){
    var windowHeight = document.body ? Math.max(document.body.offsetHeight, rIframe.htmlElement.offsetHeight) : rIframe.htmlElement.offsetHeight ;
    if ( rIframe.windowHeight === windowHeight ) {
        rIframe.requestAnimFrame.call(window, rIframe.resizeFrame);
        return false;
    }
    rIframe.windowHeight = windowHeight;
    try {
        // Same Origin iFrame
        window.frameElement.style.height = windowHeight + 'px';
    }
    catch ( e ) {
        // Cross Origin iFrame
        window.parent.postMessage('resize:' + windowHeight , rIframe.targetDomain);
    }
    rIframe.requestAnimFrame.call(window, rIframe.resizeFrame);
};
rIframe.requestAnimFrame.call(window, rIframe.resizeFrame);

index.html – Empfänger:

function receiveMessage(event) {
    var message = event.data.split(':');
    var eventName = message[0];
    var iframes, len, i = 0;

    // only receive messages from this domain
    var senderDomains = ['domain.tld'];

    if ( senderDomains.indexOf(event.origin) !== -1 && eventName === 'resize' ) {
        iframes = document.getElementsByTagName('iframe');
        len = iframes.length;

        for (; i < len; i++) {
            if ( ( iframes[i].contentWindow || iframes[i].documentWindow ) == event.source) {
                iframes[i].style.height = message[1] + "px";
                return;
            }
        }
    }
}

if ( window.addEventListener ) {
    window.addEventListener('message', receiveMessage, false);
} 
else if (window.attachEvent)  {
    window.attachEvent('onmessage', receiveMessage);
}

Den kompletten Code findet ihr hier.

JavaScript-Plugins

easyXMD

easyXDM ist eine Javascript-Library, die es Entwicklern ermöglicht, mit den Limitierung der Same-Origin-Policy umzugehen und Anwendungen Cross-Domain kommunizieren zu lassen. Im Blogpost auf easyxdm.net wird gut beschrieben, welche Schritte man unternehmen muss.

Wer im Projekt jQuery verwendet, kann das „responsiveiframe“-Plugin von NPR verwenden. Eine umfangreiche API für iFrame-Embeds bietet iframely. Die Basisvariante ist auch auf Github verfügbar. Der Online-Service bietet noch weitere Features, wenn man ein Bezahlmodell wählt.

iFrames: Performance-Tweak

Ein letzter Hinweis: Wenn der iFrame onload nicht im Viewport ist, sollte man überlegen, ob man den iFrame mit einer Lazy-Loading-Technik verzögert lädt. Am Beispiel der lazySizes-Bibliothek von Alex Farkas ist das sehr einfach zu integrieren.

<iframe data-src="//www.youtube.com/embed/ZfV-aYdU4uE" class="lazyload" frameborder="0" allowfullscreen></iframe>

Die eigentliche Soure (src) wird durch „data-src“ ersetzt und zusätzlich mit der Klasse „lazyload“ versehen. Das Script lädt dann den iFrame beim Scrollen nach, wenn der iFrame sich dem Viewport nähert.

Das ist aber mehr oder weniger nur ein Zusatzfeature der Bibliothek – das Hauptaugenmerk liegt auf dem Lazy-Loading von Responsive Images (srcset/picture). Also durchaus ein Script, das man in vielerlei Hinsicht verwenden kann.

Dieser Artikel erschien zuerst auf maddesigns.de.

Vorheriger Artikel Zurück zur Startseite Nächster Artikel
3 Antworten
  1. von Sven am 17.05.2015 (13:17 Uhr)

    ReSponsive iFrames ;)

    Antworten Teilen
  2. von Markus am 17.05.2015 (13:59 Uhr)

    Endlich iFrames im responsive Style!!!

    Antworten Teilen
  3. von Nikolaus am 19.05.2015 (15:21 Uhr)

    >/div>
    Da ist eine Klammer falsch ...

    Sonst guter Artikel!

    Antworten Teilen
Deine Meinung

Bitte melde dich an!

Du musst angemeldet sein, um einen Kommentar schreiben zu können.

Jetzt anmelden

Mehr zum Thema HTML
Marksheet: Ausgesprochen hübsche Tutorials zu HTML, CSS und Sass
Marksheet: Ausgesprochen hübsche Tutorials zu HTML, CSS und Sass

Marksheet ist eine kostenlose Tutorialsammlung zu den Themen HTML, CSS und Sass, mit einem kleinen Abstecher zu grundlegenden Webtechnologien wie HTTP. MarkSheet ist gestalterisch auf der Höhe der … » weiterlesen

HTML-Formulare sind langweilig? Mit diesen 5 grandiosen Javascript-Libs bringen wir Schwung in eure Webseite
HTML-Formulare sind langweilig? Mit diesen 5 grandiosen Javascript-Libs bringen wir Schwung in eure Webseite

Ohne HTML-Formulare würden die meisten Webseiten nicht funktionieren. Egal ob wir eine Bestellung aufgeben, mit jemanden in Kontakt treten oder uns einloggen wollen - ohne HTML-Formulare geht es … » weiterlesen

Quelloffener HTML-Editor für Anfänger: GrapeJS im Schnellcheck
Quelloffener HTML-Editor für Anfänger: GrapeJS im Schnellcheck

Wer die eigene Website optisch und ohne Code-Kenntnisse anpassen möchte, sollte einen Blick auf GrapeJS werfen. Der speziell für Anfänger konzipierte Template-Editor auf HTML-Basis steht … » weiterlesen

Alle Hefte Jetzt abonnieren – für nur 35 €

Kennst Du schon unser t3n Magazin?