Styling elements with a dot (.) in the class name - css

Hay I have an element like this
<span class='a.b'>
Unfortunately this class name comes from an eCommerce application and cannot be changed.
Can I style a class name with a dot in it?
like
.a.b { }

.a\.b { }
However there could be browsers around that don't support this.

Coming very late to this party, but you can use attribute selectors.
In your case, to target the class='a.b' element, you could use:
[class~="a.b"] {...}
// or
span[class~="a.b"] {...}
Additionally, here is the full list of attribute selectors.
Attribute Present Selector
// Selects an element if the given attribute is present
// HTML
<a target="_blank">...</a>
// CSS
a[target] {...}
Attribute Equals Selector
// Selects an element if the given attribute value
// exactly matches the value stated
// HTML
...
// CSS
a[href="http://google.com/"] {...}
Attribute Contains Selector
// Selects an element if the given attribute value
// contains at least once instance of the value stated
// HTML
...
// CSS
a[href*="login"] {...}
Attribute Begins With Selector
// Selects an element if the given attribute value
// begins with the value stated
// HTML
...
// CSS
a[href^="https://"] {...}
Attribute Ends With Selector
// Selects an element if the given attribute value
// ends with the value stated
// HTML
...
// CSS
a[href$=".pdf"] {...}
Attribute Spaced Selector
// Selects an element if the given attribute value
// is whitespace-separated with one word being exactly as stated
// HTML
...
// CSS
a[rel~="tag"] {...}
Attribute Hyphenated Selector
// Selects an element if the given attribute value is
// hyphen-separated and begins with the word stated
// HTML
...
// CSS
a[lang|="en"] {...}
Source: learn.shayhowe.com

Perhaps you could scan the elements for these classes and add a class that you could style.
For instance, scan all elements with the “a.b” class and then add a new “style-ab” class or some such.
I haven’t posted any example code for this as people may want to use vanilla Javascript or jQuery and it’s a simple enough thing to do.
To clarify, my gaming framework does exactly as the OP described so translations could be applied to certain divs and spans. It’s not a nasty way to decide class names, it’s just useful for people creating markup when using a dictionary that has keys for phrases

Yes you can.
The meaning of CSS class name like '.a.b' is targeting elements that have CSS name with 'a' which also has class name 'b',that's to say you have both of these class in the same element. Just as div.cssname targeting div elements with cssname.

Related

Testing contents of after CSS selector in protractor

