I'm writing a jQuery plugin and something I need to be able to do is determine the width of an element that the user specifies. The problem is that .width() or .css('width') will always report exact pixels, even if the developer has assigned it e.g. width:90% with CSS.

Is there any way to have jQuery output the width of an element in px or % depending on what the developer has given it with CSS?

Solution 1

I'd say the best way is to compute it yourself:

var width = $('#someElt').width();
var parentWidth = $('#someElt').offsetParent().width();
var percent = 100*width/parentWidth;

Solution 2

It's most definitely possible!

You must first hide() the parent element. This will prevent JavaScript from calculating pixels for the child element.

$('.parent').hide();
var width = $('.child').width();
$('.parent').show();
alert(width);

See my example.

Solution 3

I think you can use stylesheet ('style') object access directly. Even then, YMMV by browser. e.g. elm.style.width.

Edit for Peter's comment:: I am not looking to 'get a %'. As per the question:

I need to be able to do is determine the width of an element that the user specifies ... [is there a way to] output the width of an element in px or % depending on what the developer has given it with CSS?

Thus I provided an alternative to retrieve the "raw" CSS value. This appears to work on FF3.6. YMMV elsewhere (netadictos's answer may be more portable/universal, I do not know). Again, it is not looking to 'get a %'.

Solution 4

The way to do it is documented in this stackoverflow question.

How do you read CSS rule values with JavaScript?

The only thing you have to know is in which stylesheet is the class or loop through all the stylesheets. The following function gives you all the features of the class, it would be easy to do a regex to extract the feature you look for.

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');

Solution 5

For my purposes I extrapolated off MДΓΓ БДLL's answer.

Keep in mind, I'm only working with whole percentages.

    var getPercent = function(elem){
        var elemName = elem.attr("id");
        var width = elem.width();
        var parentWidth = elem.offsetParent().width();
        var percent = Math.round(100*width/parentWidth);
        console.log(elemName+"'s width = "+percent+"%");
    }

    getPercent($('#folders'));
    getPercent($('#media'));
    getPercent($('#player'));

Solution 6

If you are looking to reassign the original elements percentage to a new percentage, it is a good practice to define that value in CSS and modify the elements identifier in some way (class, id, etc) to reflect the new CSS definition. This does not always apply if the new percentage variable needs to be variable.

.myClass{
    width:50%;
}

.myNewClass{
    width:35%;
}

Adding a removing via this (or other) method:

$('.myClass').removeClass('myClass').addClass('myNewClass');

Solution 7

just to make it more jqueryish

add this

$.fn.percWidth = function(){
  return this.outerWidth() / this.parent().outerWidth() * 100;
}

and then use

$(selector).percWidth()

this will return the percent value without the % sign, so you can use it in calculations

Solution 8

If Its set using style tag, You can simply use .prop()
e.g. $('.selector').prop('style').width.replace('%', '')

Solution 9

Why has nobody answered this 'normally'? There are just those weirdly strange approches here.

USE VANILLA JAVASCRIPT

Don't do:

const a = $(element).width();
const b = $(element).css("width");

Do:

const c = $(element)[0].style.width;

Solution 10

I recently met this problem as well, and I really didn't want to do the "extra" work which was getting the width of the parent and calculating the percentage.

After a few quick attempts, this is what I have got:

    $($($(table).find('tr')[0]).find('td')).each(function (i, e) {
        var proptW = $(e).prop("style").width;
        console.log(proptW);
    });

So, I think this is the closest way to use jQuery to get the value of the width of an element based on what the developer specified in the css.

As you can see, I have a table and I need to retrieve the widths for each of columns.

We cannot get the developer specified value(DSV) directly with jQuery method, but after combined with the JavaScript built-in method, it's just one step away from getting the DSV.

As the DSV is in the Style and Style is a property of an element, so we can use the jQuery method: prop() to get it. This method returns the style object(say sty), so that we can call sty.width to get the DSV directly.

This is not the pure jQuery way to get it, but it is simple enough and works for me.