51

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?

joren
  • 1,135
  • 2
  • 11
  • 22
  • 4
    This question seems to be asking two orthogonal questions; please consider revising. The two questions are: 1) 'How can I get the width of an element, in %?' (from the title) and 2) 'How can I get the CSS value specified in the style-sheet?' (from the body). –  Oct 24 '10 at 01:25

10 Answers10

88

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;
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 2
    Thanks, that would certainly work, but I wanted to have the script automatically determine whether the developer specified a percent or pixel, which I don't think can be done so I'll just add it as an option that they can pass to the plugin. – joren Oct 24 '10 at 15:29
  • 4
    @joren - Please revise your question title. It contradicts the meaning of your actual question. – Peter Ajtai Oct 24 '10 at 16:39
  • @joren: I saw that you revised your question title. Do you have further questions? – Matt Ball Oct 25 '10 at 14:25
  • Not really, I still ended up deciding to just add setting the percent of the div as an option to my plugin, it seemed the best course of action after this discussion. Thanks! – joren Oct 27 '10 at 15:44
  • Does it works for height too? I didn't understand the offsetParent() function :( – sadfuzzy Jan 24 '13 at 10:48
  • what if the parent width was in percentage also? should i have to loop till i reach a parent div with fixed width? – user1386213 Jun 02 '14 at 11:40
  • 2
    @user1386213 no. `.width()` always returns an absolute (# pixels) value. – Matt Ball Jun 02 '14 at 13:01
  • I ran into troubles if the desired element has `display: none`. Seems to be the same error like in [`.offset()`](https://api.jquery.com/offset/): "... `display:none` is excluded from the rendering tree and thus has a position that is undefined" – cheich May 15 '15 at 09:30
  • Anyone struggling to calculate the width of element that have borders: add `parseFloat($('#someElt').css('border-width')) * 2` to the elements' width – Bruno Peres Aug 21 '15 at 18:35
11

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.

Timofey Drozhzhin
  • 4,416
  • 3
  • 28
  • 31
  • 2
    This is really weird. The element might blink and it doesn't really rely on the actual purposes of these function. What if this behavior changes? – Gherman Jul 13 '15 at 08:34
  • @German - to prevent the element from blinking, see the one-liner example on http://stackoverflow.com/questions/744319#19873734 – Timofey Drozhzhin Oct 15 '15 at 05:55
9

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 %'.

  • How does this return a percent? – Peter Ajtai Oct 24 '10 at 00:38
  • 1
    I see. I was going off the title: `Getting jQuery .width() to output percentage instead of px?`. The question body contradicts the title. It's unclear what the OP wants. – Peter Ajtai Oct 24 '10 at 16:38
  • According to this: http://stackoverflow.com/a/10432934/1825772 only works for css applied directly to element. – pd12 Jan 21 '16 at 00:37
2

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');
Community
  • 1
  • 1
netadictos
  • 7,602
  • 2
  • 42
  • 69
  • How does this return a percent if the orginal style is either not in a percent or it is not defined? – Peter Ajtai Oct 24 '10 at 00:40
  • The question is: "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?", that is to say the user is asking to ouput what is in the css. – netadictos Oct 24 '10 at 07:16
  • I see. I was going off the title: `Getting jQuery .width() to output percentage instead of px?`. The question body contradicts the title. It's unclear what the OP wants. – Peter Ajtai Oct 24 '10 at 16:38
1

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

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'));
Alan Mabry
  • 17
  • 1
0

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

Nick Ginanto
  • 31,090
  • 47
  • 134
  • 244
0

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

Jay Shah
  • 3,553
  • 1
  • 27
  • 26
0

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;
Nexarius
  • 346
  • 4
  • 11
-1

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
Franva
  • 6,565
  • 23
  • 79
  • 144