2

Is there any way to reference another class in an external style sheet? Take my code as an example. Say I want to turn the button red when it's hovered over; I'm aware that I could just use background:#fff, but is there a way I could use another class as the style for this selector? (No javascript, just css and/or html)

.red {
    background: #f00;
}
button {
    background: #000;
}
button:hover {
    /* Reference another class */
    .red; ???
}

EDIT: I want the button to inherit the style(s) of the red class when it is hovered over.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Rice_Crisp
  • 1,242
  • 1
  • 16
  • 33
  • 1
    No, but there are countless ways to achieve the same result. You might also be interested in a preprocessor like LESS/SASS. – Wesley Murch May 16 '14 at 20:48
  • See this post: http://stackoverflow.com/questions/10483323/use-hover-to-modify-the-css-of-another-class – The One and Only ChemistryBlob May 16 '14 at 20:49
  • 1
    Take a look at a CSS pre-processor like LESS: http://lesscss.org/ – Brandon May 16 '14 at 20:49
  • I am not sure if I understand your question, but may try this instead `.red:hover { background: #whatever; }` – Javad May 16 '14 at 20:51
  • Yes, I found this question hard to word. Perhaps that is why it was hard for me to search for an answer. – Rice_Crisp May 16 '14 at 21:15
  • This is asked semi-frequently, but it is really hard to search for. There has got to be a way to express this in a way that is searchable, but I'm not sure how. – BoltClock May 17 '14 at 16:30
  • That being said, the short answer is that this isn't possible with CSS except by manually copying the `button:hover` selector to the ruleset(s) headered by the `.red` selector. – BoltClock May 17 '14 at 17:06
  • Here are two good questions I've found so far: [Can a CSS selector "inherit" all declarations from another selector?](http://stackoverflow.com/questions/22704030/can-a-css-selector-inherit-all-declarations-from-another-selector); [Is it possible to reference one CSS selector or ruleset within another?](http://stackoverflow.com/questions/4060405/is-it-possible-to-reference-one-css-class-within-another) The second link appears to be a highly suitable duplicate, so I'll mark your question accordingly. – BoltClock May 17 '14 at 17:27
  • @Rice_Crisp I've changed my answer so that it actually answers the question originally asked. – Joeytje50 May 17 '14 at 18:05
  • @BoltClock I think this question is actually different from the question you marked this one as a duplicate of, because that question's accepted answer only suggests changing the original stylesheet (so in this case, changing the `.red` selector to `.red, button:hover`), but in this question, OP probably can't edit the CSS since it's an external stylesheet, which would make the answers to that question invalid here. I'm not sure if it's worth reopening, but I don't think it's a duplicate of it either. PS: I've updated my answer to fit this question. – Joeytje50 May 17 '14 at 18:08
  • @Joeytje50: It does start by saying "No, you cannot reference one rule-set from another." - which answers the core question. – BoltClock May 17 '14 at 18:23

2 Answers2

2

This is currently not possible without any preprocessors such as Less. There is however a quite new proposal to implement CSS variables some time in the far future. For now though, this is not possible using plain CSS. There are 2 things you can do now:

1. Use a preprocessor

You could use a preprocessor, such as LESS or SCSS. In the case of LESS, you would need to use mixins, and in SCSS you would need to extend the existing class. There are more CSS preprocessors, but these are the most popular ones.

The syntax you're using would be the exact same syntax as the syntax required in Less.

SCSS demo, LESS demo

2. Use JavaScript

If you're running your site on a server you can't easily access yourself, or if you have any other reason not to be able to install such preprocessors, you could use JavaScript as an alternative. You would have to run a script that scans all of the class's applied styles. This would work (based on this SO answer), but do watch out with cross-domain rules.

function applyRules(from, to) {
    var sheets = document.styleSheets;
    var re = new RegExp('(^|,)\\s*'+from+'\\s*(,|$)');
    var rules, curr;
    var styles = '';
    for (var i=0;i<sheets.length;i++) {
        rules = sheets[i].rules || sheets[i].cssRules;
        for (var j=0;j<rules.length;j++) {
            if (re.test(rules[j].selectorText)) {
                curr = rules[j].cssText || rules[j].style.cssText;
                styles += ';' + curr.substring(curr.indexOf('{')+1, curr.indexOf('}'));
            }
        }
    }
    var sheet = document.createElement('style');
    sheet.type = 'text/css';
    sheet.innerHTML = to + '{' + styles + '}';
    document.head.appendChild(sheet);
    return sheet;
}
applyRules('.red', 'button:hover');

Demo.

That will search through all accessible stylesheets for a style that selects for .red, and apply those styles to button:hover.

Community
  • 1
  • 1
Joeytje50
  • 18,636
  • 15
  • 63
  • 95
  • 1
    This has nothing to do with a parent selector, unless you are confusing the meaning of the term as it is used in that question, with the term as it is used in the documentation of some preprocessor languages. – BoltClock May 17 '14 at 02:19
  • @BoltClock the question involves traversing up the DOM tree using CSS selectors. – Joeytje50 May 17 '14 at 09:59
  • No, it doesn't. It involves applying styles in one rule to another. – BoltClock May 17 '14 at 16:31
  • I just noticed that you edited the question. You have completely misinterpreted the question; the subsequent edit from the asker confirms this. Your answer would be applicable had the question actually been one of DOM traversal or modifying other elements based on the state of another, but it wasn't. – BoltClock May 17 '14 at 16:52
  • @BoltClock I'm sorry. The edit by OP did indeed make it clear, but what I edited was what I (at the time) was sure OP meant. I'm sorry for the mess I've made. Is there anything I should do to fix it? – Joeytje50 May 17 '14 at 17:02
  • No problem. I see you've retracted your duplicate vote - that's a good first step to take. I've made the necessary edits on the original question. You can either rewrite this answer to match the question, or remove it - that is up to you, but it might not be wise to leave it as it is or you may risk getting downvoted. (I did not vote, because I understand that it might have been a mistake and did not want to penalize you unnecessarily for it.) – BoltClock May 17 '14 at 17:05
0

pure CSS can't do something like that.

Check http://lesscss.org/: With LESS you can do it like

.red {
    background: #f00;
}
button {
    background: #000;
}
button:hover {
    .red;
}

or

@red = #f00; /* In LESS you can define variables with @ */
button {
    background: #000;
    &:hover { /* the &:hover means the :hover event of the parent (which is button). In this case that means button:hover */
        background: @red; /* get the varriable @red */
    }
}
Jere
  • 1,196
  • 1
  • 9
  • 31