0

Currently the width() method and all of it's variations in jQuery return pixel values. The same happens when calling the css('width') method.

I have elements, which are styled in .css files, and I have no way of knowing if they're styled in percentages or pixels, but in case it's in percentage or no width is explicitly set on the element, I need to get a percent value.

For example if I have the following:

.seventy { width: 70%; }
.pixels { width: 350px; }

<div class="seventy"></div>
<div class="pixels"></div>
<div class="regular"></div>

I would need these results.

$('.seventy').method() //=> '70%'
$('.pixels').method() //=> '350px'
$('.regular').method() //=> '100%' since that's how block elements behave

Is there anything in jQuery I can use to achieve this effect? Or a custom approach to it?

GMchris
  • 5,439
  • 4
  • 22
  • 40
  • For what purpose do you need it ? – Loenix Oct 20 '16 at 15:24
  • @Loenix It's for an HTML editor of sorts. And I need users to be able to modify elements. But I also want the correct previous value to be displayed, since 70% is fluid, while for instance 500px is not. – GMchris Oct 20 '16 at 15:26
  • 1
    Unfortunately javascripts `style` and `getComputedStyle` returns pixels. Returning anything else is usually complicated, and not worth it most of the time – adeneo Oct 20 '16 at 15:26
  • You'll need to traverse the documents stylesheets looking for a match. See: http://stackoverflow.com/a/16966533/1921385 – Moob Oct 20 '16 at 15:31

2 Answers2

1
function getStyle(className) {
var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
for (var x = 0; x < classes.length; x++) {
    if (classes[x].selectorText == className) {
        (classes[x].cssText) ? alert(classes[x].cssText) : alert(classes[x].style.cssText);
    }
  }
}
getStyle('.test');
jdmdevdotnet
  • 1
  • 2
  • 19
  • 50
1

You can parse the document.stylesheets to find a match. Note, this will only return the actual style after the browser has parsed it so is of no use for getting raw unadulterated CSS as written in file. For that you'd need to parse the file itself rather than the document.stylesheets.

This code is old and untested so your mileage may vary. I have no idea how well it performs with inherited values or more complicated selectors.

//TEST PARSE CSS
var CSS = function () {
    var _sheet;
    var _rules;
    function CSS() {
        _sheet = document.styleSheets[0];
         if (_sheet.rules) {
       _rules = _sheet.rules; // IE
   } else {
       _rules = _sheet.cssRules; // Standards
   }
        this.find = function (selector) {     
   var i = _rules.length;
   while(i--){
    if (_rules[i].selectorText == selector) {
     break;
    }
    if(i==0){break;}
   }
   //return _rules[i].cssText;
   return _rules[i].style;
        }

        this.set = function (foo) {
            //to do
        }
    };

    return new CSS();
};
//init
var css = new CSS();
//view the console.
console.log(css.find(".regular"));//Note how the width property is blank
//update elements with the results
document.querySelector(".seventy").innerHTML = css.find(".seventy").width;
document.querySelector(".pixels").innerHTML = css.find(".pixels").width;
document.querySelector(".regular").innerHTML = css.find(".regular").width;
//other tests
document.getElementById("a").innerHTML = css.find("body").color;
document.getElementById("b").innerHTML = css.find("h1").color;
document.getElementById("c").innerHTML = css.find("h1").width;
document.getElementById("d").innerHTML = css.find(".notInDom").color;
body {
  font-family:sans-serif;
  color:black;
  background-color:#cccccc;
}

h1 {
  color:blue;
  font-size:1.5em;
  font-weight:400;
  width:70%;
}

.seventy, .pixels, .regular {display:block; border:1px solid red;}

.seventy {display:block; border:1px solid red; width: 70%; }
.pixels { width: 350px; }
.regular {}

.notInDom {
  color:red;
}
<h1>Find and Read Style Attributes Directly from the Stylesheet.</h1>

<div class="seventy"></div>
<div class="pixels"></div>
<div class="regular"></div>

<ul>
  <li>css.find("body").color = <span id='a'></span></li>
  <li>css.find("h1").color = <span id='b'></span></li>
  <li>css.find("h1").width = <span id='c'></span></li>
  <li>css.find(".notInDom").color = <span id='d'></span></li>
</ul>
<p>This is a work in progress and hasn't been tested in any meaningful way. Its messy and very limited.</p>
Moob
  • 14,420
  • 1
  • 34
  • 47