How to make an addon to an existing style

edited January 2008 in Style Development
I've noticed quite a few styles that are basically duplicates of one style with minor changes to them, like changing colors or the font. Instead of making a copy of the style and modifying it, you can make an addon style by taking advantage of CSS specificity. What this means is that for all selectors that you want to modify, you simply make the selector more specific. For example:

Let's say the style you're modifying looks like this:
@-moz-document domain(example.com) { body { background-color: #000 !important; color: #fff !important; } .message { color: red !important; font-style: italic !important; } .anotherMessage { color: #6699cc !important; } // tons more code after this }
Now, for an addon style, let's say the only thing we want to do is modify the message class. We want to change it from red text to yellow. Here's what my new addon style will look like:
@-moz-document domain(example.com) { body .message { color: yellow !important; } }
What I did was prefix "body " to the original selector. By doing this, you're being more specific about things, and the result is that you override the original selector. Notice though, in the addon style we only told it to override the color, but if you look at the original style, it specifies that the font-style is italic. When the original style and the addon style are both enabled, the text will be yellow AND it will still be italic. With that said, we can just as easily add to it; for example, you can change it normal yellow text using the Verdana font:
@-moz-document domain(example.com) { body .message { color: yellow !important; font-style: normal !important; font-family: Verdana, sans-serif !important } }
So, for pretty much every selector that you want to override, you can just prefix it with "body " (that's the word "body" followed by a space character). This isn't the only way to increase specificity, but I would say it's the easiest way, especially if you don't care to look at the original HTML code.

Hmm, but what if you want to modify the body element? We can't use "body body", 'cause the body element will never be a descendant of another body element. Instead, we'll prefix it with "html " since body is always a descendant of the html element:
html body { background-color: #ccc !important; }
And what about overriding the html element? Well, I'm not certain of this, but I've been told that "html:root" works, and with a few quick tests of my own, I can confirm that it does.

Just for fun, here are a few more ways to increase specificity. Basically each line adds more to the specificity:

.message
div.message // assuming the original html code was <div class="message">
body .message // same as what I talked about above
body div.message
html body .message
html body div.message

All of these select the exact same thing, but each one is being more specific about things.

I guess that's it. I hope all this helps to prevent people from unnecessarily duplicating styles with minor changes. Feel free to ask questions or make correction if what I say is wrong (I don't claim to be a CSS guru). Thanks for reading.

Comments

  • edited January 2008
    "html:root" seems to work. "* html" won't work, because :root does.

    It's also important to know that while you're writing such a style, to overlay another one, with the original style loaded (obviously!), stylish's load order can lie to you about wether or not you've actually gotten the selector specificity right. Stylish.rdf reads from top to bottom, so new styles have natural priority over older ones.

    Can we add this to the tutorial?
  • Posted By: whatrevolution"html:root" seems to work. "* html" won't work, because :root does.
    Thanks. I've tested it now, and you're right about html:root working. Tutorial updated.
    It's also important to know that while you're writing such a style, to overlay another one, with the original style loaded (obviously!), stylish's load order can lie to you about wether or not you've actually gotten the selector specificity right. Stylish.rdf reads from top to bottom, so new styles have natural priority over older ones.
    That's a good point. Sometimes it may seem that you don't need to increase specificity, but of course it's best to do it anyway. If for some reason Stylish changed the way it loads in each style, the one that increased specificity would still work.
    Can we add this to the tutorial?
    It seems ChoGGi has already added it, but I certainly don't mind :)
  • yea sorry for not asking first, figured you wouldn't mind me linking to it
  • edited January 2008
    Thanks, Vc.
  • But what if I want to make an addon which should come before the existing style.
    Example:

    existing style:
    .nav a { background-image(example1.jpg) !important; } .nav .red { background-image(example2.jpg) !important; }

    addon style:
    .nav * { background-image(example3.jpg) !important; }

    The addon style would just overwrite all of the above, I just want the addon style to come before the existing style.
    How would I go about doing that?
  • edited January 2008
    Without knowing what site you're styling, I have to assume that .red is an <a> class.

    addon style:
    .nav a[class]:not(.red) { background-image(example3.jpg) !important; }

    If my assumption is correct, that will avoid unclassed <a>, and <a class="red">, otherwise, you'll need to use some other property of the anchor, or the anchors' parents.
  • * isn't worth anything for specificity, so both .nav a and .nav .red beat .nav *.
  • edited January 2008
    Well the main point of my tutorial was that you could just prefix "body " to anything you want to override...so just do:

    body .nav a {...}
    body .nav red {...}

    .nav * would select any element that's nested inside another element with the "nav" class, so that's probably not what you want to do.
  • Happy New Year! Sorry to add to an old thread but this one seemed so relevant and I couldn't find any others that were.

    Really good tutorial Valacar!

    I have no problem using specificity (although for this addon purpose I'd rather not) but I think there are a lot of users that can do simple editing but wouldn't want to deal with modifying all the selectors as well as the rules. In order to create a style with no options (to allow auto-update) but allow user customization, I would like them to just be able to copy some of my code into an addon and modify a rule(s) and have it work.

    If the load order can be set to load theirs after mine, specificity wouldn't be an issue, right? I'm wondering if there is a way to set the load order (not in 2008, I know, but now in 2012...)
Sign In or Register to comment.