views:

190

answers:

2

So, this is a problem that's been asked before, but I'm hoping we can lay it to rest: I'm using jQuery 1.4. If I define the style

#obj { margin: 0 auto; }

and then do

$('#obj').css('marginLeft');

the result is the computed value in pixels. Is there any way to tell whether those pixels come from the auto calculation or not, without parsing document.styleSheets?

A: 

You can't get the auto from the element itself, because styles are cascading, what if you had this?

#obj { margin: 0 auto; }
div #obj { margin: 0 10px; }

Which is it? Depends on the page and how it cascades, the basic concept is you're getting the calculated style properties on that element, what's in the stylesheet doesn't matter, there could be 20 stylesheets, etc.

Basically it boils down to this: getting auto vs 000px is a really rare request and would required a lot of extra code to figure out, so much so that it's an easy case of "no, this doesn't belong in core". However, there are plugins to do CSS parsing.

Short answer: jQuery core cannot (doesn't have code to) do this, jQuery with plugins, or just JavaScript in general yes you can.

Nick Craver
Yes, I realize that jQuery core can't do this. It's not obvious how the plugin you linked to will help me to do this, either. In the case you give, surely someone has written code that will tell me whether the `auto` style is active on `#obj`?
Trevor Burnham
@Trevor - You're trying to access which style in the stylesheet for a particular CSS property is assigned to that element...but that's not something that's exposed by the browser, it was never part of any spec and there isn't a property you can access it through. Remember though JavaScript is a dynamic language, properties it accesses are available on the DOM somewhere, **explicitly** exposed by native code...this one isn't :) In most cases "auto" is actually transformed into a centering function hooked to a flow change event handler, after it's attached, it doesn't care if it said "auto" :)
Nick Craver
I get that it's not directly exposed, but it can, in principle, be discovered. For instance, if the container element were resized, then the computed margins would change. So I'm asking: How to discover it? Is there a jQuery plugin that can take care of that discovery for me?
Trevor Burnham
@Trevor - I don't think I'm conveying it correctly, it's *not* exposed **to JavaScript** *at all*, directly or not, there is no way to get this from the browser...all you can do is traverse the cascading style tree (by parsing your CSS in your own code) and attempt to see which rule matches it. jQuery can't find what JavaScript as a whole can't see. The margins are changing on resize yes, but the browser's doing it, and it's not exposing it's thought process or variables used along the way. *How* it works doesn't matter...it's the API *you can see* that matters, and you can't see this.
Nick Craver
A: 

This solution would also be triggered if the margins were set to percentages, but it might be good enough for your purposes. Basically, you record which margins change on resize. So you'd record the margins before resize to an array:

var aMargins = [];
$('.yourObjs').each(function(i,obj){
  var objML = $(obj).css('marginLeft');
  aMargins.push(objML);
});

Then resize the window, see which margins changed (these will be either 'auto' or %), do what you need to do to them and return he window to original size:

var wW = $(window).width();
var wH = $(window).height();  
window.resizeTo(wW - 5, wH);
$('.yourObjs').each(function(i,obj){
  if ($(obj).css('marginLeft') != aMargins[i]) {
    // your centering code here
  }
}
window.resizeTo(wW,wH);

If your centering code just adjusts the left margin then this should work fine for % based margins too. I can't test this code or provide an example because I'm on the road and writing from my phone, but hopefully this works or helps you come up with something that will.

mVChr