Actually ID's containing ':'(colon) shouldn't work in a self contained file either.
It's a matter of XML naming compliance.
An excerpt from the MDN Docs
It must be valid in XML documents. A stand-alone SVG document uses XML 1.0 syntax, which specifies that valid IDs only include designated characters (letters, digits, and a few punctuation marks), and do not start with a digit, a full stop (.) character, or a hyphen-minus (-) character.
As a rule of thumb:
apply the same naming rules, you would also need for html/css/js selectors:
- keep it ansi: avoid non-english characters like diacritics/accents etc.
- don't start selector names with any numbers – appending them like 'element-01' is perfectly OK
- avoid characters, which are also used as operators: like the colon for pseudo-elements, plus or tilde for adjacent siblings etc.
#myGradient\:1234{
color:red
}
#myGradient\:1234,
#\31 234myGradient{
color:#000
}
#myGradient-1234{
color:green
}
<ul>
<li id="myGradient-1234">Selectable!</li>
<li id="myGradient:1234">Not selectable: selector contains <strong>colon operator reserved for pseudo elements</strong>. You might however escape the colon by a backslash</li>
<li id="1234myGradient">Not Selectable: selector starts with <strong>numbers</strong></li>
</ul>
Edit: Here's a helper function to check validity.
checkIDs(document.body);
// check id validity
function checkIDs(el) {
let Ids = el.querySelectorAll('[id]');
let allIds = [];
let IdIssues = {
'non-unique': {},
'not-selectable': [],
}
for (let i = 0; i < Ids.length; i++) {
let thisId = Ids[i].id;
if (allIds.indexOf(thisId) == -1) {
allIds.push(thisId);
} else {
let idKey = '\'' + thisId + '\'';
if (!IdIssues['non-unique'][idKey]) {
IdIssues['non-unique'][idKey] = 2;
} else {
IdIssues['non-unique'][idKey] += 1;
}
}
try {
let selection = document.querySelector('#' + thisId);
} catch {
if (IdIssues['not-selectable'].indexOf(thisId) == -1) {
IdIssues['not-selectable'].push(thisId);
}
}
}
let errorCount = 0;
let nonUniqueCount = Object.keys(IdIssues['non-unique']).length;
let notSelectableCount = IdIssues['not-selectable'].length;
errorCount = nonUniqueCount + notSelectableCount;
if (errorCount) {
console.log('Id naming issues found:\n' + 'non unique Ids: ' + nonUniqueCount + '\n' + 'not selectable Ids: ' + notSelectableCount);
console.log(IdIssues);
} else {
console.log('Well done! – all Ids are valid and unique!')
}
}
<svg id="test" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle id="circle" fill="none" cx="50%" cy="100%" r="50%" stroke="red" stroke-width="2" />
<circle id="circle:123" fill="none" cx="25%" cy="25%" r="25%" stroke="green" stroke-width="2" />
</svg>
<p id="p1@test">test1</p>
<p id="p1!test">test1</p>
<p id="c'mon">test1</p>
<p id="p2">test1</p>
<p id="p2">test1</p>
<p id="p2:1:2">test1</p>
<p id="0123id">test1</p>
This js helper function uses a simple try/catch to check wether an element is actually selectable in DOM or not. So we don't need to check hundreds of renown uncompliant character/naming issues.
Besides, the script will also check non-unique ids that might also cause troubles.