117

For example if I have the following HTML:

<div class="someDiv"></div>

and this CSS:

.opacity {
    filter:alpha(opacity=60);
    -moz-opacity:0.6;
    -khtml-opacity: 0.6;
    opacity: 0.6; 
}
.radius {
    border-top-left-radius: 15px;
    border-top-right-radius: 5px;
    -moz-border-radius-topleft: 10px;
    -moz-border-radius-topright: 10px;    
}

.someDiv {
    background: #000; height: 50px; width: 200px;

/*** How can I reference the opacity and radius classes here
     so this div has those generic rules applied to it as well ***/

}

Like how in scripting languages you have generic functions that are used often written at the top of the script and every time you need to use that function you simply call the function instead of repeating all the code every time.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Jake
  • 1,205
  • 2
  • 8
  • 4
  • Is it not possible to change the HTML? – BoltClock Oct 30 '10 at 19:55
  • 1
    You can just add a comma-separated list of classes in `.radius`, like `.radius, .another, .element{/* css*/}`. That will save you extra code, but makes it possibly less readable. – Lekensteyn Oct 30 '10 at 19:56
  • 2
    Possible duplicate of [Can a CSS class inherit one or more other classes?](https://stackoverflow.com/questions/1065435/can-a-css-class-inherit-one-or-more-other-classes) – Organic Advocate Sep 21 '17 at 21:46
  • Perhaps when asked (2010) wasn't yet fully operational, but nowadays we can use the `SASS` (**S**yntactically **A**wesome **S**tyle**S**heets). Example down below, – SNR Aug 23 '21 at 15:25

6 Answers6

92

No, you cannot reference one rule-set from another.

You can, however, reuse selectors on multiple rule-sets within a stylesheet and use multiple selectors on a single rule-set (by separating them with a comma).

.opacity, .someDiv {
    filter:alpha(opacity=60);
    -moz-opacity:0.6;
    -khtml-opacity: 0.6;
    opacity: 0.6; 
}
.radius, .someDiv {
    border-top-left-radius: 15px;
    border-top-right-radius: 5px;
    -moz-border-radius-topleft: 10px;
    -moz-border-radius-topright: 10px;    
}

You can also apply multiple classes to a single HTML element (the class attribute takes a space separated list).

<div class="opacity radius">

Either of those approaches should solve your problem.

It would probably help if you used class names that described why an element should be styled instead of how it should be styled. Leave the how in the stylesheet.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    I don't disagree but I need to comment, that it doesn't let me copy rules e.g. `fieldset legend` to `label.legend`. I understand but regret. – Jacek Krysztofik Feb 03 '17 at 16:52
  • 1
    @rishta — Err… I said that in the first paragraph of this answer. – Quentin Feb 04 '17 at 00:50
  • You can also declare a rule-set for elements that have two classes only like so : `.someDiv.other{/*style...*/}` this way, only the elements that have both classes are affected – Sirmyself Feb 02 '18 at 21:25
18

You can't unless you're using some kind of extended CSS such as SASS. However it is very reasonable to apply those two extra classes to .someDiv.

If .someDiv is unique I would also choose to give it an id and referencing it in css using the id.

ase
  • 13,231
  • 4
  • 34
  • 46
16

You can easily do so with SASS pre-processor by using @extend.

someDiv {
    @extend .opacity;
    @extend .radius;
}

Ohterwise, you could use JavaScript (jQuery) as well:

$('someDiv').addClass('opacity radius')

The easiest is of course to add multiple classes right in the HTML

<div class="opacity radius">
Robert Wolf
  • 1,312
  • 13
  • 18
10

If you're willing and able to employ a little jquery, you can simply do this:

$('.someDiv').css([".radius", ".opacity"]);

If you have a javascript that already processes the page or you can enclose it somewhere in <script> tags. If so, wrap the above in the document ready function:

$(document).ready( function() {
  $('.someDiv').css([".radius", ".opacity"]);
}

I recently came across this while updating a wordpress plugin. The them has been changed which used a lot of "!important" directives across the css. I had to use jquery to force my styles because of the genius decision to declare !important on several tags.

eggmatters
  • 1,130
  • 12
  • 28
3

Just add the classes to your html

<div class="someDiv radius opacity"></div>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
punkrockbuddyholly
  • 9,675
  • 7
  • 36
  • 69
3

I had this problem yesterday. @Quentin's answer is ok:

No, you cannot reference one rule-set from another.

but I made a javascript function to simulate inheritance in css (like .Net):

    var inherit_array;
    var inherit;
    inherit_array = [];
    Array.from(document.styleSheets).forEach(function (styleSheet_i, index) {
        Array.from(styleSheet_i.cssRules).forEach(function (cssRule_i, index) {
            if (cssRule_i.style != null) {
                inherit = cssRule_i.style.getPropertyValue("--inherits").trim();
            } else {
                inherit = "";
            }
            if (inherit != "") {
                inherit_array.push({ selector: cssRule_i.selectorText, inherit: inherit });
            }
        });
    });
    Array.from(document.styleSheets).forEach(function (styleSheet_i, index) {
        Array.from(styleSheet_i.cssRules).forEach(function (cssRule_i, index) {
            if (cssRule_i.selectorText != null) {
                inherit_array.forEach(function (inherit_i, index) {
                    if (cssRule_i.selectorText.split(", ").includesMember(inherit_i.inherit.split(", ")) == true) {
                        cssRule_i.selectorText = cssRule_i.selectorText + ", " + inherit_i.selector;
                    }
                });
            }
        });
    });

Array.prototype.includesMember = function (arr2) {
    var arr1;
    var includes;
    arr1 = this;
    includes = false;
    arr1.forEach(function (arr1_i, index) {
        if (arr2.includes(arr1_i) == true) {
            includes = true;
        }
    });
    return includes;
}

and equivalent css:

.test {
    background-color: yellow;
}

.productBox, .imageBox {
    --inherits: .test;
    display: inline-block;
}

and equivalent HTML :

<div class="imageBox"></div>

I tested it and worked for me, even if rules are in different css files.

Update: I found a bug in hierarchichal inheritance in this solution, and am solving the bug very soon .