Why Is the # Selector of Lesser Specificity Than Anything

In CSS what is the difference between . and # when declaring a set of styles?

Yes, they are different...

# is an id selector, used to target a single specific element with a unique id, but . is a class selector used to target multiple elements with a particular class. To put it another way:

  • #foo {} will style the single element declared with an attribute id="foo"
  • .foo {} will style all elements with an attribute class="foo" (you can have multiple classes assigned to an element too, just separate them with spaces, e.g. class="foo bar")

Typical uses

Generally speaking, you use # for styling something you know is only going to appear once, for example, things like high level layout divs such sidebars, banner areas etc.

Classes are used where the style is repeated, e.g. say you head a special form of header for error messages, you could create a style h1.error {} which would only apply to <h1 class="error">

Specificity

Another aspect where selectors differ is in their specificity - an id selector is deemed to be more specific than class selector. This means that where styles conflict on an element, the ones defined with the more specific selector will override less specific selectors. For example, given <div id="sidebar" class="box"> any rules for #sidebar with override conflicting rules for .box

Learn more about CSS selectors

See Selectutorial for more great primers on CSS selectors - they are incredibly powerful, and if your conception is simply that "# is used for DIVs" you'd do well to read up on exactly how to use CSS more effectively.

EDIT: Looks like Selectutorial might have gone to the big website in the sky, so try this archive link instead.

CSS: Styling IDs not having any effect

