RegEx for css class name - css

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
});

Related

:empty doesn't work if there's blank spaces?

Trying to find a pseudo class that'll target a <div> like this:
<div class="nav-previous">
</div>
I've tried :blank and :empty but neither can detect it. Is it just not possible to do?
https://jsfiddle.net/q3o1y74k/3/
:empty alone is enough.
By the current Selectors Level 4 specification, :empty can match elements that only contain text nodes that only contain whitespace as well as completely empty ones. It’s just there aren’t many that support it as per the current specification.
The :empty pseudo-class represents an element that has no children except, optionally, document white space characters.
From the MDN:
Note: In Selectors Level 4, the :empty pseudo-class was changed to act like :-moz-only-whitespace, but no browser currently supports this yet.
The :-moz-only-whitespace CSS pseudo-class matches elements that only contain text nodes that only contain whitespace. (This includes elements with empty text nodes and elements with no child nodes.)
As the others mentioned, this isn't possible with CSS yet.
You can check to see if there's only whitespace with JavaScript however. Here's a simple JS only solution, "empty" divs that match are blue, while divs that have text are red. Updated to add an empty class to the empty divs, which would allow you to target them easily with the selector .empty in your CSS.
The JS only "empty" comparison would look like this:
if(element.innerHTML.replace(/^\s*/, "").replace(/\s*$/, "") == "")
And if you're using jQuery it would be a bit easier:
if( $.trim( $(element).text() ) == "" ){
var navs = document.querySelectorAll(".nav-previous");
for( i=0; i < navs.length; i++ ){
if(navs[i].innerHTML.replace(/^\s*/, "").replace(/\s*$/, "") == "") {
navs[i].style.background = 'blue';
navs[i].classList.add( 'empty' );
} else {
navs[i].style.background = 'red';
}
}
.nav-previous {
padding: 10px;
border: 1px solid #000;
}
.nav-previous.empty {
border: 5px solid green;
}
<div class="nav-previous">
</div>
<div class="nav-previous">Not Empty </div>
The problem with your approach is that your container is not actually empty.
The :empty pseudo-class represents an element that has no children at
all. In terms of the document tree, only element nodes and content
nodes (such as DOM text nodes, CDATA nodes, and entity references)
whose data has a non-zero length must be considered as affecting
emptiness;
As you have empty spaces this pseudo class will not do the trick.
The :blank pseudo class should be the right one, because this is its definition:
This blank pseudo-class matches elements that only contain content
which consists of whitespace but are not empty.
the problem is that this pseudo class isn't implemented by any browser yet as you can check in the link below. So you will need to wait until it get implemented to be able to use this selector.
This pretty much explains the behavior you are facing
https://css4-selectors.com/selector/css4/blank-pseudo-class/
The best approach here is just to be sure that your div will actually be empty, so your approach will work.
the best that you can do is to define an empty class like this:
.empty{
display:none;
}
and then add this JS code here, it will append the empty class to your blank items:
(function($){
$.isBlank = function(html, obj){
return $.trim(html) === "" || obj.length == 0;
};
$('div').each(function() {
if($.isBlank(
$(this).html(),
$(this).contents().filter(function() {
return (this.nodeType !== Node.COMMENT_NODE);
})
)) {
$(this).addClass('empty');
}
});
})(jQuery);
check it working here,
https://jsfiddle.net/29eup5uw/
You just can't without JavaScript/jQuery implementation.
:empty selector works with empty tags (so without even any space in them) or with self-closing tags like <input />.
Reference: https://www.w3schools.com/cssref/css_selectors.asp
If you want to use JavaScript implementation, I guess here you will find the answer: How do I check if an HTML element is empty using jQuery?
:empty indeed only works for totally empty elements. Whitespace content means it is not empty, a single space or linebreak is already enough. Only HTML comments are considered to be 'no content'.
For more info see here: https://css-tricks.com/almanac/selectors/e/empty/
The :blank selector is in the works, it will match whitespace, see here: https://css-tricks.com/almanac/selectors/b/blank/. But it seems to have no browser support yet.
Update:
See here for possible solutions to this involving jQuery.

SASS: Conditional values of CSS property based on that if an element with certain value of the same property has been present already in the page

I want to have different values of a css property (I am using SASS), based on that whether a element with a certain property's value '$additionalNavHeight' is present on the page. In some pages there is no such element, in other - there is. I wrote a SASS mixin:
#mixin top-position($navHeight, $additionalNavHeight)
{
#if $additionalNavHeight == true {
.loadingAnimation {
top: $navHeight + $additionalNavHeight;
}
}
#else {
.loadingAnimation {
top: $navHeight;
}
}
}
And I included the mixin in the selector:
#include top-position($navHeight, $additionalNavHeight);
I thought this should change the value of the property 'top' of the element with the class 'loadingAnimation', based on that if in the page already is present the element with the value of its 'top' property '$additionalNavHeight'. The compiler doesn't show any error, but the code doesn't change anything. What am I doing wrong? Any help would be very appreciated.
Тhe simplest solution. You must check with JavaScript if element exists or not
and to apply the second class to element. In the second case (element existing)
you must add adittionnal height. In this case the mixin is redundant.
.loadingAnimation {
top: $navHeight;
}
.loadingAnimation.additinnalHeight {
top: $navHeight + $additionalNavHeight;
}
Here is example jsfiffle:
https://jsfiddle.net/ra9r8rk8/
In this case element will receive class newClass when the first div exists. (the element)
Edit: This is second improved solution. In fact there is no need for regular expression. We can just use classList:
https://jsfiddle.net/ra9r8rk8/1/

target child id el by knowing the parent class

I have a css class that has a couple of children and I know that the child ellement that I want to target has an id that ends with 'inner-Ct. I don't want to assign it my unique id because it will be used in many places.
<div class="totalSummary">
<div>
<div id = "form-1406-innerCt"></div> //<---- this is the one I want to target
...
<div>
</div>
It's there a way to do this using css?
You could use the $ attribute selector to match the end of the ID like:
.totalSummary div[id$="innerCt"] {
background: red;
}
jsFiddle example
See: http://www.w3.org/TR/selectors/#selectors
[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.
You can use something like:
.totalSummary div[id$="innerCT"] {
color: gold; /* The $ indicates a string that an attribute
value ends with, in this case "innerCt" */
}
Example: http://jsfiddle.net/xgRk7/

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"

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

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.

Resources