5

How can we use JavaScript to get the value of the declared CSS value (like the value that shows up when inspecting an element using Chrome's inspector? Everything I try and search for on the web seems to only want to give the computed value.

For my specific use case I want to know what the width will be at the end of a CSS transition, which is set in the stylesheet, not inline. When I check for the width using JavaScript, I get the computed width, which at the time of retrieval in the script is at the beginning of the transition, so shows me 0 even though in 300ms it will be a declared width like 320px.

Ben
  • 2,917
  • 10
  • 28
  • 47
  • Assuming CSS is still local, you may be able to play with [`document.styleSheets`](https://developer.mozilla.org/en-US/docs/Web/API/Document/styleSheets). – Brad Christie May 08 '15 at 19:11
  • You just need to wait until the transition is complete, then you grab the value. – emerson.marini May 08 '15 at 19:12
  • @MelanciaUK the whole point of the question is that I don't want to wait until the transition is complete (for various rather verbose reasons to explain). I just want to know if there's a way to do it without waiting. – Ben May 08 '15 at 19:15
  • Could you get the width of it's parent? If the parent doesn't have a set width, could you give it one? – crowhill May 08 '15 at 19:19
  • http://stackoverflow.com/a/324533/468570 take a look at this answer. – Ruslanas Balčiūnas May 08 '15 at 19:28

3 Answers3

3

Take a look at transitionend event. Can it be used for your use case?

EDIT

Since this answer got upvoted i'm pasting some code below.

element.addEventListener("transitionend", function() {
    // get CSS property here
}, false);
Ruslanas Balčiūnas
  • 7,310
  • 3
  • 24
  • 41
  • Can't be used in my case, because I have to start another animation at exactly the same time, and need to calculate it based on what the ending width will be of the first element. – Ben May 08 '15 at 19:35
  • @ben, if you had pasted some code, this answer could be improved. There may be a case when you can solve your problem in pure CSS. – Ruslanas Balčiūnas May 08 '15 at 19:40
2

I think this is what you're after:

$('#widen').on('click', function(e){
    $('.example').addClass('wider');
    
    $('#prefetch').text('The div will be: ' + getWidth('wider'));
});

function getWidth(className){
    for (var s = 0; s < document.styleSheets.length; s++){
        var rules = document.styleSheets[s].rules || document.styleSheets[s].cssRules; console.log(rules);
        for (var r = 0; r < rules.length; r++){
            var rule = rules[r]; console.log(rule);
            if (rule.selectorText == '.'+className){
                console.log('match!');
                return rule.style.width;
            }
        }
    }
    return undefined;
}
.example {
    width: 100px;
    background-color: #ccc;
    border: 1px solid black;
}
.wider {
    width: 320px;
    -webkit-transition: width 5s;
    -moz-transition: width 5s;
    -o-transition: width 5s;
    transition: width 5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div class="example">This is a simple container.</div>
<button id="widen" type="button">Widen</button>
<span id="prefetch"></span>

Keep in mind, I believe this still falls victim to cross-domain preventions (if the CSS is hosted on a CDN/other domain, you won't be able to retrieve the styleSheet, and, therefore, not be able to access then eventual width.

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
0

I selected the most helpful answer to my question, but it appears that the solution I was looking for does not exist. What I needed was to get what the width of an element would be in pixels BEFORE the transition actually was completed. This width is percent based and so the actual pixels width would vary based on a number of factors. What I ended up doing in reality was:

  • Making a jQuery clone of the item of which I needed the "end" transition measurement.
  • Positioning the clone off screen
  • Adding inline styles to the clone, remove the CSS inherited transition properties so that it immediately gets the final/end width.
  • Using JS to save the ending width to a variable
  • Removing the clone with jQuery's .remove()

Doing this, I now know what the ending width in pixels would be at the moment the element begins to transition, rather than having to wait until the end of the transition to capture the ending width.

Here is a function that does what I described above.

var getTransitionEndWidth = function($el) {
    $('body').append('<div id="CopyElWrap" style="position:absolute; top:-9999px; opacity:0;"></div>');
    var copyEl = document.createElement('div');
    var $copy = $(copyEl);
    var copyElClasses = $el.attr('class');

    $copy.attr('class', copyElClasses).css({
        WebkitTransition: 'all 0 0',
        MozTransition: 'all 0 0',
        MsTransition: 'all 0 0',
        OTransition: 'all 0 0',
        transition: 'all 0 0'
    }).appendTo($('#CopyElWrap'));
    var postWidth = $copy.width();
    $('#CopyElWrap').remove();
    return postWidth;
};
Ben
  • 2,917
  • 10
  • 28
  • 47