You can start ID selectors with a number(To Elaborate more look at Xec's answer), but within CSS its not good practice, it needs to be escaped or begin with a letter. I recommend you change it with a name like id="img2" in the HTML. and also use #img2 in css

Is there a reason to use a instead of a:link or a:visited in my stylesheet?

This is of course assuming there would never be a reason to use an <a> tag without an href value. Maybe that's a mistaken assumption.

It depends on your project. Strictly speaking, that is a mistaken assumption, as not every <a> element needs to have a href attribute. Indeed, it's still not required in HTML5 to specify href for every <a>. Chris Blake and Ryan P mention named anchors, and I'll add that while the name attribute for <a> has been made obsolete as of HTML5, named anchors are still rife and will continue to be, simply by legacy and tradition.

That said, going forward, authors are recommended to use id attributes and not named anchors to designate document anchor fragments.

Also, <a> elements that lack href attributes but have onclick attributes for JavaScript are a mess. Even if you insist on using onclick to bind events, for the sake of graceful degradation you should at least point it somewhere using href.

But to make things simple, let's assume that you won't be writing <a> elements without href attributes.

With this in mind, going back to the CSS selectors, there are two important points to consider:

Are they the same?

No, the selectors a and a:link, a:visited are not strictly equivalent. I'll quote a previous answer of mine on this topic:

The selector a should match any <a> elements, while a:link only matches <a> elements that are unvisited hyperlinks (the HTML 4 document type defines hyperlinks as <a> elements with a href attribute). Nowhere does it state in either specification that a should automatically translate to a:link or vice versa.

In other words, in HTML, a:link, a:visited (in CSS1) is strictly equivalent to a[href] (in CSS2 with an attribute selector) or a:any-link (new in Selectors level 4), rather than a. Note that it doesn't matter whether the attribute has a value or not, as long as it is present the pseudo-classes will match, hence [href]. Note also that this is true for all current standards of HTML, and I believe this includes HTML5, since as mentioned above href is not a required attribute in any existing spec.

Just bear in mind, that other languages may define completely different semantics for :link and :visited — it just so happens that they coincide with an equally specific selector in HTML, which is covered next...

Specificity

This is a huge gotcha: a is less specific than either a:link or a:visited, which is a very common source of specificity problems that are particularly evident when applying styles to a, a:link and a:visited separately. This then leads to all kinds of !important hacks to get around a lack of understanding of specificity.

For example, consider this CSS:

/* All unvisited links should be red */
a:link {
color: red;
}

/* All visited links should be slightly darker */
a:visited {
color: maroon;
}

/* But no matter what, header links must be white at all times! */
body > header > a {
color: white;
}

This doesn't work as expected, because a:link and a:visited (what I call generalized rules/selectors) are more specific than body > header > a (what I call a specialized rule/selector), so header links will in fact never be white:

/* 1 pseudo-class, 1 type  -> specificity = (0,1,1) */
a:link, a:visited

/* 3 types -> specificity = (0,0,3) */
body > header > a

Now the first thing that comes to mind for most CSS coders is to throw in !important, trumping specificity altogether:

body > header > a {
color: white !important;
}

But that gets you all kinds of bad rep, right? So let's not do that.

Selectors level 4 gives you not one, but two solutions to this specificity problem. These solutions, new as they are, aren't supported in Internet Explorer and Microsoft Edge Legacy (the UWP/EdgeHTML/not-Chromium one), but thankfully there is a third solution that works in Internet Explorer 7 and later, which is a[href], the attribute selector I mentioned above.

1. The :any-link pseudo-class

:any-link has some history behind it which you can read in my answer to this question, but practically speaking, :any-link serves as a catch-all for :link, :visited. Its main purpose is to eliminate selector duplication, and for that reason there is in fact an equivalent in the form of :is(:link, :visited).

You can use a:any-link in your specialized rule to match the specificity of the generalized a:link and a:visited rules, thereby allowing it to override them:

a:link {
color: red;
}

a:visited {
color: maroon;
}

/* 1 pseudo-class, 3 types -> specificity = (0,1,3) */
body > header > a:any-link {
color: white;
}

2. The :where() pseudo-class

:where() also has some history behind it, but essentially it's an analogue to :is() with the exception that it zeroes out the specificity of its argument. See my answer to this question for an in-depth guide to how it works.

You can wrap the :link and :visited pseudo-classes in :where()s to remove their pseudo-class specificity, thereby allowing them to be overridden by the specialized rule:

/* 1 type                  -> specificity = (0,0,1) */
a:where(:link) {
color: red;
}

/* 1 type -> specificity = (0,0,1) */
a:where(:visited) {
color: maroon;
}

/* 3 types -> specificity = (0,0,3) */
body > header > a {
color: white;
}

3. a[href] (for older browsers)

Fortunately, if you need to support older browsers, an attribute selector is as specific as a pseudo-class. This means you can use a[href] to mean both/either a:link and/or a:visited, and not run into specificity issues because they are equally specific!

/* 1 attribute, 3 types    -> specificity = (0,1,3) */
body > header > a[href] {
color: white;
}

So which selector(s) to use?

This is all still incredibly subjective, but I follow these personal rules of thumb:

  • Apply to a styles that do not depend on the state of a link (i.e. as long as it's a link will do).

  • Apply to a:link and a:visited styles where it does matter whether a link is visited or not.

  • Taking into account the specificity problems mentioned above, do not mix any declarations between both a and a:link/a:visited rules. If I need to apply the same property to both states somewhere, but I already have it in separate a:link and a:visited rules, I'll use one of the 3 options above to avoid specificity problems.

For example, here are the link styles I used in my site's Coming Soon page prior to its launch:

a {
text-decoration: none;
transition: text-shadow 0.15s linear;
}

a:link {
color: rgb(119, 255, 221);
}

a:visited {
color: rgb(68, 204, 170);
}

a:hover, a:active {
text-shadow: 0 0 0.5em currentColor;
}

a:focus {
outline: thin dotted;
}

/* ... */

footer a:link, footer a:visited {
color: rgb(71, 173, 153);
}

The text-shadow transition is defined for all a elements, regardless of whether they are visited or not, because the transition only takes effect when one of them is moused over and clicked (corresponding to the a:hover, a:active rule).

Now, I want visited links to have a slightly darker shade than unvisited links, so I put the colors in separate a:link and a:visited rules. However, for some reason, I want footer links to appear the same color whether they're visited or not.

If I use footer a, I'll run into the specificity problems described above, so I choose footer a:link, footer a:visited instead. This was for legacy reasons (as you'll see below, I originally posted this in 2012!), but of course it can be shortened to footer a:any-link. However, the specificity-matching principle applies all the same.

Hopefully my advice helps you get a handle on the mess that is link styles.

CSS attribute-value selector doesn't work if value contains hash # sign

Use quotes:

div[data-demo='#does_work'] {
color: green;
}

DEMO

Why it has to be quoted? Because # has special meaning in CSS. Quoting it hides that special meaning. The same effect could be approached using ": [data-demo="#does_work"] or by escaping # with \: [data-demo=\#does_work]

Is there any pros and cons if i use always CSS Class instead CSS ID for everything?

One big difference: in CSS, a class has a lower importance level than an ID.

Imagine that each specification in a CSS declaration added a certain number of points to that declaration's value. Let's say the points go something like this (totally made up, but whatever):

  • Tag name ('a', 'div', 'span'): 1 point
  • Class name ('.highlight', '.error', '.animal'): 10 points
  • ID ('#main-headline', '#nav', '#content'): 100 points

So, the following declarations:

a {
color: #00f;
}

.highlight a {
color: #0f0;
}

#nav .highlight a {
color: #f00;
}

