CSS selector with period in ID - html

The HTML spec allows for periods (.) in an id:
<img id="some.id" />
However, using a CSS ID selector rule will not match correctly:
#some.id { color: #f00; }
The CSS spec for ID Selectors does not mention this case. So I assume it is using the combination of a tag name and class selector? For example, a CSS rule of a.className would apply to all anchor tags (<a>) with a class name of className, like <a class="className"></a>.
Is it possible to have an external CSS file rule that references an HTML element by its id that has a period in it?
I expect not since the CSS spec specifies that a CSS "identifier" does not include the period as a valid character. So is this a fundamental mismatch between HTML and CSS specs? Is my only alternative to use a different type of CSS selection? Can anyone smarter than I confirm or deny this?
(I would remove the period from the HTML id attribute to simplify things, but it is a system-generated id, so I don't have the ability to change it in this case.)

After digging through the specs some more, I found the CSS spec does allow for backslash (\) escaping like most languages.
So in my example, the following rule would match:
#some\.id {
color: #f00;
}

You could also use the attribute selector like this:
[id='some.id'] {
color: #f00;
}

Since you are using id, you can also use document.getElementById() which checks the id value as a normal string and not a CSS selector.
e.g. the following works too:
const myElem = document.getElementById("some.id");
The only drawback is, you can't limit the scope of search, like you could with querySelector e.g. someElement.querySelector().
but since Ids should always be unique, a document wide search with id is valid.

Related

How to configure stylelint to ban all HTML tags

Is there a way to configure stylelint to disallow all selectors which include tag names?
I found the (stylelint-selector-tag-no-without-class)[https://www.npmjs.com/package/stylelint-selector-tag-no-without-class] plugin, using which I want to ban ALL tag names, present and future, without listing each and every tag.
You can use the built-in selector-max-type rule to disallow all selectors which include tag names (aka type selectors):
{
"rules": {
"selector-max-type": 0
}
}
This will disallow all tag names, present and future, as the rule disallows selectors that are parsed as type selectors, rather than relying on some list of known type selectors.
Edit: #jeddy3's answer is better. Use that.
Configure the rule like so for all tags and custom elements: ​"plugin/selector-tag-no-without-class": ["/\\w+/"].
If you use BEM you'll want to allow __ and -- prefixes too: "plugin/selector-tag-no-without-class": ["/^(?!.__*).\\w+/"].
(Solution based on these SO answers: https://stackoverflow.com/a/28975388/915875 and https://stackoverflow.com/a/1240365/915875).

CSS classes with special characters

I have a WebApp where I need to manipulate certain elements using a CSS file. The CSS classes contain square brackets and other special characters. At least chrome doesn't seem to accept them directly.
<div class="profileElement profile[~redString]">123</div>
Is this class even valid? Is there a way to use the classname? I want:
.profile[~redString]{
color: red; }
When I escape the ~ with a backslash chrome allows me to inject (F12 -> Elements -> the plus symbol on the top right) it to the page but displays the css in grey, meaning the class does not exist in the page.
Is that class valid?
If so, how would I use it?
Is this class even valid?
It depends on what you're validating against.
profile[~redString] is a valid HTML class name, exemplified by putting the markup through a validator.
However, .profile[~redString] is not a valid CSS selector, because the ~ is a special symbol as you have found out, and it's not in a place where the CSS parser would expect it. When you escape it, you get
.profile[\~redString]
which is a valid selector, but with a completely different meaning. It represents an element with a class name profile, as well as an attribute called ~redString. It does not represent an element with a class name that is exactly profile[~redString].
To match this element, you need to escape the square brackets as well. This will result in the entire stream of characters being treated as a single identifier:
.profile\[\~redString\]
Alternatively, you can use an attribute selector instead to make things cleaner:
[class~="profile[~redString]"]
Notice the ~= in this CSS2.1 attribute selector, which works similarly to a class selector.
See both selectors in action:
:first-child.profile\[\~redString\],
:last-child[class~="profile[~redString]"] {
color: red;
}
<div>
<div class="profileElement profile[~redString]">123</div>
<div class="profileElement profile[~redString]">456</div>
</div>

Need equivalent CSS Selectors of an XPATH expression

I have an html code as below :
<div id="select_a_boundary" class="dataset_select2">Homes name</div>
I wrote a xpath expression for the same:
//div[#id = 'select_a_boundary' and #class = 'dataset_select2']
What will be the equivalent CSS Selectors for the same?
First of all if you are using id, you don't require to use class, secondly if you are willing yo select an element with an id select_a_boundary you can use
#select_a_boundary {
/* Styles goes here */
}
Demo
Note: Am not selecting the element which has that id and that class as
here, id is sufficient as it has to be unique, if you are using the id
for multiple elements than it's invalid
As per your comment
div[id=select_a_boundary][class=dataset_select2] {
color: red;
}
Demo X-Path Equivalent
Or an easier one (Credits: Jack)
#select_a_boundary.dataset_select2 {
color: red;
}
Note: Still I would recommend you to use #select_a_boundary is more
than enough
The equivalent of your expression in CSS is this:
#select_a_boundary.dataset_select2 {
/* whatever */
}
Because identifiers in a single document should be unique, you can even narrow it down to:
#select_a_boundary {
/* whatever */
}
One important thing to realize is that although XPath and CSS selectors have many similarities, they're two different things.
For instance, there's no XPath equivalent of :active or :hover for instance. Properly matching by class names is also more cumbersome with XPath.
On the other hand, CSS can't match things like "all paragraphs with an anchor child" which is trivial in XPath using //p[a].

