Display an iframe without truncate content

In my project for ADEME (national environment agency), we need to display our app in an iframe to embedded it as a tool inside a marketing campaign. The fact that there is two different webapp should be transparent for the user and we absolutely want to avoid double scroll : one for the website and one for the iframe.

Then, we need to display the content of the iframe in a box which fit to the size of the embedded webapp in the iframe. We don’t want to fix a size of the box because it would be : less flexible to display content, difficult to maintain when the content of the iframe will change even a little bit, a blocker to upgrade safely the dependencies which can have display effect.

After some investigation, I found 2 ways to do it

Use your own JS

Create a piece of javascript in the iframe which will post a message with the height of the page, written in typescript below :

function postHeightSize(): void {
    const target: Window | undefined = parent.postMessage ? parent : undefined

    if (target && document.body.scrollHeight) {
        target.postMessage(document.body.scrollHeight, "*")
    }
}

window.addEventListener("load", function (): void {
    postHeightSize()
})

And a piece of javascript which will interpret it in the page which embed the iframe : receive this posted message and apply the height received to the iframe block

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <iframe id="myiframe" src="http://exemple-iframe.com/?iframe" style="width: 100%;border: none;" allow="geolocation"></iframe>
    </body>
    <script>
        function receiveSize(e){
            console.error(e);
            if(e.origin === "http://exemple-iframe.com/"){
                var newHeight = e.data + 40;
                document.getElementById("myiframe").style.height = newHeight + "px";
            }
        }

        window.addEventListener("message", receiveSize, false);
    </script>
</html>

Here is the PR I made with this version : manage a resizable iframe #59

Use iframe-resizer library

Searching a little bit deeper, I found a library which resize the iframe for you, without custom code : iframe-resizer, thank you @David J. Bradshaw

Actually it use the same process of posting messages but it will handle the edge case like :

  • Works with multiple and nested iFrames.
  • Detects changes to the DOM that can cause the page to resize using MutationObserver.

But also a lot more option you can read in the documentation.

Here is the implementation, in the webapp embed as an iframe

<html>
    <head>...</head>
    <body>
    ...
        <script
            src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.6/iframeResizer.contentWindow.js"
            integrity="sha512-hBWsS94l8+snzSPo759jDKZ3z3jn3WT4snJZTBaeMPbrCGzDrYdl2pN9EaXjh6IqEZC7wF10qcmp42TPRVgAYQ=="
            crossorigin="anonymous"
            referrerpolicy="no-referrer"
            defer
        ></script>
    </body>
</html>

And in the page which embed the iframe :

<!DOCTYPE html>
<html>
    <head>
        <script
            src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.6/iframeResizer.min.js"
            integrity="sha512-f0wd6UIvZbsjPNebGx+uMzHmg6KXr1jWvumJDYSEDmwYJYOptZ0dTka/wBJu7Tj80tnCYMKoKicqvZiIc9GJgw=="
            crossorigin="anonymous"
            referrerpolicy="no-referrer"
        ></script>
    </head>
    <body>
        ...
        <iframe
            id="myiframe"
            src="http://example-iframe/?iframe"
            style="width: 100%;border: none;"
            allow="geolocation"
        ></iframe>
        ...
        <script>
            document.getElementById('myiframe').addEventListener('load', function () {
                iFrameResize({
                    heightCalculationMethod: 'documentElementOffset',
                    maxWidth: 800,
                }, '#myiframe')
            })
        </script>
    </body>
</html>

Here is the PR I made with the iframe-resizer library : Manage ifarme resize with iframe resize library #72

Conclusion

I really prefer the JS library version, it uses less code, it is more flexible, furthermore, I don’t need to maintain it.

Less code, less bugs

Leave a Reply

Your email address will not be published. Required fields are marked *