are worth 1, 11, and 111 points (respectively). For a given tag, the declaration with the highest number of points that matches it "wins". So for example, with those declarations, all a tags will be blue, unless they're inside an element with the "highlight" class, in which case they'll be green, unless that element is inside the element with id="nav", in which case they'll be red.

Now, you can get yourself into tricky situations if you're only using classes. Let's say you want to make all the links in your content area blue, but all the links in your foo area red:

.content a {
color: #00f;
}

.foo a {
color: #f00;
}

By my previous (made up) scale, those both have 11 points. If you have a foo within your content, which one wins? In this situation, foo wins because it comes after. Now, maybe that's what you want, but that's just lucky. If you change your mind later, and want content to win, you have to change their order, and depending on the order of declarations in a CSS file is A Bad Idea. Now if, instead, you had the following declaration:

#content a {
color: #00f;
}

.foo a {
color: #f00;
}

Content would always win, because that declaration has a value of 101 (beating foo's 11). No matter what order they come in, the content declaration will always beat the foo one. This provides you with some very important consistency. The winners won't arbitrarily change based on changing orders in the file, and if you want to change the the winner, you have to change the declarations (maybe add a #content in front of the .foo declaration, so it will have 111 points).

So basically, the differences in values are important, and you get a lot of inconsistency and seemingly arbitrary winners if you just use classes.

HTML DOMs, ids vs no ids?

At the very most, I'm guessing that the basic few things a browser would do is assign the ID as a property to each element when building the DOM structure, as well as store the IDs in a hash table to facilitate things like #id selectors, document.getElementById() and idref lookups later. I don't think this is going to cause even a slight dent in observed performance or memory usage, as hash tables and the DOM are designed to be very well-optimized.

That said, if IDs aren't needed on your elements at all, then there quite simply is no point in assigning them IDs; you're going to end up with a whole lot of markup bloat instead. As Dan Davies Brackett mentions, that will obviously cause a slowdown since it depends on the client connection.

If you can afford to reference these elements using CSS selectors, you can always use :nth-child() to look up specific children. If you need to support older browsers, there's always a CSS2 solution. See these questions:

  • How can I get the second child using CSS?
  • How do I get the nth child of an element using CSS2 selectors?

CSS Selector Strategy: (Prefix using a parent class: .widget .widget-item {}) or (Directly: .widget-item {})

Check out this post on Decoupling HTML from CSS. I avoid deep-chaining as often as I can, because it makes your styles really brittle. From a maintenance aspect, simple .widget class selectors are easier to fix and change down the road.

Performance-wise, I think @ Toni Michel Caubet is right. Shorter selector chains are less work for the browser.

Selectors in CSS & jQuery: just the class/id, or the tag as well?

With the tag included

$("div.foo") or div.foo{}

you are giving the browser a hand, telling it not to search every element with a certain class or ID. Instead, in the examples above, it would just search divs.

Although the performance may be negligible on a single element or a small page, it could add up if you are talking about a document with thousands of tags and several different css or jQuery calls.

Distinguishing between two elements

In some cases you may need it, too, to distinguish between two elements with the same class.

For Specificity

Plus, I think that you should include the elements when possible, as a way to make your CSS (and jQuery) as specific as possible... keeping the surprises to a minimum!

Better for shared code/troubleshooting/updating

It is also much easier to find/change/edit rules when the element is included in the rule.

EDIT

To respond to @stefmikhail's comment about @YoTsumi's benchmark test, here is the difference:

Searching for a unique ID will always be the fastest thing, as there should only be one ID on a page and the engine needs to look for it and it alone. However, as @BoltClock mentioned, there is more to this question than performance.

How do I select an element based on the state of another element in the page with CSS?

The general answer to the canonical question

How do I select an element based on the state of another element in the page with CSS?

is that it depends on exactly three conditions:

  1. whether the state of these elements can be represented using simple selectors,
  2. whether a structural relationship can be expressed between these two elements using combinators to form a single complex selector, and
  3. whether the element that you want to target can be made the subject of the resulting complex selector.

While the current Selectors standard has some interesting and sometimes potentially powerful features, the way it is designed makes it extremely limited in area #2 (with #3 being a direct consequence). Some of these limited possibilities are enumerated in other answers, e.g. through the most basic use of child and sibling combinators, clever use of dynamic pseudo-classes (which actually relates to condition #1), or a combination of both.

The problem given in the question, on the other hand, cannot be solved using what is currently available in Selectors for this reason. Most of this boils down to the lack of either a parent selector and/or a previous sibling selector, both of which may seem like trivial features, but have certain implications that make them difficult to define or implement well. In summary:

  1. Yes, the state of these elements can be represented using simple selectors: div and [data-status~=finished] for the former, and .blink and .spin for the latter two.

  2. The first element can be represented by section > div[data-status~=finished], and the two subject elements can be represented by section + section > .blink and section + section > .spin respectively. The problem is that it's not possible to write a complex selector incorporating all of these structures, because combinators are one-way, and there is no parent counterpart to the child combinator to join them at the first section element.

  3. Assuming the answer to the first two questions is also "yes", each of .blink and .spin can be made the subject of its own complex selector. (But more on that in the next section.)

If you've been directed to this question, chances are the problem you're trying to solve, like the one given above, cannot be solved with Selectors due to these limitations.

The upcoming standard boasts some new features that will greatly enrich selector syntax and potentially open it (and CSS) up to a host of new possibilities, including a possible solution to the example problem. All of these things will be covered in the following sections, but first I'll explain what each condition means and how it relates to the given example:

Element states, and structural relationships between elements

The defining characteristic of a selector is that it represents a certain structure of one or more elements in the document tree. This isn't just something I made up — you can actually find this description in the informative overview of the Selectors standard:

A Selector represents a structure. This structure can be used as a condition (e.g. in a CSS rule) that determines which elements a selector matches in the document tree, or as a flat description of the HTML or XML fragment corresponding to that structure.

Selectors may range from simple element names to rich contextual representations.

Each element is represented by a sequence of one or more simple selectors. This sequence is known as a compound selector (I'm using terminology from Selectors 4 here as it is much clearer than what is used in Selectors 3 — see this answer for a non-exhaustive list of terms).

Each simple selector represents a certain state of an element. There are simple selectors for matching the type (or tag name) of an element, a class name, an ID, or an arbitrary attribute. There are also pseudo-classes, which represent abstractions and other special states not directly represented within the document tree, such as the order and position of an element in its hierarchy (:nth-child(), :nth-of-type()), user interactions (:hover, :active, :focus, :checked), the visitedness of a hyperlink (:link, :visited), and much more.

In the given example, the div element with a data-status attribute whose space-delimited value contains finished can be represented with a type selector and an attribute selector:

div[data-status~=finished]

If you want the selector to apply only when the pointer is over this element, simply throw in a :hover pseudo-class:

div[data-status~=finished]:hover

Compound selectors are linked via combinators to form complex selectors. These combinators, the >, + and ~ symbols that you may be familiar with, express a relationship between the elements represented by each compound selector. With these two tools alone, you're already able to create some very interesting results as shown in the other answers here. I explain these basics in even further depth in this answer.

In the given example, the following structural relationships can be established:

  • The first section element is the parent of div[data-status~=finished]. This is represented using the child combinator >:

    section > div[data-status~=finished]
  • The second section immediately follows the first one as its sibling. This is represented using the adjacent sibling combinator +:

    section + section
  • Additionally, the second section is the parent of both .blink and .spin. This can be represented using two selectors, one for each child:

    section + section > .blink, 
    section + section > .spin

    Why are two selectors required? In this case it's mainly because there is currently no syntax for subgrouping two compound selectors into one, so you will have to represent each child element separately. The upcoming Selectors 4 standard introduces a :matches() pseudo-class that will provide this very subgrouping functionality:

    section + section > :matches(.blink, .spin)

Now, since every compound selector in a complex selector represents one element, and thus section + section represents two elements that are siblings, section > div represents a parent and a child, and section + section > div represents a child of a next-sibling, you would think that a parent combinator and a previous-sibling combinator are quite redundant. So why do we commonly get these questions:

  • Is there a CSS parent selector?
  • Is there a "previous sibling" CSS selector?

And, more importantly, why is the answer to both of these questions no? The reason is addressed in the next point:

Subject of a selector

The subject of a selector is always represented by the rightmost compound selector. For example, the selector section + section > div represents three elements, of which div is the subject. You might say that the div is selected, or targeted, as in the question, but if you've ever wondered if there was a proper term, it's known as the subject of the selector.

In a CSS rule, styles are applied to the element represented by the subject of the selector. Any child boxes and pseudo-element boxes inherit the styles from this element where appropriate. (The exception is if the subject of the selector includes a pseudo-element, in which case the styles are applied directly to the pseudo-element only.)

Taking the selectors from the previous section, we have the following:

  • The subject of section > div[data-status~=finished] is div[data-status~=finished].
  • The subject of section + section is the second section selector.
  • The subjects of section + section > .blink, section + section > .spin are .blink and .spin respectively.
  • Using :matches(), the subject of section + section > :matches(.blink, .spin) is :matches(.blink, .spin).

It might seem therefore that we do need a parent selector or a previous-sibling selector. But remember that selectors can already represent complex structures. Instead of simply adding new combinators that work opposite of existing ones, it makes sense to seek out a more flexible solution, and that is exactly what the CSSWG has been doing.

Which brings us to the following from the original question:

Is there a CSS selector that would let me specify which elements should get selected based on target element state?

The answer to this is no, and will remain no. However, in the earlier drafts of Selectors 4 (from the FPWD up to the latest working draft from May 2013), there was a proposal for a new feature that would let you pick any of the compound selectors other than the rightmost one, and designate that as the subject of the selector.

A potential solution

However, the subject indicator was recently removed in favor of the :has() pseudo-class (that was in turn adopted from jQuery). I speculate on a likely reason here:

The reason :has() is more versatile is because, with the subject selector, it was never made clear in any draft if a single complex selector could have more than one subject selector (since a single complex selector can only ever have one subject) and/or if functional pseudo-classes such as :matches() accepted the subject selector. But because a pseudo-class is a simple selector, you know that :has() can be accepted anywhere a pseudo-class is accepted.

So while you cannot change the subject of a selector, :has() will completely write off the need to do so, due to its pseudo-class nature. And the best part is that it does this — and then some — all without fundamentally changing selector syntax.

In fact, the example problem can be solved using Selectors 4's :has():

/* Combined with the :matches() example from above */
section:has(> div[data-status~=finished]) + section > div:matches(.blink, .spin)

Notice the use of a child combinator: this scopes the relative selector argument to just children of the first section. Yes, this is the elusive "parent selector" that Web developers the world over have been wanting for years.

And since :has() comes from jQuery, you can use it today, although :matches() doesn't exist yet so you'll have to replace that with a call to .filter() in the meantime:

$('section:has(> div[data-status~=finished]) + section > div')    .filter('.blink, .spin')    .css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><section>    <div>Element 1</div>    <div data-status="finished">Element 2</div>    <div>Element 3</div></section><section>    <div>Element 4</div>    <div class="blink">Element 5</div>    <div>Element 4</div>    <div>Element 4</div>    <div class="spin">Element 4</div>    ...</section>


Related Topics



Leave a reply



Submit