Why Selecting by Id Is Not Recommended in CSS

Why selecting by ID is not recommended in CSS?

CSSLint gives a guide to why they make their recommendations:

IDs shouldn't be used in selectors because these rules are too tightly coupled with the HTML and have no possibility of reuse. It's much preferred to use classes in selectors and then apply a class to an element in the page. Additionally, IDs impact your specificity and can lead to specificity wars.

(From Disallow IDs in selectors.)

Basically, if you structure your code to use classes rather than IDs, your code can be more general and reusable, which is generally a good thing. Furthermore, specificity is a hard thing to get your head around, and can cause bugs that are hard to find, so if you omit ID selectors, you're less likely to have conflicting rules resolved in unexpected ways.

Don't use IDs in selectors (CSS) then, what to use instead of IDs?

give them another class for example:

<div class="myClass special"></div>

.myClass.special{
color: red;
}

Is it improper to use an ID as a CSS selector?

Using an ID is the most efficient way of selecting a DOM node in both CSS and Javascript. I personally like to use classes for all repeated items and ids for unique items, or unique configurations of repeated modules. There are many CSS patterns, I use a style called BEM (Block, Element, Modifier as seen here) which is a class based naming convention. Look at your favorite websites, right click or inspect. You will find that there is no one right answer to your question, only many right answers.

May I also say that both exist in the standard for a reason and serve a purpose depending on your applications needs.

Below is the order of efficiency for selectors. IDs are the most efficient and pseudo classes and pseudo elements are the least efficient.

id (#myid)
class (.myclass)
tag (div, h1, p)
adjacent sibling (h1 + p)
child (ul > li)
descendent (li a)
universal (*)
attribute (a[rel=”external”])
pseudo-class and pseudo element (a:hover, li:first)

See here...

Why is #.id a bad selector in CSS/jQuery yet it works in an HTML anchor?

HTML5 permits having a period in an ID attribute value, and browsers have handled this without any issues for decades (which is why the restriction in HTML 4 — itself defined not by HTML but by SGML on which it is based — was relaxed in HTML5, now free from the legacy baggage of SGML). So the problem isn't in the attribute value.

The grammar of a fragment identifier as defined by RFC 3986 is:

fragment    = *( pchar / "/" / "?" )

Where the character set of pchar includes the period. So .someMethodName is a valid fragment identifier, which is why <a href="#.someMethodName"> works.

But #.someMethodName is not a valid selector, and the reason is twofold:

  1. An ID selector consists of a # followed by an ident, and an ident in CSS cannot contain a period.
  2. The period is therefore reserved for a class selector (which similarly consists of a period followed by an ident).

In short, the parser is expecting a CSS ident after the # but not finding one because of the . that directly follows it, making the selector invalid. This is surprising because the notation of an ID selector is in fact based on the URI notation for a fragment identifier — as evident in the fact that both of them start with a # sign, as well as the fact that they are both used to reference an element uniquely identified within the document by that identifier. It's not unreasonable to expect anything that works in a URI fragment to also work in an ID selector — and in most cases it is true. But because CSS has its own grammar which doesn't necessarily correlate with the URI grammar (because they're two completely unrelated standards1), you get edge cases such as this one.

As the period is part of the fragment identifier, you will need to escape it with a backslash in order to use it in an ID selector:

#\.someMethodName

Don't forget that you need to escape the backslash itself within a JavaScript string (e.g. for use with document.querySelector() and jQuery):

document.querySelector('#\\.someMethodName')
$('#\\.someMethodName')

1 Several years ago a W3C Community Group was formed (of which I am a member) around a proposal known as Using CSS Selectors as Fragment Identifiers that, as you can imagine, married the two technologies in an interesting way. This never took off, however, and the only known implementations are some browser extensions that probably aren't even being maintained.

CSS Best Practice about ID and Class?

I guess they always use the id in examples because it's less ambiguous. You know that they're talking specifically about that one element and its styles.

In general, the rule of thumb is that you should ask yourself: "is there more than one element which requires the same style, now or at any time in the future?", and the answer is even "maybe", then make it a class.

CSS Class Selector won't work, but it works when I make it an ID?

It's probably because some other css rule takes priority. This could be due to css specifity or the other rule being defined later in the css (then it takes priority also). If you add !important then it should override the other styles.

.song-selection {
background-color: gray !important;
}

External CSS ID selector not working

The titleImage ID is for the <div> surrounding the image, not the image itself. At the moment, you are trying to find an element with a #titleImage selector inside an image tag.

For the titleLink, the ID is the element, so you can do this instead:

a#titleLink { ... }

However, you'd typically only have one ID on a page, so you could just target the title link by doing this:

#titleLink { ... }

The webpage title should be working as intended. However, I'd still recommend just using the ID. An element with relative positioning doesn't really appear different unless you've given it some style declarations:

#webpageTitle {
position: relative;
top: 10px;
left: 10px;
}

Hope that helps.

Is there CSS style to select an element that has any id?

Use a CSS attribute-selector, selecting only elements that have a specific attribute present, such as – as in your question – the id:

h1[id], h2[id] {
/* CSS rules */
}

h1[id],

h2[id] {

color: limegreen;

font-size: 2em;

}
<h1>Heading level 1, with no id</h1>

<h1 id="h1">Heading level 1, with an id</h1>

<h2>Heading level 2, with no id</h1>

<h2 id="h2">Heading level 2, with an id</h1>


Related Topics



Leave a reply



Submit