Using Mootools Element.Dimensions I can get the computed size, in pixels, of any element. However, I can find no way of telling whether an element has been sized using pixel or percentage values (other than in the special case of its having an inline style).
Is there a sensible way of doing this? The only solution I can think of (which is so hideous that it barely deserves the name) is to walk through the document stylesheets, looking for selectors that match the target element and then looking through the declared styles for the target propety.
Background
I'm attempting to replace all textareas of a certain class with CKEditor instances. Ideally, textareas with 100% width would be replaced by similarly styled editor instances - so they would scale on window resize - while fixed size textareas would be replaced by fixed sized editors.
Yes, I could just give them a different class (which I will do if there's no nice solution), but ideally I'd like to be able to drop in my CKEditor script and have everything just work without having to tweak the HTML.
It can be done. Looking at this question (Why does getComputedStyle return 'auto' for pixels values right after element creation?) gives us the hint.
If you set the element's style to display = none and then call getComputedStyle you will get the calculated value (percentage width or 'auto' or whatever the stylesheets apply to the element) instead of the pixel width.
Working code jsfiddle https://jsfiddle.net/wtxayrnm/1/
function getComputedCSSValue(ele, prop) {
var resolvedVal = window.getComputedStyle(ele)[prop];
//does this return a pixel based value?
if (/px/.test(resolvedVal)) {
var origDisplay = ele.style.display;
ele.style.display = 'none';
var computedVal = window.getComputedStyle(ele)[prop];
//restore original display
ele.style.display = origDisplay;
return computedVal;
} else {
return resolvedVal;
}
}
It should be noted that this will cause the layout to be re-rendered but, depending on your situation, it's probably a simpler solution than traversing all the stylesheet rules or cloning the element (which can cause some cascading rules to not be applied).
Not that familiar with Motools but in jQuery you can do it.
Check here for a live demo http://jsbin.com/ewuqa
Or check this it handles also multiple matching CSS rules but only returns the correct value (the only thing I didn't bother to handle is if !important
is set).
Included JS
http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
http://github.com/hafriedlander/jquery.concrete/raw/master/vendor/jquery.selector/jquery.class.js
http://github.com/hafriedlander/jquery.concrete/raw/master/vendor/jquery.selector/jquery.selector.js
http://github.com/hafriedlander/jquery.concrete/raw/master/vendor/jquery.selector/jquery.selector.specifity.js
Own functions
function compare(as,bs) {
return (as[0] - bs[0]) || (as[1] - bs[1]) || (as[2] - bs[2]);
}
//selector should only match a single element
//property is a css style-name
//returns the set css value (if set) for matched element, not the computed value
//also handles multiple matching rules and only returns most specific match
//doesn't handle !important
function whatIsSet(selector, property) {
var se = $(selector);
var regex = new RegExp("(.*)-(.)(.*)","g");
var p = property;
if (/-/.test(p)) {
p = regex.exec(property);
p = p[1] + p[2].toUpperCase() + p[3];
}
if (se.get(0).style[p] != undefined && se.get(0).style[p] != '')
return se.get(0).style[p];
var matchers = new Object();
var mostSpecific = undefined;
for(var i = 0; i < document.styleSheets.length; i++) {
//IE support
var rules =
document.styleSheets[i].cssRules ?
document.styleSheets[i].cssRules :
document.styleSheets[i].rules;
for (var j=0; j < rules.length; j++)
if (rules[j].style[p])
if (jQuery.inArray(se, $(rules[j].selectorText)))
matchers[rules[j].selectorText] = rules[j].style[p];
}
for(var i in matchers) {
if(mostSpecific != undefined) {
var ms = $.selector(mostSpecific).specifity();
var is = $.selector(i).specifity();
mostSpecific = compare(ms, is) > 0 ? mostSpecific : i;
} else
mostSpecific = i;
}
return matchers[mostSpecific];
}
CSS
body { background-color: #000; font: 16px Helvetica, Arial; color: #fff; }
#myElement {background-color: yellow; width:10%}
div {background-color: green; width:200px}
div#myElement {background-color: blue; width:30%}
div.asd#myElement {background-color: red; width:50%;}
HTML
<div id="myElement" class="asd" style="width:91%">asd</div>
<input
type="button"
onclick="javascript:alert('width originally set to: '+
whatIsSet('#myElement', 'width'));"
value="Tell me original width!"><br>
<input
type="button"
onclick="javascript:alert('height originally set to: '+
whatIsSet('#myElement', 'height'));"
value="Tell me original height!"><br>
<input
type="button"
onclick="javascript:alert('background-color originally set to: '+
whatIsSet('#myElement', 'background-color'));"
value="Tell me original background-color!"><br>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With