get CSS rule's percentage value in jQuery
Asked Answered
B

13

101

Let's say the rule is as follows:

.largeField {
    width: 65%;
}

Is there a way to get '65%' back somehow, and not the pixel value?

Thanks.

EDIT: Unfortunately using DOM methods is unreliable in my case, as I have a stylesheet which imports other stylesheets, and as a result the cssRules parameter ends up with either null or undefined value.

This approach, however, would work in most straightforward cases (one stylesheet, multiple separate stylesheet declarations inside the head tag of the document).

Bicipital answered 13/4, 2009 at 15:50 Comment(1)
It would be best to seed this data on the element itself and then track how it changes in the future.Sexagenarian
V
52

There's no built-in way, I'm afraid. You can do something like this:

var width = ( 100 * parseFloat($('.largeField').css('width')) / parseFloat($('.largeField').parent().css('width')) ) + '%';
Voiceful answered 13/4, 2009 at 16:9 Comment(6)
just to be clear, this doesn't tell you the value in your style, it gives you a computed valueSabina
@shevski it works fine, you have to add class="largeField" to the span, currently you are selecting an empty set.Voiceful
I know what's not working in it and that's why it's a counter-example.Affluent
@Affluent my example gives a computed value of an existing element on the page, as Anthony already pointed out a year ago. Your comments are superfluous.Voiceful
@AdamLassek, Anthony didn't say it most exists.Affluent
Other way: #30084417Planck
N
120

Most easy way

$('.largeField')[0].style.width

// >>> "65%"
Nordgren answered 3/5, 2012 at 13:57 Comment(4)
Just a note: this will only work with css directly applied on the element (e.g. style="width:65%").Kimura
Great!! To return just the numbers: parseInt($('.largeField')[0].style.width, 10);Meatball
Tiago, you can just use parseFloat().Bhayani
This works only in inline styling as @Kimura said.Armillary
A
85

This is 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.

Now... I wonder if I'm first to discover this hack:)

Update:

One-liner

element.clone().appendTo('body').wrap('<div style="display: none"></div>').css('width');

It will leave behind a hidden element before the </body> tag, which you may want to .remove().

See an example of one-liner.

I'm open to better ideas!

Antipole answered 9/11, 2013 at 7:56 Comment(10)
This should be the accepted solution. I can also confirm it works for me where the other answers don't get the originally assigned percentage value.Enamel
To avoid flickering, clone the child, hide the parent, then retrieve the width. var clone = $('.child').clone();Grory
Update: var childWidth = jQuery('.parent').clone().hide().find('.child').width(); However, this only returns a number. You couldn't use it to find whether the width was 50px or 50%.Grory
Update: function getCssWidth(childSelector){ return jQuery(childSelector).parent().clone().hide().find(childSelector).width(); } console.log('child width:' + getCssWidth('.child'));;Grory
Awesome solution! Here's a pure-js equivalent of the script jsfiddle.net/Sjeiti/2qkftdjdRoa
If the $(...)[0].style.width answer works, then shouldn't that be the accepted solution? This solution, while elegant, does suffer from some performance shortcomings.Cantal
@MihaiDanila $(...)[0].style.width won't work for most people, since it only works when you apply width through a style, not a class.Antipole
@MihaiDanila That information is already there. See stackoverflow.com/questions/744319#answer-10432934 and the highest rated reply to it.Antipole
I'm sure that the same information is also in many other places around the internet, but that's not helpful. There are plenty of folks like me who won't read the comments when looking for an answer, but will read through the various answers.Cantal
That is one AWESOME trick. I published a package on NPM using this trick. any contributions are welcome :) github.com/idanen/getSizePercentHeartwarming
V
52

There's no built-in way, I'm afraid. You can do something like this:

var width = ( 100 * parseFloat($('.largeField').css('width')) / parseFloat($('.largeField').parent().css('width')) ) + '%';
Voiceful answered 13/4, 2009 at 16:9 Comment(6)
just to be clear, this doesn't tell you the value in your style, it gives you a computed valueSabina
@shevski it works fine, you have to add class="largeField" to the span, currently you are selecting an empty set.Voiceful
I know what's not working in it and that's why it's a counter-example.Affluent
@Affluent my example gives a computed value of an existing element on the page, as Anthony already pointed out a year ago. Your comments are superfluous.Voiceful
@AdamLassek, Anthony didn't say it most exists.Affluent
Other way: #30084417Planck
X
45

You could access the document.styleSheets object:

<style type="text/css">
    .largeField {
        width: 65%;
    }
</style>
<script type="text/javascript">
    var rules = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
    for (var i=0; i < rules.length; i++) {
        var rule = rules[i];
        if (rule.selectorText.toLowerCase() == ".largefield") {
            alert(rule.style.getPropertyValue("width"));
        }
    }
</script>
Xerophthalmia answered 13/4, 2009 at 16:27 Comment(8)
+1 proper usage of DOM methods (sometimes jQuery is not the answer)Calfee
+1 I'm with you here for accuracy. I'm curious about how each browser suppports this, but this is the right answer.Kamerman
Works well in simpler cases, both FF and IE7, but not for me (see EDIT above).Bicipital
Have you tried running through all stylesheets too? My example just used the first (styleSheets[0]).Xerophthalmia
Sorry if this is a noob question, but how would for (var i=0; rules.length; i++) work? Shouldn't it be for (var i=0; i<rules.length; i++)Shepley
There is an issue with this method: there may be more specific rules that apply to an element, for example #somecontainer > .child > .largefield { width: 30% } - the proposed method does not take it into account and thus is not a reliable way to determine the final css rule that is being used for width calculation. There is a function in webkit that does the work for you - called window.getMatchedCSSRules, but it's only in Webkit...Burrill
If you're fetching an external stylesheet from a different domain, then you won't be able to read the rules (at least on Chrome). Same-origin policy at work, it seems.Drunk
styleSheets[0] is just the first stylesheet, not realiable and easy to get the correct fileAronoff
O
19

