No need for selecting by partial attribute? - html

If
.animal {background: yellow}
will apply the styling rule to any elements with a class containing the word animal, even if it also contains other words eg...
<li class="toy animal">Toy Bear</li>
then what is the need for the below syntax for selecting by partial attribute?
*[class~="animal"] {background: yellow}
Thanks

The only difference is, you can use .value syntax only for classes, when [attribute~="value"] can be used to match any attribute values.
But when you use [class~="className"] to match class attribute values, it is equivalent to standard .className syntax.

According to the selectors spec, the period . is an alternative for the ~= notation for the class attribute.
Thus, for HTML, div.value and div[class~=value] have the same meaning
Just to clarify the ~= meaning:
E[foo~="bar"] an E element whose "foo" attribute value is a list of whitespace-separated values, one of which is exactly equal to "bar"
Note that this is different than *=
In other words, .animal and [class~=animal] (without the *) are the same.

Related

Targeting a class value that begins with a space

I want to make a CSS selector for a class which starts with a whitespace, but I don't know how. For example: <table class=" example">…</table>.
Any leading or trailing spaces in the value of a class attribute are meaningless for targeting purposes. This: class=" example" is equivalent to this: class="example".
There is no need for a special selector that factors in the space.
From the HTML 5 spec:
2.4.7 Space-separated
tokens
A string containing a set of space-separated tokens may have leading
or trailing space characters.
Space characters are necessary, however, for separating multiple values in a class attribute.
3.2.5.7 The class
attribute
The attribute, if specified, must have a value that is a set of
space-separated tokens representing the various classes that the
element belongs to.
CSS classnames are single words; spaces just separate different classnames.
You want .example.
Whitespace at the start and end of a value for the class attribute is insignificant for the purposes of class selectors. class=" example" is valid HTML and equivalent to class="example", class="example " and even class=" example " for the purposes of the .example class selector.
Therefore the selector you're looking for is simply .example.
The only situation where it makes a difference in selectors is with attribute selectors: [class~="example"] will match all of the given examples, but [class="example"] will only match class="example". (This means, consequently, that if you have some esoteric reason to want to match the element only when its class attribute has a leading space, you can use either [class^=" example"] or [class=" example"], but you most likely just want a regular class selector.)

Can I have multiple values in one HTML "data-" element?

Can I have multiple values in one HTML "data-" element? Similar to how a class can have multiple class names.
If possible, I would like to create a CSS/JS library that makes use of one "data-" element to house all of the library styles. For example:
<div data-library-name="xs-hidden col-md-10 col-xl-8 big-hero"></div>
That way, any of the programmers custom style rules can go into the elements class. My reasoning for this is to make readability easier, so together it would look like:
<div class="custom-style another-style" data-library-name="xs-hidden col-md-10 col-xl-8 big-hero"></div>
Can I have multiple values in one HTML "data-" element?
You can have a string. The spec doesn't define any particular format for the data in the attribute, which is designed to be processed by site specific JavaScript.
Similar to how a class can have multiple class names.
The class attribute takes a space separated list of classes.
Your JavaScript can your_data_attribute_value.split(" "); if you like.
Handling this with CSS would use the ~= attribute selector.
[att~=val]
Represents an element with the att attribute whose value is a whitespace-separated list of words, one of which is exactly "val". If "val" contains whitespace, it will never represent anything (since the words are separated by spaces). Also if "val" is the empty string, it will never represent anything.
AFAIK, I don't think data- attributes can convert that to an array. Instead, I think it'll interpret it as one value, but it is allowed.
If you want to do that, you'll probably have to split() it later in JavaScript into an array of usable values.
See this example on JSFiddle.net.
CSS has the shortcut .class selector but it actually is parsing the attribute named "class" as a list for space separated values. This is supported in the non-shortcut form by the following attribute selector:
[att~=val]
Represents an element with the att attribute whose value is a white space-separated list of words, one of which is exactly "val". If "val" contains white space, it will never represent anything (since the words are separated by spaces). If "val" is the empty string, it will never represent anything either.
Ref: http://www.w3.org/TR/CSS2/selector.html#class-html
As your question is tagged CSS you're perhaps looking for that. The rules how the parsing of attribute values is done is given in that document as well, so in case the javascript library you're trying to use on this (if any) won't cover that, it should be easy to add:
var list = $("div").data("library-name").split(/\s+/);
^^^^^^^^^^^^
This split with the white-space regular expression parses the string attribute value into an array with javascript and the Jquery library (for accessing the DOM and the data attribute).

CSS Target Attribute Containing Partial Match

Using the following CSS, why am I not able to target the 3 following anchor tags?
a[href~="checkout"] { /* Do something. */ }
<a href="http://shop.mydomain.com/checkout/onepage/">
<a href="https://shop.mydomain.com/checkout/onepage/">
<a href="https://shop.mydomain.com/checkout/onepage/?___SID=S">
What am I doing wrong in my CSS selector? I'm trying to select a partial match using ~= for all URLs containing the word "checkout."
Try this
a[href*="checkout"] { /* Do something. */ }
You have to use *, which means contain - see reference.
Also, don't forget to close anchor tags
</a>
Working JSFiddle
a[href~="checkout"]
matches elements where in a whitespace-separated list of words one of these is exactly "checkout".
See W3C Docs for Selectors Level 3:
[att~=val]
Represents an element with the att attribute whose value is
a whitespace-separated list of words, one of which is exactly "val".
If "val" contains whitespace, it will never represent anything (since
the words are separated by spaces). Also if "val" is the empty string,
it will never represent anything.
Source: http://www.w3.org/TR/css3-selectors/#attribute-selectors
If you want to match all elements where attr contains string, use
[attr*=string]

CSS substring matching attribute selectors: Contains multiple class names

A CSS "contains" selector is
td[class*="foo"]
I can select multiple classes with
td[class*="foo bar"]
This however will fail for <td class="foo baz bar" />
How can I do a CSS "contains" wildcard select?
BTW: I cannot use td.foo.bar
The selector you're looking for is as follows, see this question for more details.
td[class*="foo"][class*="bar"]
However, if you need to use selectors like that then it's often a sign that your class name logic is bad.
Honestly I don't know what you mean by "failing" td[class*="foo bar"] selector as it seems working to me in your particular case.
However, since the class names are separated by white spaces, you could use multiple [attr~=value] attribute selectors to select the elements having the classes as follows:
td[class~="foo"][class~="baz"] {
background-color: gold;
}
WORKING DEMO.
From the MDN:
[attr~=value] Represents an element with an attribute name of attr
whose value is a whitespace-separated list of words, one of which is
exactly "value".
Visit : CSS-Tricks (CSS Attribute Selectors)
From the above for finding a match of a given string to the string in the class specified according to your question , the only option I find working and correct is * and ~.
1. Demo for *
2. Demo for ~
Multiple attribute matches

How exactly is [att~=val] different from [att*=val] in CSS Attribute Selectors?

Maybe I am missing something, but they seem similar. If you use for example...
a[alt~="thumb"]
or...
a[alt*="thumb"]
What can I narrow my selection down to differently? I am at the understanding that ~ gives you a partial match in the quotes while the * gives you a partial match. I am going to fiddle with the code a little, but since I could not find a question on the subject here, thought it would make a good topic either way.
From the JQuery help (which supports the standard selectors):
a[alt~="thumb"]
Description: Selects elements that have the specified attribute with a
value containing a given word, delimited by spaces. This selector
matches the test string against each word in the attribute value,
where a "word" is defined as a string delimited by whitespace. The
selector matches if the test string is exactly equal to any of the
words.
a[alt*="thumb"]
Description: Selects elements that have the specified attribute with a
value containing the a given substring. This is the most generous of
the jQuery attribute selectors that match against a value. It will
select an element if the selector's string appears anywhere within the
element's attribute value. Compare this selector with the Attribute
Contains Word selector (e.g. [attr~="word"]), which is more
appropriate in many cases.
Basically the selector ~= only matches if the value is found surrounded by white space. The selector *= matches if the value is found anywhere.
<div alt='heading navigation'>
<div alt='head'>
div[alt~='head'] would match only the second div, but div[alt*='head'] would match both.
[att~=value] is a contains word selector.
So a [alt="foo"] selector will match <a alt="foo bar"> but will not match <a alt="foobar">.
[alt*="foo"] will match both though, because this doesn't discriminate on words or whatever. As long as it's in the value, it hits.