7

What's the most efficient way in jQuery to extend/inherit CSS properties from one element to another?

Desired effect

$('#blah').extendCSSTo('#me') // Is there a plugin or a good way to do this?
$('#me').css({ background: 'blue' });

#me will now have all the CSS of #blah and also background

CSS:

#blah {
    padding: 5px;
    width: 200px;
    height: 20px;
    border: 1px solid #333;
    font-family: "Verdana";
}

#me {
    position: absolute;
    left: 5px;
    top: 5px;
}

<div id="blah"></div>
<div id="me">test</div>

Edit: This will be used in a plugin so using classes and simply doing .addClass is not an option

I'm looking for the same effect as setting default value for plugin options, but instead for CSS:

$.extend([css object], [#blah css object], [#me css object])
Community
  • 1
  • 1
Gary Green
  • 22,045
  • 6
  • 49
  • 75
  • Can't you just in your CSS change `#blah` to `.blaClass`, and then add `.blaClass` to `#me` with `.addClass()`? – thirtydot Jun 08 '11 at 10:54
  • Given that the CSS model in jQuery is being derived from the DOM not the CSS file your method would override padding, width, height, border and font-family... position, left, top, right, bottom, etc. You see my point. If I want more than one element to share CSS properties the I tend to use a CSS class, i.e. `.commonCSS` rather than assigning by ID. Then you can use `addClass`. – Lazarus Jun 08 '11 at 10:55
  • `.addClass` isn't possible as it's used on sites that I have no control over. It's for use in a general plugin/script across multiple sites. – Gary Green Jun 08 '11 at 10:57
  • @Lazarus, I see, so what your saying is there's no way of knowing what CSS properties where set in the *file* as all CSS properties exist and have a value set? I was hoping for functionality just like when setting default plugin options; `$.extend([css object], [#blah css object], [#me css object])` – Gary Green Jun 08 '11 at 11:02
  • @Gary Green: I'm fairly sure what you're asking for *is possible*. For example, the second answer on this similar question looks hopeful: http://stackoverflow.com/questions/754607/can-jquery-get-all-css-styles-associated-with-an-element – thirtydot Jun 08 '11 at 11:08
  • Stop writing tags in titles please. After 2 years you should know better! – Lightness Races in Orbit Jun 08 '11 at 11:17
  • @Gary Green : Exactly. To accurately produce the effect I think you are looking for you'd need to parse the CSS files associated with the page, build a list of all the attributes assigned across all methods (by class, by ID, by tag name) and files (after all these are cascading style sheets) and then assign those to your target element. – Lazarus Jun 08 '11 at 11:18
  • Thanks Tomalak, tagging is sufficient although highlighting the target language in the title doesn't hurt. I'm not sure I appreciate the rude comment "you should know better." Anyway thanks for sharing good practise. – Gary Green Jun 08 '11 at 12:06

3 Answers3

2
$('#me').addClass('class');

This works, not sure if you can use the css relative to an ID though.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
José Valente
  • 331
  • 1
  • 10
1

Try this.

function CloneStyle(sourceID, targetID){
    var myStyle;
    var source = document.getElementById(sourceID);
    var target = document.getElementById(targetID);
    if (window.getComputedStyle) {
        myStyle = window.getComputedStyle(source).cssText;
    }
    else if (source.currentStyle) {
        myStyle = $.extend(true, {}, source.currentStyle);
    } else {
        throw "antique browser!";
    }
    target.style.cssText = myStyle;
}

Now call like.

CloneStyle("blah", "me");
$('#me').css({ background: 'blue' });

Fiddle here: http://jsfiddle.net/naveen/3FdDp/

naveen
  • 53,448
  • 46
  • 161
  • 251
  • Tried in FF 4.0.1 doesn't seem to extend any properties? – Gary Green Jun 08 '11 at 12:00
  • Would be great if this could work across all the latest browsers. This seems like a really interesting technique! – Gary Green Jun 08 '11 at 13:50
  • 1
    This technique will have the problem Lazarus mentioned on the original question - 'computed style' will be a full list of all the style properties that the source object has, whether they're given by a stylesheet, or the browser's defaults. Using 'extend' to mix the two will over-write any of the target's styles, because extend doesn't know about the specificity of the selectors that applied the rules in the first place. I think a true solution would need to address this, by parsing the CSS source, rather than computed styles of the element. – Ben Hull Jun 08 '11 at 22:12
0

If you were to use CSS classes rather than ID references you could do the following:

$("#me").addClass($("#blah").attr("class"));

Which would copy the classes from #blah to #me

Lazarus
  • 41,906
  • 4
  • 43
  • 54