Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firefox -moz-transform:scale scales the graphic but takes up the same amount of space

Tags:

css

firefox

I am resizing icons on a sprite sheet by scaling the image with CSS. In Chrome it works fine. Firefox scales the graphic correctly but it takes up the same space as the unscaled version.

I found -moz-focus-inner which removed some padding but doesn't appear to be related.

I've tried reducing the size of the image in CSS, but it crops then scales instead of scaling then cropping, and it breaks Chrome's version. This is it in Firefox :(

I don't want to add more tags to fix it, e.g. I could wrap the <i> with a <span> and set the span's CSS to width:x and height:x and overflow:hidden. I'm looking for a CSS solution to fix this, so without creating another sprite sheet, without changing the HTML and without JS, if there is one.

<button class="btn"><i class="icon"></i></button>
<button class="btn"><i class="icon icon-small"></i></button>

CSS

.btn, .btn-small{
    border:0;
    background:#000;
    padding:5px;
    margin:5px;
}

.icon{
    width:50px;
    height:50px;
    background-image:url(https://ssl.gstatic.com/gb/images/v1_53a1fa6a.png);
    background-position: -145px -75px;
    background-repeat:no-repeat;
    display:inline-block;

}

.icon-small{
    zoom:0.5;
    -moz-transform:scale(0.5);
    -moz-transform-origin: 0 0;
}

Fiddle

like image 271
Popnoodles Avatar asked Oct 02 '22 05:10

Popnoodles


1 Answers

Extending from comment:

That's how transform means to work: modifying the coordinate space to change the position and shape of the affected content without disrupting the normal document flow. So a scaled element still take up as much space as it should, only "visually" scaled;

zoom on the other hand, is a Microsoft extention that actually zoom the object, causing "the content that surrounds the object to reflow".

Chrome seems to adopt this property for whatever reason, but the two is not exactly equal.

If the background image is a standalone image, you can use background-size: contain to follow the scaling;
but in case of sprite sheet, you might "shrink" the sheet with background-size and then re-position:

/* origin coord: */
.icon{
    width:50px;
    height:50px;
    background-image:url(https://ssl.gstatic.com/gb/images/v1_53a1fa6a.png);
    background-position: -145px -75px;
    background-repeat:no-repeat;
    display:inline-block;
    vertical-align:text-bottom;
}

/* shrinked coord: */
.icon-small-resized{
    width:25px;
    height:25px;
    background-position:-72.5px -37.5px;
    background-size:268px 170.5px;
}

Explain:

  • The original sheet is 536px width, 341px height, so I shrink it to 536/2=268px width, 341/2=170.5px height, thus "scaling" both dimensions to half;
  • And because both dimensions are scaled, position has to change from -145 to -145/2=-72.5px left, -75 to -75/2=-37.5 top.

JSFiddle demo

How browser handle the 0.5px is unpromising, though. I tested it on a non-GPU-accelerated Firefox XP, and the background has some gap.

like image 53
Passerby Avatar answered Oct 10 '22 02:10

Passerby