Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-browser method of using the transform:scale css property?

I have the following css rules:

  -webkit-transform: scale(0.5);  /* Saf3.1+, Chrome */
     -moz-transform: scale(0.5);  /* FF3.5+ */
      -ms-transform: scale(0.5);  /* IE9 */
       -o-transform: scale(0.5);  /* Opera 10.5+ */
          transform: scale(0.5);

Which I intend to apply to a div in order to scale it, including all its contents, images, etc, to 50% its size while keeping the same center. As you probably know the rules I listed do exactly that, except for IE7-8.

According to this site, the equivalent, MS proprietary rule would be:

   /* IE8+ - must be on one line, unfortunately */ 
   -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.5, M12=0, M21=0, M22=0.5, SizingMethod='auto expand')";

   /* IE6 and 7 */ 
   filter: progid:DXImageTransform.Microsoft.Matrix(
            M11=0.5,
            M12=0,
            M21=0,
            M22=0.5,
            SizingMethod='auto expand');

However these don't seem to actually resize the contents of the div, it seems to shift its position but that is all.

CSS3Please.com reports different matrix values to be the equivalent for scale(0.5):

filter: progid:DXImageTransform.Microsoft.Matrix(/* IE6–IE9 */
                     M11=0.9999619230641713, M12=-0.008726535498373935, M21=0.008726535498373935, M22=0.9999619230641713,SizingMethod='auto expand');

I've tested these aswell, but the effect was the same; the div seemed to change its position, but the actual size of its contents remained unchanged.

Finally I've tried transformie.js, which calculates the matrix via sylvester.js automatically as you assign the transform property, but the end result was still:

M11=0.5, M12=0, M21=0, M22=0.5

Exactly the same as the one I tried first, which seemingly did do nothing other than shift the position of the div.

I would try cssSandpaper.js, but it looks pretty bloated for what I intend to do, plus there's no jQuery port and I don't feel like adding cssQuery to the project only for that. Chances are the results would be the same as what transformie.js generates though, because it seems to use sylvester.js aswell.

Edit: I also tried this which seems to come from microsoft directly, and suggests the following matrix calculation method:

function resizeUsingFilters(obj, flMultiplier) {
    // If you don't do this at least once then you will get an error
    obj.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11='1.0', sizingmethod='auto expand')";
    // Resize
    obj.filters.item(0).M11 *= flMultiplier;
    obj.filters.item(0).M12 *= flMultiplier;
    obj.filters.item(0).M21 *= flMultiplier;
    obj.filters.item(0).M22 *= flMultiplier;
}  

Unfortunately this does not scale the contents of the div itself either. It looks like this may not be possible at all, but:

How can the modern transform: scale be simulated in IE8-7, in such a way that it actually resizes inner div contents aswell?

Perhaps I'm looking for something that doesn't exist, but I wanted to be sure. All the tests have been done using IE9 in compatibility mode for IE8 and IE7 (so far it has always done the job, I don't believe it's unreliable but feel free to correct me if you think otherwise)

like image 907
Mahn Avatar asked Jul 30 '12 01:07

Mahn


1 Answers

I'm a little confused by your explanation. This fiddle in IE7-8 scales the inner elements down for me just fine with the first set of code you posted (though you indicate it was not scaling, only changing position). What that code does not do (and cannot do) is scale it from the center point (it is from the upper left), and the matrix transform cannot accommodate a translation (it only "Resizes, rotates, or reverses the content of the object"), so it is not "keeping the same center" as you indicate you desire.

There is a page I found similar to the transformie.js you noted in performing transform, but this other page speaks to the issue of the transform origin being centered. Ultimately, to get the appearance of being scaled on center, you must include a calculation of some kind to do a shift of the element using position: relative.

In this fiddle I've made it easy on myself to do such a calculation manually by setting a width on the wrapping div and knowing the height based on the inner sizes. This could get complicated with any dynamic sizing, but the link above I believe gives the calculations to do it dynamically using javascript (JQuery) with the sylvester.js as well.

like image 180
ScottS Avatar answered Oct 09 '22 04:10

ScottS