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).
Related
I was wondering if you can use a random letter as an html tag. Like, f isn't a tag, but I tried it in some code and it worked just like a span tag. Sorry if this is a bad question, I've just been curious about it for a while, and I couldn't find anything online.
I was wondering if you can use a random letter as an html tag.
Yes and no.
"Yes" - in that it works, but it isn't correct: when you have something like <z> it only works because the web (HTML+CSS+JS) has a degree of forwards compatibility built-in: browsers will render HTML elements that they don't recognize basically the same as a <span> (i.e. an inline element that doesn't do anything other than reify a range of the document's text).
However, to use HTML5 Custom Elements correctly you need to conform to the Custom Elements specification which states:
The name of a custom element must contain a dash (-). So <x-tags>, <my-element>, and <my-awesome-app> are all valid names, while <tabs> and <foo_bar> are not. This requirement is so the HTML parser can distinguish custom elements from regular elements. It also ensures forward compatibility when new tags are added to HTML.
So if you use <my-z> then you'll be fine.
The HTML Living Standard document, as of 2021-12-04, indeed makes an explicit reference to forward-compatibility in its list of requirements for custom element names:
https://html.spec.whatwg.org/#valid-custom-element-name
They start with an ASCII lower alpha, ensuring that the HTML parser will treat them as tags instead of as text.
They do not contain any ASCII upper alphas, ensuring that the user agent can always treat HTML elements ASCII-case-insensitively.
They contain a hyphen, used for namespacing and to ensure forward compatibility (since no elements will be added to HTML, SVG, or MathML with hyphen-containing local names in the future).
They can always be created with createElement() and createElementNS(), which have restrictions that go beyond the parser's.
Apart from these restrictions, a large variety of names is allowed, to give maximum flexibility for use cases like <math-α> or <emotion-😍>.
So, by example:
<a>, <q>, <b>, <i>, <u>, <p>, <s>
No: these single-letter elements are already used by HTML.
<z>
No: element names that don't contain a hyphen - cannot be custom elements and will be interpreted by present-day browsers as invalid/unrecognized markup that they will nevertheless (largely) treat the same as a <span> element.
<a:z>
No: using a colon to use an XML element namespace is not a thing in HTML5 unless you're using XHTML5.
<-z>
No - the element name must start with a lowercase ASCII character from a to z, so - is not allowed.
<a-z>
Yes - this is fine.
<a-> and <a-->
Unsure - these two names are curious:
The HTML spec says the name must match the grammar rule [a-z] (PCENChar)* '-' (PCENChar)*.
The * denotes "zero-or-more" which is odd, because that implies the hyphen doesn't need to be followed by another character.
PCENChar represents a huge range of visible characters permitted in element names, curiously this includes -, so by that rule <a--> should be valid.
But note that -- is a reserved character sequence in the greater SGML-family (including HTML and XML) which may cause weirdness. YMMV!
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.)
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]
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.
What's the point of the name attribute on an HTML form? As far as I can tell, you can't read the form name on submission or do anything else with it. Does it serve a purpose?
In short, and probably oversimplifying a bit: It is used instead of id for browsers that don't understand document.getElementById.
These days it serves no real purpose. It is a legacy from the early days of the browser wars before the use of name to describe how to send control values when a form is submitted and id to identify an element within the page was settled.
From the specification:
The name attribute represents the form's name within the forms collection.
Once you assign a name to an element, you can refer to that element via document.name_of_element throughout your code. It doesn't work to tell when you've got multiple fields of the same name, but it does allow shortcuts like:
<form name="myform" ...>
document.myform.submit();
instead of
document.getElementsByName('myform')[0].submit();
Here's what MDN has to say about it:
name
The name of the form. In HTML 4, its use is deprecated (id should be used instead). It must be unique among the forms in a document and not just an empty string in HTML 5.
(from <form>, Attributes, name)
I find it slightly confusing that specifies that it must be unique, non-empty string in HTML 5 when it was deprecated in HTML 4. (I'd guess that requirement only applies if the name attribute is specified at all?). But I think it's safe to say that any purpose it once served has been superseded by the id attribute.
You can use the name attribute as an "extra information" attribute - similarly as with a hidden input - but this keeps the extra information tied into the form, which makes it just a little simpler to read/access.
name attribute is not completely redundant vis-à-vis id. As aforementioned, it useful with <forms>, but less known is that it can also be used with with any HTMLCollection, such as the children property of any DOM element.
HTMLCollection, in additional to be a array-like object, will have named properties commensurate with any named members (or the first occurrence in case of non-unique name). It is useful to retrieve specific named nodes.
For example, in the following example HTML:
<div id='person1'>
<span name='firstname'>John</span>
<span name='lastname'>Doe</span>
<span name='middlename'></span>
</div>
<div id='person2'>
<span name='firstname'>Jane</span>
<span name='lastname'>Doe</span>
<span name='middlename'></span>
</div>
by naming each child, one can quickly and efficiently retrieve a named element, such as lastname, as such:
document.getElementById('person1').children.namedItem('lastname')
...and if there is no risk of 'length' being the name of a member element, (being that length is a reserved property of HTMLCollection), a more terse notation may be used instead:
document.getElementById('person1').children.lastname
DOM Living Standard 2019 March 29
An HTMLCollection object is a collection of elements...
The namedItem(key) method, when invoked, must run these steps:
If key is the empty string, return null.
Return the first element in the collection for which at least one of the following is true:
it has an ID which is key;
it is in the HTML namespace and has a name attribute whose value is key;