Transform Scale: Problem with Scaling Down

Transform scale: problem with scaling down

Use a 3D transformation instead:

div{
padding: 60px;
margin:100px;
background-color:red;
transition:1s;
transform:perspective(100px) translateZ(0);
}
div:hover {
transform:perspective(100px) translateZ(10px);
}
<div>abc</div>

Transform:scale issue

As Niet says, or just put this in the div{} rule, rather than div:hover{}:

transition:.2s;
transform-origin:top;

for the same reason (to avoid a transition on transform-origin at the wrong time).

In a CSS transform, how to prevent shifting of scaled up element when scaling down

The reason that is happening is that you declare transform-origin on the first time when you hover the element.

Solution:
Move transform-origin: left top; from #test:hover to #test.

Preventing blurry rendering with transform: scale

It is to do with the default transform-origin on the scaled elements. It defaults to 50% 50% for any element being transformed, but this has issues when scaling down 1px values as it has to centre the scale on a half pixel and the rendering of the elements has issues from here on out. You can see it working here with the transform-origin moved to the relevant extremes for each item.

A bit of playing about shows that this same blurring happens on scaled elements for any dimension where the scaling ends up halving a pixel.

body {

padding: 1em;

}

.container {

width: 200px;

height: 200px;

margin: 100px;

background-color: #EEE;

position: absolute;

transform: scale(2);

}

.outline {

position: absolute;

background: #1899ef;

z-index: 999999;

opacity: 1 !important;

}

.outlineBottom, .outlineTop {

width: 100%;

height: 1px;

transform: scale(1, 0.5);

}

.outlineBottom {

bottom: 0;

transform-origin: 0 100%;

}

.outlineTop {

transform-origin: 0 0;

}

.outlineLeft, .outlineRight {

height: 100%;

width: 1px;

transform: scale(.5,1);

}

.outlineRight {

right: 0px;

transform-origin: 100% 0;

}

.outlineLeft {

left: 0px;

transform-origin: 0 0;

}
<div class="container">

<div class="outline outlineTop"></div>

<div class="outline outlineRight"></div>

<div class="outline outlineBottom"></div>

<div class="outline outlineLeft"></div>

</div>

Scale down big image doesn't update body size

Quick answer: the body (container) won't use the transformed size of the image. To prevent this container element size reflecting the original image size, either you define dimensions or restrict size without transforms, or you remove the element from the document flow with absolute positioning.

Transforms are a visual 'effect' applied to an element, and don't affect the underlying document layout. Basically the browser draws elements as they are before transforms, then applies the transform effect. This allows transformed elements to overlay other elements, push outside the window etc. without affecting other element layout.

More detail in this SO question.

webkit-transform: scale breaks down when zoomed in on iOS

Here's the result of my extensive investigation before I gave up.

There are two major problems involved in applying transform: scale to content inside iframes on iOS. The first was what I pointed out in the original question, that content starts to drift away from it's specified location on the page if you are using fixed position elements. It works up to a point that seems to be based on the original size of the element, the scale factor, and presumably the viewport width. In my tests a large element might scale and position perfectly when scaled at any factor greater than 0.85. A small element might be positioned perfectly so long as the scale factor is at least >3.5. It seems almost random, so I didn't bother determining what the exact point was.

I didn't try this on relatively positioned elements, but I'm assuming they function similar to fixed position elements.

There is a rather kludgy workaround for this involving using absolutely positioned elements anchored to the bottom of the page using scroll offsets and innerHeight. i.e.:

container.css('top', (document.body.scrollTop + window.innerHeight - container.height()) + 'px');
container.css('left', document.body.scrollLeft);

And updating this on every drag, transform, pinch, resize, etc. There is some weirdness involved with this method (iOS doesn't update scroll offsets until after a drag has completely stopped) but it's workable if you absolutely had to do it.

However, even though that's a possibility, when you scale content inside iframes on iOS, if you have ANY anchor tags (or other elements that need to be clicked on), the clickable area stays unscaled. If you have an image in inside an anchor tag that's 200x100 and you scale it 2x, the image will be twice as big, but the anchor will only respond to the first 200x100. Using the iOS simulator, if you double click on an image outside the clickable area Safari is even helpful enough to darken the original bounds so you know where you could have clicked. It's pretty much a deal breaker if you want to display anything other than text/images that don't require clicking or other inputs. More information here:

CSS3 Transform scaling issue on IPad Safari

"-webkit-transform: scale(2)" doesn't affect click area of Facebook Like Button (on iPad)

Until Apple fixes these long standing bugs in mobile Safari, it seems that trying to scale iframe content using webkit-transform isn't a viable option unless you are only targeting Chrome.

Edit:

Demo of scaling issues here.

Transform scale keeps the original space around the scaled element

A brutal way would be to virtually reduce space needed by element.

Your example shows a known width & height, so it makes it easy. else you would need a javascript method.

.box_1 {
width: 300px;
height: 300px;
transform: scale(0.5);
transform-origin: left top;
margin-bottom:-150px;
margin-right:-150px;
}

https://jsfiddle.net/0bc4sxk3/1/

Scaling up would mean positive margins.

Transform only happens at screen, elements still use initial room and place needed in the flow of the document.



Related Topics



Leave a reply



Submit