why does the *#uniqueID selector exist if the ID attribute is supposed to be unique?

I understand that there is a *.className selector since there can be multiple html elements with class=className.
But for the ID attribute which should be unique, why does *# exist and when do we use it?
Thanks.
The * matches any element, not all elements. It is called the universal selector
So *#myid matches any element with id equals myid. In CSS, it does not really matter and it is equivalent to #myid.
Source
Just because IDs are supposed to be unique doesn't mean they are. You can create multiple elements with the same ID, but you shouldn't. CSS doesn't care anyway, lack of uniqueness would just screw with Javascript. For example, if you have this:
<div id='blah'>blah</div>
<div id='blah'>blah</div>
<div id='blah'>blah</div>
<div id='blah'>blah</div>
Then jQuery('#blah') returns [ div#blah ], whereas jQuery('*#blah') returns [ div#blah, div#blah, div#blah, div#blah ].
jsFiddle Demo
Combining the universal selector with the ID, class, or attribute selectors makes no difference: #foo is the same as *#foo, .bar is the same as *.bar, and [baz] is the same as *[baz]. Therefore, you don't want to be using the universal selector in these scenarios.

What do square brackets in class names mean?

I saw here square brackets that are used in class names:
<input class="validate[required,custom[onlyLetter],length[0,100]]" name="firstname" type="text" />
What do these square brackets mean?
The square brackets are used as an attribute selector, to select all elements that have a certain attribute value. In other words, they detect attribute presence.
Example 1:
img[alt="picName"] {width:100px;}
would affect only
<img src="picName.png" alt="picName" />
in your code, and won't affect
<img src="picName.png" alt="picName2" />
Example 2:
The following affects all elements with title attribute specified:
[title] {border:1px dotted #333;}
Example 3:
This CSS
p[class~="fancy"]
will affect the following html
<p class="fancy">Hello</p>
<p class="very fancy">Hola</p>
<p class="fancy maybe">Aloha</p>
but won't affect this:
<p class="fancy-fancy">Privet</p>
Example 4:
[lang|="en"]
will affect elements with lang attribute, which is hyphen-separated list of words beginning with “en”, like
<div lang="en">Tere</div>
<div lang="en-gb">GutenTag</div>
Examples 5, 6, 7:(CSS3)
The following attribute selector affects link elements whose href attribute value starts with the string “http:”.
a[href^="http:"]
The following attribute selector affects image elements whose src attribute values ends with the string “.png”.
img[src$=".png"]
The following attribute selector affects any input element whose name attribute value contains the string “choice”.
input[name*="choice"]
That is most likely used by some sort of validator or validation library. The class here means that validate this field denoted by validate keyword and then:
required it is required field
custom validation type; allow only letters
length should be between 0 to 100 chars
Well, this information is used by the jQuery validation library you posted the link to :)
Apart from the use-case / example given by the OP for brackets in class names, there is also another use case which Harry Roberts proposed (and later stopped proposing) in his blog a while back: grouping related classes in your markup where the square brackets could be used to group
two or more related class attributes to make them easier to notice
when scanning an HTML file
...
and that looks something like this:
<div class="[ foo foo--bar ] baz">
where:
There must be more than one ‘set’ of classes.
One ‘set’ must contain more than one class.
He also noted that adding the brackets is completely valid according to the html5 spec
There are no […] restrictions on the tokens authors can use in the
class attribute…
Just to reiterate:
The brackets in the class attributes - while being valid CSS class names are not actually meant to be used in the CSS1 - but rather to help readability in the HTML.
Notes:
1
Although technically, they can be used when escaped,
.\[ {
color: red;
}
<div class="[">Hi there</div>
Nothing. Brackets are a legal character for class names with no special meaning whatsoever.
In standard HTML, they have no particular meaning. It's just more text.
To the jQuery Validation plugin, they do.
Example:
[what-ever] {
color: red;
}
<p what-ever>Hello</p>
This will color Hello red. You can use square-bracket as class names
There is no particular rule within a class name. In your example they are almost certainly being used by a JavaScript validation framework. This is because in HTML you can't simply add your own attributes to tags, therefore the validation framework is exploiting the fact that CSS class names can contain such characters in order to 'store' the validation rules within the class name. There won't actually be any corresponding class in the style-sheet - this is just a trick to work around the limitations of HTML.