Neisha
Neisha

Reputation: 41

Scaled element gets cut off when printing in IE11

I have a solution to printing that works well in Chrome but I am getting odd results in IE11. The solution involves scaling down the content of the web page to fit onto the printed page.

In IE I am seeing my content cut off about halfway down the page.

I have created a simplified example of what I believe is the cause of my issue, which is that the scaled content only seems to take up that percent of the page. E.g. if I scale the content by 50% (0.5), it only takes up half of the page space when I print it. If scaled by 75% it takes up about three quarters of the page space. Example below.

HTML structure

<body>
    <div class="content">
        ... content goes here ...
    </div>
</body>

CSS

    .content {
        transform: scale(0.5);
        transform-origin: left top;
    }

Here is a hosted version you can see in action, with borders for debugging: https://neisha.github.io/ieprintingissue/

Image of the behaviour in IE

I have tried all sorts of different permutations of css to get it to work but I am at a loss. Also I'm not sure if this a bug in IE or expected behaviour. I can't imagine who would want this behaviour. Is there a css guru out there who can shine some light on this?

Upvotes: 1

Views: 1829

Answers (1)

Neisha
Neisha

Reputation: 41

I'm still convinced it's an IE bug, but I've managed to partially crack this using a specific hierarchy of elements and some restrictions.

I can get it to render correctly in the print/print preview, but only if the content fits on a single page.

This requires having the scaled element absolutely positioned within an absolutely positioned container element, and behaves differently depending on whether the container is relative to an element in it's ancestry (in the flow of the DOM), or whether the container elements is completely outside of the flow of the DOM.

I will explain each of these restrictions using the example below:

HTML structure

<body>
    <div class="relativeAncestor">
        <div class="container">
            <div class="content">
                ... content goes here ...
            </div>
        </div>
    </div>
</body>
  1. Cannot allow content to go over multiple pages

The absolutely positioned container and it's ancestors must also not be allowed to go over multiple pages. i.e. they cannot be more than the view height.

Example CSS to enforce restriction 1

.container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;

    overflow: hidden;
}
  1. The absolutely positioned parent is outside the flow of the DOM so that it doesn't have ancestors

Example CSS to enforce restrictions 1 and 2

// html, body and .relativeAncestor will have position: static by default

.container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;

    overflow: hidden;
}

.content {
    position: absolute;

    transform: scale(0.5);
    transform-origin: left top;
}
  1. If it is within the flow of the DOM (has a relative ancestor), it must start from the top of the page with no gap

This means:

  • no margin top
  • if a border if present, box-sizing needs to be set to border-box
  • padding is ok

Example CSS to enforce restrictions 1 and 3

html, body {
    width: 100%;
    height: 100%;
}

body {
    margin-top: 0;
}

.relativeAncestor {
    position: relative;

    width: 100%;
    height: 100%;
}    

.container {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;

    overflow: hidden;
}

.content {
    position: absolute;

    transform: scale(0.5);
    transform-origin: left top;
}

In cases 2 and 3, margin on the absolutely positioned container is ok.

This works for part of my use case where I am scaling the viewport onto a single page. When I have to scale and have it go over multiple pages I am still in trouble.

Here is a hosted version of the partial workaround you can see in action: https://neisha.github.io/ieprintingissue/workaround.html

Image of the expected behaviour

I don't have an in-depth answer for why this magical combination makes it render correctly, but hopefully this will help someone. Please comment if you have any insight as to what is going on.

Upvotes: 3

Related Questions