Retrieve width/height of a css3 scaled element
Asked Answered
C

4

43

I'm fighting against an oddity (I think) of the offsetWidth property.
this is the scenario:

I've got, let's say, a span tag, in my js, at a certain point I perform a css3 transform to this element, like:

        el.set('styles', {
            'transform':'scale('+scale+', '+scale+')',      /* As things would be in a normal world */
            '-ms-transform':'scale('+scale+', '+scale+')',      /* IE 9 */
            '-moz-transform':'scale('+scale+', '+scale+')',         /* Moz */
            '-webkit-transform':'scale('+scale+', '+scale+')',  /* Safari / Chrome */
            '-o-transform':'scale('+scale+')'       /* Oprah Winfrey */ 
        }); 
        w = el.getWidth();
        console.log('after scaling: ' + w);

at this point the log returns me fuzzy values, like it doesn't know what to say.
any suggestion?

Cruzeiro answered 29/4, 2011 at 16:22 Comment(9)
Fuzzy values? Can you explain that one a bit more, please.Woodson
@Blowski, sure m8, as long as I put the above code in a loop that iterates 100 times, every time that the code hits console.log I get the same value (i.e. the setence 'lorem ipsum sit dolor' scaled of 10, always returns its initial value: 272px, so, according to the log, the scale doesn't affect the size at all, even if the phrase on the screen gets huge )Cruzeiro
@Cruzeiro Can you post the getWidth() function you're using as well. And what browser(s) are you checking in?Woodson
@Blowski I've used both the offsetWidth, getWidth() and window.computedStyle(el) functions (all gets the same) and I've test it in Moz, Safari and Chrome (with the same results). By inspecting the element with firebug, it shows me that the element size itself is not changed at allCruzeiro
and further more I'd like to know y the scale transition begins from the center of the element and not from the {0,0} coordinates.. :-/Cruzeiro
k I discovered it myself, developer.mozilla.org/En/CSS/-moz-transform-origin [ LOL ]Cruzeiro
@Cruzeiro So it's all working? In which case, write your solution as an answer, and then choose it...Woodson
no, it's not working properly. I mean, I've found a workaround. that's kinda working but it's not a solution.Cruzeiro
see stackoverflow.com/a/30157405Uncommercial
D
49

getBoundingClientRect() returns the correct values for me.

jsFiddle.

Damselfly answered 14/6, 2012 at 0:0 Comment(6)
This does work for me in Chrome, but from the spec it does not seem like it should: "Note: Transformations do affect the visual layout on the canvas, but have no affect on the CSS layout itself. This also means transforms do not affect results of the Element Interface Extensions getClientRects() and getBoundingClientRect(), which are specified in [CSSOM-VIEW]."Mcmullin
@JakeCobb That's quite odd, it seems no vendor listened to that spec :)Damselfly
Instead they decided to change the spec to make it fit : DSaliva
Actually "for me" is not a very precise answer. You didn't even mention your browser, neither did you mention other browsers behavior.Bowse
I have tested positive in latest Firefox, Chrome and Safari on macOS, August 2018Bowse
Not working for me for an image inside a scaled divHardbitten
R
5

Transforms don't affect the intrinsic CSS properties, so you are seeing correct behavior. You need to look at the Current Transformation Matrix - as returned from getComputedStyle().webkitTransform in order to figure out how big something has been scaled.

Update: In Firefox 12 and later and Chrome/Safari - as Alex says below, you can use getBoundingClientRect() to take into account any transforms applied to an element

The scale transition starts from 50%/50% because that's the default & correct behavior. If you want it to start from the origin, then you need to set transform-origin: 0% 0%;

Rahr answered 29/4, 2011 at 17:58 Comment(3)
I've tried with window.getComputedStyle(el).getWidth() but it still gave me the same result, you think that I should retrieve another parameters?Cruzeiro
ok, I've extracted the transformation matrix, but the only thing that tells me, it's something I already know: matrix(1.18577, 0, 0, 1.18577, 0px, 0px) this data is useless to me, because I already know which scale ratio I applied to the element; I'd rather need the new size of my scaled objectCruzeiro
If you just need to know coordinates (offsetLeft, offsetTop) setting the transform-origin to the top-left corner (0% 0%) works perfectlySirree
E
0

I take it the span tag has display:block? transforms are only supposed to work for block elements. When I goto console and load jquery (just for ease) and do this:

$('span#foo').css({"-webkit-transform": "scale(2.0, 2.0)"})

nothing happens. But if I do this:

$('span#foo').css('display','block').css({"-webkit-transform": "scale(2.0, 2.0)"})

suddenly it changes, and offsetHeight increases. Disappointingly, the offset hight goes from 16 to 19, and not to 32 (although the visual appearance is double the size and maybe it is accurate) — but at least it does appear to work as advertised.

Experience answered 3/5, 2011 at 18:50 Comment(2)
Yes, transforms are not supported on inline displayed elements in webkit - although the spec explicitly states that they should be.Rahr
that's cool, 'though I just read the other day how transforms are supposed to only affect block elements :P seems to be a recent change at least. either way, the point remains: transforms do effect HTMLElement properties, explicitly the offsetHeight and offsetWidthTallboy
W
-1

getBoundingClientRect() didn't work for me (in Chrome 49).

This answer led me to another solution to my problem: https://mcmap.net/q/390968/-read-css-property-of-an-element-using-javascript

function getStyleProp(elem, prop){
    if(window.getComputedStyle)
        return window.getComputedStyle(elem, null).getPropertyValue(prop);
    else if(elem.currentStyle) return elem.currentStyle[prop]; //IE
}
getStyleProp(element, 'zoom')    //gives zoom factor to use in calculations
Wendish answered 15/5, 2016 at 4:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.