Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm using JSDoc. It generates ids with a period as in

<a id=".someMethodName"></a> 

If another part of the page has

<a href="#.someMethodName"></a>  

That works perfectly. Clicking the second anchor scrolls to the first.

But, neither document.querySelector nor jQuery will find the anchor.

Why does the browser itself accept this anchor but jQuery and querySelector do not?

test("document.querySelector('#.someMethodName')", function() {    document.querySelector('#.someMethodName');  });  test("$('#.someMethodName')", function() {    $('#.someMethodName');  });    function test(msg, fn) {    try {      var result = fn();      log(msg, result);    } catch(e) {      log(msg, e);    }  }    function log() {    var pre = document.createElement("pre");    pre.appendChild(document.createTextNode(Array.prototype.join.call(arguments, " ")));    document.body.appendChild(pre);  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <a href="#.someMethodName">click here to go to anchor and see errors</a>  <pre>  put  some  text  here  so  the  page  is  long  enough  that  when  we  click  the  anchor  the  browser  has  as  a  place  to  scroll  that  is  off  screen  otherwise  we'd  have  no  way  to  see  if  it  worked  or  not  </pre>  <a id=".someMethodName">we should scroll to here</a>  <p>did we make it?</p>  <hr/>
like image 274
gman Avatar asked Mar 14 '16 06:03

gman


People also ask

Why is the sky blue short answer?

The Short Answer: Sunlight reaches Earth's atmosphere and is scattered in all directions by all the gases and particles in the air. Blue light is scattered more than the other colors because it travels as shorter, smaller waves. This is why we see a blue sky most of the time.

How is the sky blue?

The scattering caused by these tiny air molecules (known as Rayleigh scattering) increases as the wavelength of light decreases. Violet and blue light have the shortest wavelengths and red light has the longest. Therefore, blue light is scattered more than red light and the sky appears blue during the day.

Why is the sky blue but space is black?

Since there is virtually nothing in space to scatter or re-radiate the light to our eye, we see no part of the light and the sky appears to be black.

What makes the sky blue during the day?

Gases and particles in Earth's atmosphere scatter sunlight in all directions. Blue light is scattered more than other colors because it travels as shorter, smaller waves. This is why we see a blue sky most of the time.


1 Answers

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') 

1Several 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.

like image 182
BoltClock Avatar answered Sep 21 '22 04:09

BoltClock