Scaling 3D Secure Iframe for Mobile
When implementing 3D Secure with Braintree for a web page, the bank's verification page is passed into the JavaScript function as an iframe
element to embed into the web page. Unfortunately, the bank pages have fixed 400px width, therefore they don't fully fit on narrower mobile screens.
Without handling this issue, adding the iframe
to a page in Ionic 2 is very simple:
@ViewChild('iframeHost') hostDiv;
addFrame(error: braintree.BraintreeError, iframe: HTMLIFrameElement) {
let hostElement: HTMLDivElement = this.hostDiv.nativeElement;
hostElement.appendChild(iframe);
}
Of course, iframeHost
is a template variable on the target host element:
<div #iframeHost id="iframeHost"></div>
As far as I know, scaling the iframe
is the only way to fully accommodate it when it's wider than the page:
iframe {
width: 100% !important;
transform-origin: 0 0;
transform: scale(0.9);
}
However, the scale factor can't be fixed. We want to scale the embedded page only as much as necessary. Hence, we will need to calculate the scale factor in code:
private readonly iframeWidth = 400;
addFrame(error: braintree.BraintreeError, iframe: HTMLIFrameElement) {
let hostElement: HTMLDivElement = this.hostDiv.nativeElement;
let hostWidth = hostElement.parentElement.clientWidth;
if (hostWidth < this.iframeWidth) {
iframe.style.transform = `scale(${hostWidth / this.iframeWidth});`;
}
hostElement.appendChild(iframe);
}
For this to work, we need to set host element width in CSS to stretch its parent to the maximum available size. We can also remove the transform from CSS, since the code overrides it anyway:
#iframeHost {
width: 400px;
}
iframe {
width: 100% !important;
transform-origin: 0 0;
}
Now, if the page is narrower than the required 400px, the iframe
will be scaled just enough to fit the page. Its contents will be rendered smaller, but they will be visible in full and therefore also fully functional.