What is the most character-efficient way to increase CSS specificity?
Asked Answered
M

4

27

If I want to increase the CSS specificity of a rule, I tend to prefix with html, but I wonder if there are more concise ways of doing this?

(It may seem like a trivial issue, but over the course of my stylesheets defining a responsive grid, decreasing the specificity prefix by a single character would save a few hundred bytes)

Machinate answered 16/10, 2013 at 9:23 Comment(4)
Why do you bother with html ? Are the styles being overwritten? Why not just include that stylesheet after the others if they're using the same selectorTaken
Define 'character efficient'. And then tell us why it's important.Reseau
@EJP by character efficient I mean using as few characters as possible, and I already explained what the benefit isMachinate
@SmokeyPHP Good call - I realised shortly after posting that 2 stylesheets were in a silly order and it now works without having to worry about specicifity. Although I'm still interested to know if html can be improved uponMachinate
I
42

This really depends on what you're trying to achieve. A cheap way of increasing specificity is to simply repeat a selector. For instance, if this was your markup:

<figure id="myId" class="myClass"></figure>

And this was your CSS:

#myId.myClass { color:red; font-weight:bold; }      /* Specificity: 110 */

You could simply repeat the class or id selector without modifying your markup at all:

#myId.myClass.myClass { color:green; }              /* Specificity: 120 */
#myId#myId { font-weight:normal; }                  /* Specificity: 200 */

JSFiddle demo.

This is completely valid, as the W3C Selectors Level 3 Recommendation states in its Calculating Specificity section:

Note: Repeated occurrances of the same simple selector are allowed and do increase specificity.

Incision answered 16/10, 2013 at 9:35 Comment(6)
+1 - would lead to a greater file size than prefixing with html in most cases, but a neat little trick all the sameMachinate
Not sure how that link is relevant in any way. There's only one selector per rule here, so there's nothing to read from right to left. Besides, if you're going to link to another Stack Overflow answer, just link directly to the answer.Rosauraroscius
I had found this link from research without referring to any SO answers. I would have surely linked the answer if I would have founded one.Justis
@Nathan Lee: I'm saying that that article itself links to SO anyway, so instead of linking to the article, you could have linked to the answer which that article links to, saving everyone a pointless extra click.Rosauraroscius
Yes @BoltClock. Infact I was reading the same in SO, but went back to see if they had any other info and went on linking it from where I got the link. Shall link directly to SO if any such similar situations are encountered the next time. Thnx. for the mention.Justis
Right ... that's a revelation! I'd never have thought about that ...Saylor
F
14

I've seen a postcss library use :not(#\9) which is pretty short, increases specificity by one, and basically works on everything. Doesn't work with ie8 or less, but come on this is 2020

Edit: I realized that this increases specificity by one ID which is an important distiction :not(.\9) would increase it by one class, which might be what you want most of the time.

Finding answered 13/5, 2020 at 18:7 Comment(5)
Thank you! This is a great answer because it requires no extra setup. +1!Mcwhorter
What does \9 mean?Alejandro
No idea 😅 ASCII 9?Finding
it is in fact ascii nine which is a <tab>, so this whole selector is "any element whose id is not the tab character"Finding
noticed that this increases specificity by one ID, the actual way specificity works is rule with most id specifiers, then most class specifiers break ties, then most element specifiers break tiesFinding
J
8

Least Bytes, but How Much More Specific?

It seems to me for selectors, in most cases you cannot get any shorter than two characters plus the space, especially if we are talking about a "global" use of adding specificity (which seems to be the case since you were using html). So to save on CSS, you need a single character id on the html. I would say an id (and not a class), as you would want to keep it unique. So you implement like so in the html:

<html id="A">

Which then allows for the shortest possible selector addition in the CSS of:

#A .whateverYour [OriginalSelector] string .was {}

Then using what James Donnelly stated (which, by the way, I never knew about the repetition of the same selector), you could continually add more and more specificity with the least amount of characters like so:

#A#A#A .whateverYour [OriginalSelector] string .was {}

Disclaimer

By answering as I have, I am not recommending this is necessarily a good way to do CSS, nor a good way to handle specificity issues. But I do believe that adding the short one character id to the html element is the least amount of bytes one could use to increase specificity of any selector, which answers the question here.

Jessejessee answered 16/10, 2013 at 15:13 Comment(5)
+1 Good answer, but this also made me realise that the question I really wanted answering was how to increase specicifity by a small amount. Using a class instead of an id would help (but would also be more vulnerable to the class being used elsewhere). Even though this does answer the original question I'm not going to mark this as the answer purely because, as you say, it's a bad idea to actually use and I wouldn't want to promote it at all.Machinate
@wheresrhys: Perhaps you should change your question then. Also, I'm a bit confused by not wanting to mark it as the answer because "it's a bad idea to actually use and I wouldn't want to promote it at all," when my answer is the exact same thing (beside specificity difference) you were already doing using the html addition, only with two less characters (which was your original question to solve). So it seems odd to not want to promote that which you are already doing, for a question you asked on how to do it.Jessejessee
Put simply, if it's got a green tick next to it people might not read all the caveats and just go ahead and use what, as you say yourself, isn't something you'd recommend.Machinate
@wheresrhys: I understand that. So then that makes me wonder, should you just delete the whole question, since the whole premise is wrong?Jessejessee
I think no because it's a valid question to find out if increasing specicifity more efficiently can be done and both your answer and the other one could have valid use cases. Also a few people starred the question, so I'll defer to the crowdMachinate
L
6

I realize I am late to the conversation, but using an indeed non-existent ID selector, such as "#dummy", is by far the most efficient way to increase CSS specificity and the :not and :is pseudo-classes should be used.

This method can be utilized even if no ID or class is not present in the HTML!

This is a perfectly valid way to greatly increase specificity, for example:

ul li:not(#dummy)

On the other hand, an example with little less specificity would be:

ul :is(li)

These two examples both have greater specificity than a standard ul li selector.

To experiment with different selectors and their specificities, you can use a specificity calculator such as the one found at: Specificity Calculator


I'm not sure that most readers have understood how flexible :not(X) is in terms of adjusting specificity. I encourage you to experiment with the specificity calculator. What can be achieved is a fine tuning of the specificity value. Exact specificity can easily be adjusted at will.

For example, ul li:not(#i#i#i#i.c.c.c) has a weight of 4 x ID and 3 x class. If you need it with 3 x ID, you can use ul li:not(#i#i#i), or for a slight boost, you can use ul li:not(.c.c), which increases it by 2 x class.

Moreover, all this can be done without touching HTML classes or IDs in any way, which is the main idea behind this method.

Lydalyddite answered 17/1, 2023 at 16:57 Comment(1)
Late indeed, but great answer, it should get more votes.Pelasgian

© 2022 - 2024 — McMap. All rights reserved.