CSS classes with special characters - html

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>

Related

What does a reference inside a div tag without an attribute do?

I would like to start using Attribute Selectors in my css. I am seeing div tags that contain a reference WITHOUT any attribute statement like:
<div class="container" data-footer>
All my searches (for the last hour) to find out how "data-footer" can be listed without the use of an attribute= (e.g., id= or class= or etc.) have resulted in no information. Dozens of SO and Google links without a single example of a reference inside a div tag without the use of an attribute. Because I do not know what this is (or what to call it) I'm probably not searching with the right keywords. Is this a short-form way to pass an id or ???
Data- attributes without a value can be used as Boolean. For example:
if(div.hasAttribute('data-footer')) {
// then do something
}
In css you can access it like:
div[data-footer] {
}

style auto generated html attributes with regex

I have an ionic/angular app which autogenerates a custom tag element with a different _ngcontent attribute each time e.g.:
<tag _ngcontent-hgr-c2>...</tag> (1st refresh)
<tag _ngcontent-agj-c7>...</tag> (2nd refresh)
<tag _ngcontent-cfx-c5>...</tag> (3rd refresh)
Is there a way to use regex to target the custom tag attribute?
This didn't work:
tag[^=_ngcontent-] {
color: red !important;
}
Nor did just targetting the tag app e.g.:
tag {
color: red !important;
}
According to this answer, there is kind of regex in CSS, but it can be only applied to attribute's value, not to attribute itself. The W3C documentation says the same, so because Angular creates custom attributes, I'm afraid that it can be hard to achieve by regex.
If you want to style your tag like in the second example you can do it by defining its styles in global styles.scss. This is not the best solution, but should work.
This angular-blog article recently helped me understand the idea behind the style ecapsulation.
Unfortunately, there is no wildcarding support in CSS for attribute names.
If you have access to the application code which generates the custom tags, you should add classes to these elements (if the app supports it).
See also this question.

Dollar sign in HTML attribute name

I was looking at some Polymer code (link) and stumbled upon something new to me: a dollar sign $ in an html attribute name e.g.
<div class="item" wide-layout$="{{wide}}">
Also, a CSS selector is used:
.item[wide-layout] .title { ... }
How is the $ sign interpreted in the element attribute ?
Thanks for your time folks!
Using $ on the element binds a property to an attribute. You can read more here.
wide in your scenario is probably a Boolean property on the element.
When wide = true, a wide-layout DOM attribute will be added to the element so it can be targeted via CSS.
The dollar sign tells Polymer that some code will change the attribute, may it be class or any specific property on a Polymer element.
The code can be a function or a simple variable.
Example:
<shopping-cart class$="[[colorDependingOnItem(onSale, typeOfBrand)]] row-element">
So the class can now change dynamically depending on what the method colorDependingOnItem returns, based on the two properties onSale and typeOfBrand.

CSS selector with period in ID

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.

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.