The printed parent window of the iframed pages causes an odd scaling

I was tasked with combining several HTML documents into one printable page. My first attempt failed - I tried to isolate the contents of the page each in my <div> and the rules of the style sheets modified to match. My second attempt, using iframes to isolate each document, looks much better, but the pages are enlarged when printing from the parent frame of the iframe stack and printing individual documents in their own windows.

Here is an example of the documents I'm working with: http://dl.dropbox.com/u/291229/print-test/index.html

You can do a preview in Firefox to understand what I mean. If you open the first frame in your tab / window and print a preview, the selected fields fit well into the page. Doing the same in the parent window of the iframe stack shows cells that flow outside the borders of the page.

Disclaimer: I have not encoded these pages. Yes, I know that they are terrifying. Unfortunately, the project does not have the time or budget to remake the pages in such a way as to fulfill the goal of a single page to print a set of documents. I may temporarily require users to print each page separately for proper scaling, but I would still like to understand what might cause this problem.

+6
source share
2 answers

The problem is that browsers use the width of the iframe container to determine how to scale the contents of this frame for printing. Therefore, frames must explicitly define the width.

Unfortunately, dynamically determining print widths is quite complicated and involves hackers. You might be better off just styling the fixed width of the component pages and hard-coded the width of the iframe.

However, if you really need to dynamically size them, you can run the following code after loading the document (tested in Chrome):

 var iframes = document.getElementsByTagName("iframe"); for(var i = 0; i < iframes.length; ++i) { var curFrame = iframes[i]; var curBody = curFrame.contentDocument.body; curBody.innerHTML = '<div id="iframe-print-content" style="display:inline-block; overflow:hidden; white-space: nowrap;">' + curBody.innerHTML + '</div>'; var printContent = curFrame.contentDocument.getElementById("iframe-print-content"); var curWidth = printContent.offsetWidth + printContent.offsetLeft; iframes[i].style.width=(curWidth + "px"); } 

After that, you can print normally or call window.print() or do whatever you want.


Note. This method will not work on ie6 or ie7, since they do not support inline-block . (There are also several other old browsers that are also not). You can, of course, try

 display:-moz-inline-stack; display:inline-block; zoom:1; *display:inline; overflow:hidden; white-space: nowrap; 

which will probably take care of most of these cases, but I don't do promises for older browsers.

Good luck, sorry you are stuck with the code on these pages.




Edit: The above solution is a bit inconvenient in Firefox.

Solution for Firefox (tested and works in Firefox 5):

 var iframes = document.getElementsByTagName("iframe"); for(var i = 0; i < iframes.length; ++i) { var curFrame = iframes[i]; var curBody = curFrame.contentDocument.body; var oldHTML = curBody.innerHTML; curBody.innerHTML = '<div id="iframe-print-content" style="display:inline-block; overflow:hidden;">' +  oldHTML + '</div>'; var printContent = curFrame.contentDocument.getElementById("iframe-print-content"); var curWidth = printContent.offsetWidth + printContent.offsetLeft + 25; var curHeight = printContent.offsetHeight + printContent.offsetTop + 25; curBody.innerHTML = oldHTML; iframes[i].style.width=(curWidth + "px"); iframes[i].style.height=(curHeight + "px"); } 

For a full explanation of why this general approach works, see my answer above.

What is the difference from the above solution and why?

Firstly, Firefox features:
There are several key differences. The first notices that Firefox handles display: inline-block and white-space: nowrap differently than Chromium / WebKit for fixed-width elements (so one document looked really unstable with the previous code). It should be further noted that Firefox likes to give a little margin inside its frames. I am not very familiar with the Firefox code that does this (spend my days on Chrome), but my usual solution (besides avoiding frames) is to simply give an extra 25 pixels in the margins. A small amount like this seems like a popular pen to solve this problem.

Now the parts of the code that are actually better:
Firstly, it now stores the old body, raises the body on a div to measure, and then restores the old body. This should avoid problems with inflexible CSS and should guarantee more predictable behavior. Secondly, now it does the same for height as width (my previous assumption that hardcoded widths just worked would not be good, and in any case this is a more flexible solution).

Why is it still bad?

By removing white-space: nowrap , you will get text printing in Chromium / WebKit. It still prints fine, but this is not entirely correct, as some additional texts will be wrapped. To make this a truly workable solution, you still have to execute the browser discovery code.

Again, I recommend using this code to quickly determine the appropriate widths and heights, and then check and adjust the correct sizes for each browser. This is an ugly solution, but ultimately it is the only truly reliable solution.

+9
source

I believe that you can (again) “fool” the browser by adding a static width to one of the iFrames in the middle ... This forces the print version to resize, returning all your information to the page ... I changed only this iFrame and returned size (note width: 150%):

 <iframe src="order/form.html" style="height: 1707px;width:150%"> 
+1
source

Source: https://habr.com/ru/post/892465/


All Articles