Late, but for newer users, try this if the css style contains a percentage:

$element.prop('style')['width'];
Oscar answered 7/6, 2016 at 10:9 Comment(1)
Worked like a charm for css font-size. $element.prop('style')['font-size];Diathesis
F
10

A jQuery plugin based on Adams answer:

(function ($) {

    $.fn.getWidthInPercent = function () {
        var width = parseFloat($(this).css('width'))/parseFloat($(this).parent().css('width'));
        return Math.round(100*width)+'%';
    };

})(jQuery);

$('body').html($('.largeField').getWidthInPercent());​​​​​

Will return '65%'. Only returns rounded numbers to work better if you do like if (width=='65%'). If you would have used Adams answer directly, that hadn't worked (I got something like 64.93288590604027). :)

Fractional answered 4/9, 2012 at 19:15 Comment(0)
Z
6

Building on timofey's excellent and surprising solution, here is a pure Javascript implementation:

function cssDimensions(element) {
  var cn = element.cloneNode();
  var div = document.createElement('div');
  div.appendChild(cn);
  div.style.display = 'none';
  document.body.appendChild(div);
  var cs = window.getComputedStyle
    ? getComputedStyle(cn, null)
    : cn.currentStyle;
  var ret = { width: cs.width, height: cs.height };
  document.body.removeChild(div);
  return ret;
}

Hope it's helpful to someone.

Zaller answered 6/4, 2016 at 19:29 Comment(2)
a syntax error, you forgot { in end of first line.Armillary
only this solution correctly shows 'auto' when width for div not set, jquery css('width') return '0px'. all other answers incorrect...Speculate
S
1

I have a similar issue in Getting values of global stylesheet in jQuery, eventually I came up with the same solution as above.

Just wanted to crosslink the two questions so others can benefit from later findings.

Sig answered 20/8, 2011 at 11:48 Comment(1)
Your question and this one are already linked (see the “Linked” sidebar on the right) by virtue of shesek’s comment on your question.Picturize
S
1

Convert from pixels to percentage using cross multiplication.

Formula Setup:

1.) (element_width_pixels/parent_width_pixels) = (element_width_percentage / 100)

2.) element_width_percentage = (100 * element_width_pixels) / parent_width_pixels

The actual code:

<script>

   var $width_percentage = (100 * $("#child").width()) / $("#parent").width();

</script>
Subtract answered 8/12, 2017 at 18:59 Comment(0)
M
1

A late response but wanted to add on for anyone 2020+ who stumbles across this. Might be more for niche cases but I wanted to share a couple options.

If you know what the initial % value is you can also assign these values to variables in the :root of the style sheet. i.e

:root {
    --large-field-width: 65%;
}

.largeField {
  width: var(--large-field-width);
}

When you want to access this variable in JS you then simply do the following:

let fieldWidth = getComputedStyle(document.documentElement).getPropertyValue('--large-field-width');
// returns 65% rather than the px value. This is because the % has no relative
// size to the root or rather it's parent.

The other option would be to assign the default styling at the start of your script with:

element.style.width = '65%'

It can then be accessed with:

let width = element.style.width;

I personally prefer the first option but it really does depend on your use case. These are both technically inline styling but I like how you can update variable values directly with JS.

Meliorate answered 28/8, 2021 at 7:15 Comment(0)
A
0

You could put styles you need to access with jQuery in either:

  1. the head of the document directly
  2. in an include, which server side script then puts in the head

Then it should be possible (though not necessarily easy) to write a js function to parse everything within the style tags in the document head and return the value you need.

Aftergrowth answered 13/4, 2009 at 16:24 Comment(0)
D
0

There's nothing in jQuery, and nothing straightforward even in javascript. Taking timofey's answer and running with it, I created this function that works to get any properties you want:

// gets the style property as rendered via any means (style sheets, inline, etc) but does *not* compute values
// domNode - the node to get properties for 
// properties - Can be a single property to fetch or an array of properties to fetch
function getFinalStyle(domNode, properties) {
    if(!(properties instanceof Array)) properties = [properties]

    var parent = domNode.parentNode
    if(parent) {
        var originalDisplay = parent.style.display
        parent.style.display = 'none'
    }
    var computedStyles = getComputedStyle(domNode)

    var result = {}
    properties.forEach(function(prop) {
        result[prop] = computedStyles[prop]
    })

    if(parent) {
        parent.style.display = originalDisplay
    }

    return result
}
Deadline answered 3/10, 2016 at 4:11 Comment(0)
B
-1

You can use the css(width) function to return the current width of the element.

ie.

var myWidth = $("#myElement").css("width");

See also: http://api.jquery.com/width/ http://api.jquery.com/css/

Ballyrag answered 6/3, 2010 at 10:42 Comment(2)
why is this marked down? there is a bug open on this bugs.jquery.com/ticket/4772, looks like there is some inconsistency in calling this depending on whether you put your style inline or in a style sheet jsfiddle.net/boushley/MSyqR/2Sabina
i cant get % with thisCapriccioso

© 2022 - 2024 — McMap. All rights reserved.