You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Scrollspy stops working when any of the DOM elements it is "spying" on has an id that starts with a number, such as
<divid="3rd">Text</div>
This should be considered a bug because HTML5 has no restrictions on what form an ID can take (official spec).
There are no other restrictions on what form an ID can take; in particular, IDs can consist of just digits, start with a digit, start with an underscore, consist of just punctuation, etc.
Historically, HTML4 did not allow for ids to start with numbers, but it would seem ridiculous to assume only HTML4 content today.
Bug Demo
See this JSBin for the demo. https://jsbin.com/rehematazo/3/edit?html,output. By default, I've commented out the <a> elements that link to <div>s whose IDs start with a digit, so Scrollspy works. But once you uncomment out these <a> tags, then Scrollspy stops working entirely.
I have also copied the HTML code for the demo here:
Code
<!DOCTYPE html><html><head><metacharset="utf-8"><metaname="viewport" content="width=device-width"><title>JS Bin</title><linkhref="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"><style>
.tall { height:300px; }
.toc-nav { /* <nav> */position: sticky;
top:0;
height: min-content;
max-height:100vh;
overflow-y: auto;
}
.toc-nava.active {
color:#007bff;
}
</style></head><bodydata-bs-spy="scroll" data-bs-target="#nav"><divclass="container"><divclass="row"><mainclass="col-8"><h2id="A">ID A</h2><divclass="tall">Chunk of text</div><h2id="B">ID B</h2><divclass="tall">Chunk of text</div><h2id="C">ID C</h2><divclass="tall">Chunk of text</div><h2id="1">ID 1</h2><divclass="tall">Chunk of text</div><h2id="2">ID 2</h2><divclass="tall">Chunk of text</div><h2id="3">ID 3</h2><divclass="tall">Chunk of text</div></main><navclass="col-4 toc-nav" id="nav"><navclass="navbar navbar-light"><spanclass="navbar-brand">Contents</span><aclass="list-group-item list-group-item-action" href="#A">Item A</a><aclass="list-group-item list-group-item-action" href="#B">Item B</a><aclass="list-group-item list-group-item-action" href="#C">Item C</a><!-- Uncomment the following 3 lines to see the bug: Once you uncomment, you will notice that Scrollspy stops working. --><!-- <a class="list-group-item list-group-item-action" href="#1">Item 1</a> <a class="list-group-item list-group-item-action" href="#2">Item 2</a> <a class="list-group-item list-group-item-action" href="#3">Item 3</a> --></nav></nav></div></div><scriptsrc="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script></body></html>
However, document.querySelector() only works for valid CSS selector strings, and CSS selector strings for IDs cannot start with a number (even though HTML IDs can). See this StackOverflow Q&A for more info: https://stackoverflow.com/q/20306204. This causes Bootstrap JS to encounter the following error (copied from Microsoft Edge console):
Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '#3rd' is not a valid selector.
at <anonymous>:1:10
The StackOverflow Q&A proposes several possible fixes. For example, document.getElementById("3rd") works fine, but only works with ID-based selectors. I am also not sure which fixes fall within Bootstrap's browser compatibility goals.
System Info
OS: Windows 10 20H1
Browser: Microsoft Edge (Chromium) 91.0.864.59 and Firefox 89.0.2 (64-bit)
Bootstrap version 5.0.2
The text was updated successfully, but these errors were encountered:
Same topic than #31099 and a few others— this is a concern for all components. Any PR is welcome, but FWIW the HTML spec evolved but browsers and other specs (eg CSS or DOM) took some time to close the gap.
@ffoodd Thanks for pointing out the related issue.
Given that Scrollspy is only meant to point to elements with specific IDs, can we use document.getElementById() instead of document.querySelector()? Put another way, why does the code use document.querySelector() at all?
I'm tagging @XhmikosR, who seems to have been the last person to touch this code.
Bug Report
Scrollspy stops working when any of the DOM elements it is "spying" on has an id that starts with a number, such as
This should be considered a bug because HTML5 has no restrictions on what form an ID can take (official spec).
Historically, HTML4 did not allow for ids to start with numbers, but it would seem ridiculous to assume only HTML4 content today.
Bug Demo
See this JSBin for the demo. https://jsbin.com/rehematazo/3/edit?html,output. By default, I've commented out the
<a>
elements that link to<div>
s whose IDs start with a digit, so Scrollspy works. But once you uncomment out these<a>
tags, then Scrollspy stops working entirely.I have also copied the HTML code for the demo here:
Code
Why this happens, and possible fixes
This bug seems to happen because Bootstrap uses
document.querySelector()
to identify elements:bootstrap/js/dist/scrollspy.js
Line 78 in 696996d
However,
document.querySelector()
only works for valid CSS selector strings, and CSS selector strings for IDs cannot start with a number (even though HTML IDs can). See this StackOverflow Q&A for more info: https://stackoverflow.com/q/20306204. This causes Bootstrap JS to encounter the following error (copied from Microsoft Edge console):The StackOverflow Q&A proposes several possible fixes. For example,
document.getElementById("3rd")
works fine, but only works with ID-based selectors. I am also not sure which fixes fall within Bootstrap's browser compatibility goals.System Info
OS: Windows 10 20H1
Browser: Microsoft Edge (Chromium) 91.0.864.59 and Firefox 89.0.2 (64-bit)
Bootstrap version 5.0.2
The text was updated successfully, but these errors were encountered: