Can a CSS selector search part of a word? - css

I need a pure CSS way to select an element based on part of an HTML attribute value. For example, I want to select this element:
<div data-gt="{'type':'select_me'}"></div>
based on the fact that the element has a data-gt value that contains select. The closest I can get is using [data-gt~=select] as a CSS selector, but that searches for whole words only. So if the word select in the HTML attribute was surrounded by spaces like {'type':' select _me'}, it could find it no problem, but it can't find it because it's preceded by a quote and followed by an underscore.
Note: The example above is a simplified version of what I want to do, so no I can't just change how the HTML attribute is generated and no I can't predict any of the surrounding data in the data-gt attribute.
Just curious if there is a pure CSS way to do this? I know it could be handled with Javascript, but that doesn't work for my purposes.

You can use the * attribute selector:
Represents elements with an attribute name of attr whose value
contains at least one occurrence of value within the string.
[data-gt*="select"] {
color: red;
}
<div data-gt="{'type':'select_me'}">Select Me</div>
<div data-gt="{'type':'please_dont'}">Don't Select Me</div>

Related

CSS How to check if an attribute name on HTML element itself (not the value) exists or matches some pattern?

lets say I have different div elements in HTML with different "data-something" attributes.
now, I want to check for all data-something attributes and check if they are present on the elements...
<div data-test1></div>
<div data-test2></div>
...etc.
I know that it's possible to check the value of attributes in css for some pattern matches, e.g
div[data-test1*="value"]
but how do I check the attribute itself if its present on some element, based on some regex match, e.g like matching the suffix data-test*, then then I color all divs background green on the elements that have those matching attributes present on themselves (just an example)...
Is there some way to do that?

CSS [attribute|=value] vs [attribute*=value] selectors

