307

Is there a way in jQuery to get all CSS from an existing element and apply it to another without listing them all?

I know it would work if they were a style attribute with attr(), but all of my styles are in an external style sheet.

5 Answers 5

345

A couple years late, but here is a solution that retrieves both inline styling and external styling:

function css(a) {
    var sheets = document.styleSheets, o = {};
    for (var i in sheets) {
        var rules = sheets[i].rules || sheets[i].cssRules;
        for (var r in rules) {
            if (a.is(rules[r].selectorText)) {
                o = $.extend(o, css2json(rules[r].style), css2json(a.attr('style')));
            }
        }
    }
    return o;
}

function css2json(css) {
    var s = {};
    if (!css) return s;
    if (css instanceof CSSStyleDeclaration) {
        for (var i in css) {
            if ((css[i]).toLowerCase) {
                s[(css[i]).toLowerCase()] = (css[css[i]]);
            }
        }
    } else if (typeof css == "string") {
        css = css.split("; ");
        for (var i in css) {
            var l = css[i].split(": ");
            s[l[0].toLowerCase()] = (l[1]);
        }
    }
    return s;
}

Pass a jQuery object into css() and it will return an object, which you can then plug back into jQuery's $().css(), ex:

var style = css($("#elementToGetAllCSS"));
$("#elementToPutStyleInto").css(style);

:)

Sign up to request clarification or add additional context in comments.

29 Comments

BTW, when you say a JSON object, you just mean a JavaScript object right?
this looks awesome, but when I'm trying it it misses out on certain properties such as font-family.
@Damon: That's a valid assumption, considering the first line of the answer says ...here is a solution that retrieves both inline styling and external styling.
This code doesn't work any more (always returns empty object in Chrome)
Note: Moderators have modified my original code, I give no guarantee anything will work.
|
92

Two years late, but I have the solution you're looking for. Not intending to take credit form the original author, here's a plugin which I found works exceptionally well for what you need, but gets all possible styles in all browsers, even IE.

Warning: This code generates a lot of output, and should be used sparingly. It not only copies all standard CSS properties, but also all vendor CSS properties for that browser.

jquery.getStyleObject.js:

/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 */

(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            };
            style = window.getComputedStyle(dom, null);
            for(var i = 0, l = style.length; i < l; i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            };
            return returns;
        };
        if(style = dom.currentStyle){
            for(var prop in style){
                returns[prop] = style[prop];
            };
            return returns;
        };
        return this.css();
    }
})(jQuery);

Basic usage is pretty simple, but he's written a function for that as well:

$.fn.copyCSS = function(source){
  var styles = $(source).getStyleObject();
  this.css(styles);
}

6 Comments

@Damon: Thanks! I've updated my post, and edited the wording slightly to make it clear that this is not my work. Sorry about the previous wording, I think I typed this answer up late at night, but either way, it was pretty douchey.
Why does this return this.css()? There's no documentation for this method taking no arguments, and if this statement is reached, it throws an exception. I think it would be more appropriate to return returns; even if it's an empty object.
Would it be possible to get a working demo of this? Not clear to me where to put this code and how to invoke it. It's also not clear to me where the output is being stored. Thanks.
I do not understand how to use it, There's something called jsfiddle that most people use to help. Good programmer are the worse teacher
@Gino If you want to copy the style of div1 to div 2 just use: $("#div2").copyCSS($("#div1")); and to get the style of any element you could use: JSON.stringify($('#element').getStyleObject());
|
18

Why not use .style of the DOM element? It's an object which contains members such as width and backgroundColor.

3 Comments

I'm pretty sure this is the only way to get the actual styles associated with the class. (as opposed to the calculated styles which are different)
With .style you only get properties applied to the style attribute of the element, but not those applied with a CSS class.
+1 as i m using inline script and changing it dynamically afterwords
11

I had tried many different solutions. This was the only one that worked for me in that it was able to pick up on styles applied at class level and at style as directly attributed on the element. So a font set at css file level and one as a style attribute; it returned the correct font.

It is simple! (Sorry, can't find where I originally found it)

//-- html object
var element = htmlObject; //e.g document.getElementById
//-- or jquery object
var element = htmlObject[0]; //e.g $(selector)

var stylearray = document.defaultView.getComputedStyle(element, null);
var font = stylearray["font-family"]

Alternatively you can list all the style by cycling through the array

for (var key in stylearray) {
console.log(key + ': ' + stylearray[key];
}
4

@marknadal's solution wasn't grabbing hyphenated properties for me (e.g. max-width), but changing the first for loop in css2json() made it work, and I suspect performs fewer iterations:

for (var i = 0; i < css.length; i += 1) {
    s[css[i]] = css.getPropertyValue(css[i]);
}

Loops via length rather than in, retrieves via getPropertyValue() rather than toLowerCase().

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.