In my HTML I have element such as below
HTML:
<hmtl>
<head>
<style>
label::after {
content: " *"
}
</style>
</head>
<body>
<label> I'm mandatory</label>
</body>
</hmtl>
So what gets displayed on browser is:
I'm mandatory *
Query Selector
>getComputedStyle(document.querySelector('label')).content
<"normal"
So I see normal instead of *.
I can't see where is normal coming from. Is this the correct way to test content of ::after CSS selector?
I want to test that there's a "*" after the label, but can't seem to be able to get the value of "content" property correctly. Once I'm able to find it in using browser DOM API, I'd eventually want to test it in protractor.
Update
I found the answer at - Selenium WebDriver get text from CSS property "content" on a ::before pseudo element.
Now the question remains how I would test this on protractor.
Window.getComputedStyle()
The Window.getComputedStyle() method returns an object containing the values of all CSS properties of an element, after applying active stylesheets and resolving any basic computation those values may contain. Individual CSS property values are accessed through APIs provided by the object, or by indexing with CSS property names.
Syntax:
var style = window.getComputedStyle(element [, pseudoElt]);
element
The Element for which to get the computed style.
pseudoElt (Optional)
A string specifying the pseudo-element to match. Omitted (or null) for real elements.
The returned style is a live CSSStyleDeclaration object, which updates automatically when the element's styles are changed.
You can find a related discussion in WebDriver select element that has ::before
Usage with pseudo-elements
getComputedStyle() can pull style info from pseudo-elements (such as ::after, ::before, ::marker, ::line-marker.
As per the HTML, the <style> is as follows:
<style>
label::after {
content: " *"
}
</style>
Implemented as:
<label> I'm mandatory</label>
To retrieve you need to:
var label = document.querySelector('label');
var result = getComputedStyle(label, ':after').content;
console.log('the generated content is: ', result); // returns ' *'
Reference
CSS Pseudo-Elements Module Level 4
const label = document.querySelector('label'); // "normal";
console.log(label);
const labelAfter = getComputedStyle(label, ':after').content;
console.log(labelAfter == "normal");
label::after {
content: " *"
}
<label> I'm mandatory</label>
Since my question was specifically w.r.t protractor I'm posting the solution that I got working. Coming to the part I was stuck initially - why do I get "normal" instead of " *"
>getComputedStyle(document.querySelector('label')).content
<"normal"
So earlier I was unaware that ::after creates a pseudo child element inside the label element.
Inspecting <label> element in Chrome shows the below HTML
<label>
I'm mandatory
::after
</label>
If I click<label> element and checked the Computed tab, I could see that the value for content property is normal.
However, if I click on ::after pseudo-element, I can see in the Computed tab the value for content property is " *".
As mentioned in the other answers getComputedStyle() with the pseudo element as second parameter, is the only way to get value of CSS property for "::after". The crux of the problem is that protractor does not have an equivalent for getComputedStyle(), so we have to rely upon browser.executeScript() as shown below:
let labelHeader = 'I'm mandatory *';
// Passing label element separately as in the real test case, it would be extracted from parent
// enclosing element and need to be able to pass it as a parameter to browser.executeScript().
let label = element(by.css('label'));
browser.executeScript("return window.getComputedStyle(arguments[0], ':after').content",
label)
.then ((suffixData: string) => {
// suffixData comes out to be '" *"', double quotes as part of the string.
// So get rid of the first and last double quote character
suffixData = suffixData.slice(1, suffixData.length - 1);
labelText += suffixData;
expect(labelText).toBe(labelHeader);
});

How to select part of a custom element with CSS?

To select all elements that start with the class name foo. I can use:
[class^="foo"] { }
What can I use to select a custom element that starts with foo.
Example:
<foo-bar>Hola</foo-bar>
<foo-bazz>Hola</foo-bazz>
I want to have a single selector for both elements.
You can't. The [...] selectors only work on attributes, not element types themselves.
What you can do though, as I'm sure you're already aware, is chain them all into one selectors group, but this will mean that you'll need to know the exact element names:
foo-bar,
foo-bazz {
...
}
Failing that, you can always just give them all a shared class or data-* attribute:
<foo-bar class="foo"></foo-bar>
<foo-bazz class="foo"></foo-bazz>
.foo {
...
}

RegEx for css class name

I want to have a class cX where x is a number between 0 and 100. I could add c0 to c100 to my css. But well, I'd like to avoid that.
I know there are ways to match element attributes like h2[rel="external"]. But is it also possible to match class names? Would it also possible to use the matched value within the rule?
Example
.c[x] { height: x%; }
EDIT - CSS attr
After a bit of research, I found that there is a CSS function called attr which is exactly what you are looking for, however, its support is currently limited to the CSS content property and not others, however, it is interesting to keep an eye on it, I reckon it will be the solution of the future
From Moz MDN:
The attr() CSS function is used to retrieve the value of an attribute
of the selected element and use it in the style sheet. It can be used
on pseudo-elements too and, in this case, the value of the attribute
on the pseudo-element's originated element is returned.
Your code would probably look like this:
.c { height: attr(data-height %, 0); }
HTML
<div class="c" data-height="1"></div>
...
This will get the height from the element's data attribute and sets it with the % percentage unit and falls back to 0 if data-height is not found.
Current supported methods:
From the W3 Docs:
6.3.2. Substring matching attribute selectors
Three additional attribute selectors are provided for matching
substrings in the value of an attribute:
[att^=val]
Represents an element with the att attribute whose value
begins with the prefix "val". If "val" is the empty string then the
selector does not represent anything.
[att$=val]
Represents an element
with the att attribute whose value ends with the suffix "val". If
"val" is the empty string then the selector does not represent
anything.
[att*=val]
Represents an element with the att attribute
whose value contains at least one instance of the substring "val". If
"val" is the empty string then the selector does not represent
anything. Attribute values must be CSS identifiers or strings. [CSS21]
The case-sensitivity of attribute names in selectors depends on the
document language.
As discussed in the comments, there is no pure CSS solution at the moment, you could try one of the following approaches:
SASS
#for $i from 1 through 100 {
$height: percentage($i/100);
.c#{$i} {height: $height;}
}
Output:
.c1 {height: 1%;}
.c2 {height: 2%;}
.c3 {height: 3%;}
...
LESS
.c-gen(#index) when (#index > 0){
.c#{index}{
height: #index * 1%;
}
.c-gen(#index - 1);
}
.c-gen(100);
LESS code by Harry
Server Side
You could make your server side script output inline CSS for each item
PHP Example:
<?php
for ($i = 1; $i <= 100; $i++) {
echo "<span height='".$i."%'>".$i."</span>";
}
?>
Output
<span height="1%">1</span>
...
jQuery
var i = 0;
$('.c').each(function() {
i++;
$(this).attr('height', i + '%');
//console.log(i); //debug
});

How can I apply an external CSS class to a span created with dojo.create?

I'm creating a span in my web page with dojo.create, and need to apply CSS to it. I can see how to apply a style to it in the dojo reference, but I'd rather apply it via the external stylesheet (there's quite a few attributes I need to set and I'd rather not do it inline).
So given the example code below, how would I apply the CSS for the printSpan class?
var node = dojo.create("span", {innerHTML:_text, id:"printSpan", class:"printSpan"}, map);
You can write this in your external stylesheet:
.printSpan { color: red; }
This is called the class selector.
By the way, your code should be:
{ innerHTML : _text, id : "printSpan", "class" : "printSpan" }
Notice the colon was inside the "class" string, though it should be outside and printSpan is a different string.

What does the selector [class^="span"] do?

I can't work out what this is:
Line 33 of http://twitter.github.com/bootstrap/assets/css/bootstrap-1.2.0.min.css
.row [class^="span"] {
display: inline;
float: left;
margin-left: 20px;
}
I understand the style but I've never seen this before
[class^="span"]
This means a class beginning with the word "span", such as:
<div class="spanning"></div>
The ^ symbol is taken from regular expressions, wherein this symbol refers to the beginning of a string.
It should be noted that this checks for the beginning of the class attribute, not the beginning of the classname. Which means it will not match said selector:
<div class="globe spanning"></div>
The above element has two classes, the second of which begins with "span" - but since the attribute class begins with "globe", not with "span", it will not match.
One could use [class*=span], which would return all classes containing span, but that would also return other classes, such as wingspan.
AFAIK, the way to get classes that begin with a string are to use a double selector:
.row [class^="span"], .row [class*=" span"]{}
This will return the class beginning with span, whether at the beginning of the attribute, or in the middle.
(I also recall working in a solution in the homegrown selector engines used by DOMParser).
That is an attribute selector, specifically one of the CSS3 substring-matching attribute selectors.
This rule applies styles to any element whose class attribute begins with span (^= means "starts with"), that occurs in any element with the class row.
That is a CSS attribute Selector.
Have a look at http://www.w3.org/TR/css3-selectors/ (Section 2)
E[foo^="bar"] an E element whose "foo" attribute value begins exactly
with the string "bar"

Resources