Why do we need the CSS [attribute|=value] Selector at all when the CSS3 [attribute*=value] Selector basically accomplishes the same thing, the browser compatibility is nearly similar? Is there something that the first CSS selector does and the second isn't able to? This is the first time to encounter two very similar selectors and wonder why the first one exists in the first place.
From the doc:
[attr|=value] Represents an element with an attribute name of attr.
Its value can be exactly “value” or can begin with “value” immediately
followed by “-” (U+002D). It can be used for language subcode matches.
[attr*=value] Represents an element with an attribute name of attr and
whose value contains at least one occurrence of string "value" as
substring.
Visual differences:
[attr|=value]
/* Any span in Chinese is red, matches simplified (zh-CN) or traditional (zh-TW) */
span[lang|="zh"] {color: red;}
<span lang='zh'>zh</span>
[attr*=value]
/* All links to with "example" in the url have a grey background */
a[href*="example"] {background-color: #CCCCCC;}
<a href="www.example.com">example<a/>
In the same code example:
div[color|="red"] {
background: red;
}
div[color*="blue"] {
color: blue;
}
<div>
<div color='red-yellow'>This shoud has only red background</div>
<div color='blue'>This shoud has only blue color</div>
<div color='red-blue'>This shoud has blue color and red background</div>
<div color='blue-red'>This shoud be only blue color</div>
</div>
References
Attribute selectors
There are a lot of differences between these two selectors
[lang|=en] {
background: yellow;
}
[lang*=en] {
color:red;
}
<p lang="en">Hello!</p>
<p lang="en-us">Hi!</p>
<p lang="en-gb">Ello!</p>
<p lang="usen">Hi!</p>
<p lang="noen">Hei!</p>
<p><b>Note:</b> For [<i>attribute</i>|=<i>value</i>] to work in IE8 and earlier, a DOCTYPE must be declared.</p>
The [attribute|=value] selector is used to select elements with the specified attribute starting with the specified value.
The [attribute*=value] selector matches every element whose attribute value containing a specified value.
See the example to get a clear idea about both the selectors.
They are distinctly different:
[attr|=value]
Represents an element with an attribute name of attr. Its value can be exactly “value” or can begin with “value” immediately followed by “-” (U+002D). It can be used for language subcode matches.
[attr*=value]
Represents an element with an attribute name of attr and whose value contains at least one occurrence of string "value" as substring.
https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
The first selector ensures the attribute value starts with the value submitted, the second only requires the attribute value contains it.
This would be helpful if you had to distinguish between attributes that had the same string in different positions within the same attribute.
CSS has evolved over time, and as it has evolved the need and want for more selectors, and functions has increased.
The CSS [attribute|=value] Selector was defined before CSS3 (latest version), and was available in CSS 2.1. As noted in the page you linked to:
used to select elements with the specified attribute starting with the specified value.
Whilst this is handy in most cases, sometimes there are frameworks, which come with structured css in the from of someString_somethingUseful_somethingElse for its class definition.
Now say I wanted to select all elements with the somethingUseful bit in it. The above selector would not allow me to do this, as the somethingUseful bit of the class definitions located in the middle of the class name. the same with the somethingElse bit, it is located at the end.
Thus in CSS3, we saw the introduction of [attribute*=value] selector which allows us to select elements which may have these keywords as a substring in their definition (though not necessarily at the front) See:
selector matches every element whose attribute value containing a specified value.

How To Apply CSS rule to Classes with Specific Keywords Inside Them?

That is to say, see the following:
<div class="helloeverybody">
</div>
<div class="heyeveryperson">
</div>
I want to apply a css rule to every class with the word "every" in it.
Is there a formal name for this?
You can use the "contains" attribute selector by appending an asterisk after the attribute - e.g.
div[class*=every] {
color: orange;
}
http://jsfiddle.net/FWP8j/1/
The definition from Selectors Level 3:
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.

Matching first element in whole document? [duplicate]

This question already has an answer here:
Matching the first/nth element of a certain type in the entire document
(1 answer)
Closed 7 years ago.
I want to match the first H1 element in my whole document. However, right now I'm faced with a problem.
I'm using the following CSS selector:
h1:first-child {
...
}
However, it matches several H1 tags on the page. How can I make it match only the first one?
There is no such selector; all available selectors can only match siblings, not the order of elements of the same name across multiple parents. Your selector would be very brittle anyways.
Instead, simply markup the first h1 with an appropriate class, or match its structure. For example, you might want to match
body>header:first-child>h1
instead.
That is because the selector does now look at the entire document, it looks at the parent. Any time an <h1> is the first child of any element, it will match to that selector. If you only want it to apply to one single <h1> in a document, considering giving it a separate class or ID, or selecting it more specifically based on where you expect it to appear.
For example, on my site I separate each chunk of text into a <div class="box"> which are all present in the <body> of the document. So if I wanted to match only the first <h1> in the document, I could do something like this:
body > .box:first-child > h1:first-of-type { }
This would select the first box only, and then match the first <h1> in that box, simulating the "first <h1> in the document" effect (assuming the first box has an <h1>, which on my website is always true if one exists). I assume you wanted to use the :first-of-type selector here, because the first <h1> in a document doesn't necessarily have to be the first child of a parent.
are you allowed to cheat with jQuery? some times jQuery (javascript) provide(s) elegant alternatives beyond the html and css limitations
$(document).ready(function() {
$('body').find('h1:first').css('color','#0000ff');
}); // ready
That will match every h1 that is the first child of its immediate parent. so if you have like
<div>
<h1></h1>
</div>
<div>
<h1></h1>
</div>
both of those h1 tags are first-children.
Try h1:first

Is there a CSS selector by class prefix?

I want to apply a CSS rule to any element whose one of the classes matches specified prefix.
E.g. I want a rule that will apply to div that has class that starts with status- (A and C, but not B in following snippet):
<div id='A' class='foo-class status-important bar-class'></div>
<div id='B' class='foo-class bar-class'></div>
<div id='C' class='foo-class status-low-priority bar-class'></div>
Some sort of combination of:
div[class|=status] and div[class~=status-]
Is it doable under CSS 2.1? Is it doable under any CSS spec?
Note: I do know I can use jQuery to emulate that.
It's not doable with CSS2.1, but it is possible with CSS3 attribute substring-matching selectors (which are supported in IE7+):
div[class^="status-"], div[class*=" status-"]
Notice the space character in the second attribute selector. This picks up div elements whose class attribute meets either of these conditions:
[class^="status-"] — starts with "status-"
[class*=" status-"] — contains the substring "status-" occurring directly after a space character. Class names are separated by whitespace per the HTML spec, hence the significant space character. This checks any other classes after the first if multiple classes are specified, and adds a bonus of checking the first class in case the attribute value is space-padded (which can happen with some applications that output class attributes dynamically).
Naturally, this also works in jQuery, as demonstrated here.
The reason you need to combine two attribute selectors as described above is because an attribute selector such as [class*="status-"] will match the following element, which may be undesirable:
<div id='D' class='foo-class foo-status-bar bar-class'></div>
If you can ensure that such a scenario will never happen, then you are free to use such a selector for the sake of simplicity. However, the combination above is much more robust.
If you have control over the HTML source or the application generating the markup, it may be simpler to just make the status- prefix its own status class instead as Gumbo suggests.
CSS Attribute selectors will allow you to check attributes for a string. (in this case - a class-name)
https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
(looks like it's actually at 'recommendation' status for 2.1 and 3)
Here's an outline of how I *think it works:
[ ] : is the container for complex selectors if you will...
class : 'class' is the attribute you are looking at in this case.
* : modifier(if any): in this case - "wildcard" indicates you're looking for ANY match.
test- : the value (assuming there is one) of the attribute - that contains the string "test-" (which could be anything)
So, for example:
[class*='test-'] {
color: red;
}
You could be more specific if you have good reason, with the element too
ul[class*='test-'] > li { ... }
I've tried to find edge cases, but I see no need to use a combination of ^ and * - as * gets everything...
example: http://codepen.io/sheriffderek/pen/MaaBwp
http://caniuse.com/#feat=css-sel2
Everything above IE6 will happily obey. : )
note that:
[class] { ... }
Will select anything with a class...
This is not possible with CSS selectors. But you could use two classes instead of one, e.g. status and important instead of status-important.
You can't do this no. There is one attribute selector that matches exactly or partial until a - sign, but it wouldn't work here because you have multiple attributes. If the class name you are looking for would always be first, you could do this:
<html>
<head>
<title>Test Page</title>
<style type="text/css">
div[class|=status] { background-color:red; }
</style>
</head>
<body>
<div id='A' class='status-important bar-class'>A</div>
<div id='B' class='bar-class'>B</div>
<div id='C' class='status-low-priority bar-class'>C</div>
</body>
</html>
Note that this is just to point out which CSS attribute selector is the closest, it is not recommended to assume class names will always be in front since javascript could manipulate the attribute.

Resources