I need to know how to make an empty-non-required input element invalid.
For example:
<input pattern="[0-9]+" title="" />
This field is :valid by default, as is not required. I need to turn it :invalid if it is empty.
Thank you all in advance. Cheers.
EDIT:
HTML:
<div>
<input type="text" name="Country" pattern="[a-zA-Z ]+" title="" placeholder="Country" />
Toggle
</div>
CSS:
input:valid + a
{
color: blue;
}
The <a> starts blue since there is no text inside the <input> which is not required.
The pseudo-class :valid state for an empty-non-required <input> element is true.
I need the <a> to remain uncolored when the <input> field is empty.
You need to add the attribute required, which has the same (limited, but growing) browser support as the pattern attribute. There is no way to make an “empty non-required” element invalid, because the required attribute means that the value must be non-empty.
The description of the pattern attribute in HTML5 CR says the attribute is used in constraint validation only if the value is not empty. This could also be said so that an empty string is always regarded as matching the pattern (but it really isn’t even checked against it).
This answer addresses the clarified/modified question, which seems to be about styling. An input element cannot match the selector :invalid if its value is empty, since such an element is exempted from constraint validation (as explained in my first answer). There is no selector for checking that the value of an input element is empty or non-empty. (The :empty pseudo-class tests for the content being empty, and an input element always has empty content.)
So this cannot be done in CSS (alone). You can use JavaScript e.g. so that any input operation causes the input element value to be checked. If the value is nonempty, put the input element to a class, say ok. Modify the CSS selector accordingly.
<style>
input:valid + a.ok {
color: blue;
}
</style>
<input ... oninput=check(this)>
...
<script>
function check(el) {
el.nextElementSibling.className = el.value ? 'ok' : '';
}
This works in sufficiently modern browsers. If wider browser coverage is needed, you may need to add event attributes like onkeypress and onpaste etc. that are used to run the same check. (And nextElementSibling might need to be replaced by some clumsier way of getting at the next element.)
Update, as per the comment below, you can simplify the code somewhat by setting the class on the input element rather than the a element. This means that the CSS selector would be input:valid.ok + a and the JavaScript assignment statement would have just el.className as the left-hand side. Regarding browser coverage, it’s probably not an issue here as compared with the basic restriction caused by the use of the :valid pseudo-class, which isn’t supported by IE 9 and earlier.
Related
I have the following SCSS code:
input[type="checkbox"] {
...
&:read-only, &[readonly] {
cursor: default;
filter: grayscale(1);
}
}
That is being applied to
<input type="checkbox" id="checkbox" onChange={this.rememberMe} />
Following MDN: :read-only documentation:
it will select any element that cannot be edited by the user.
Why is it being applied on my input that is editable?
The problem is applicable both to Firefox and Chrome.
Because <input type="checkbox" /> and <input type="radio" /> (and most other elements) are inherently read-only.
Unlike an <input type="text" /> or <input type="date" />, when you interact with (i.e. toggle) a checkbox or radio button you are not changing its value, you are changing its checked state.
Yes, I agree it's counter-intuitive.
Consequently...
You should not apply the <input readonly attribute to a radio or checkbox for any purpose.
Because it won't do anything useful.
You should not define a CSS selector that uses the :read-only pseudo-class to select <input> elements that have an explicit HTML <input readonly attribute set.
Instead use the has-attribute-selector: input[readonly].
It's probably a good idea just to avoid using the :read-only pseudo-class entirely because it also selects pretty-much every HTML element on the page too; a function with little practical utility, imo.
From the current WHATWG HTML specification (emphasis mine, especially the last point):
https://html.spec.whatwg.org/multipage/semantics-other.html#selector-read-only
The :read-write pseudo-class must match any element falling into one of the following categories, which for the purposes of Selectors are thus considered user-alterable: [SELECTORS]
<input> elements to which the <input readonly attribute applies, and that are mutable (i.e. that do not have the <input readonly attribute specified and that are not <input disabled).
<textarea> elements that do not have a <textarea readonly attribute, and that are not <textarea disabled.
elements that are editing hosts or editable and are neither <input> elements nor <textarea> elements.
[i.e. contenteditable]
The :read-only pseudo-class must match all other HTML elements.
Now, if you want a "read-only checkbox/radio" then you don't have too many good options, unfortunately; instead you have a mix of terrible options and barely-adequate ones...:
There is this popular QA, however most of the highest-voted answers have suggestions that I think are bad ideas: such as depending upon a client-script to block user-interaction ...very imperfectly (from people who are ignorant of the fact a radio and checkbox can be manipulated in far, far more many ways than just onclick), or using CSS's pointer-events: none; while completely disregarding the fact that computer keyboards both exist and are regularly used by human computer operators.
The least worst suggestion, I think, is using <input type="checkbox/radio" disabled />, as demonstrated with this answer. (The <input type="hidden"> is necessary because disabled (and unchecked) inputs are not submitted, which is another violation of the principle of least astonishment by the then-nascent browser vendors of the late-1990s.
If you want to use the :read-only pseudo-class on all input elements except radio and checkboxes then you need to think carefully (and test it too, using variations on document.querySeletorAll("input:read-only") in your browser's console!)
I recommend that you do not apply any styles using selectors for input elements without also explicitly specifying the [type=""] attribute selector - this is because styles with a selector like "input" (without any attribute-selectors) will be applied to future HTML input elements that we don't know about yet and could be introduced at any point in the near-future, and maybe next week Google Chrome adds a new <input type="human-dna-sample" /> or Microsoft adds <input type="clippy" /> to a particularly retro edition of their Edge browser - so you definitely don't want a :read-only style applied to those elements until you at least know how it will look and work - and so the browser will use its default/native styling which won't violate your users/visitor's expectations if they happen to come across it on your website at some point.
...so it means you need to write out rules for every known <input type="..."> as repetitive input[type=""] style rules, and now you might wonder if there were any pseudo-classes for input elements based on their default native appearance because a lot of them sure do look share similar, if not identical, native appearance and visual-semantics (and shadow DOM structure, if applicable) - for example in desktop Chrome the input types text, password, email, search, url, tel and more are all clearly built around the same native textbox widget, so there surely must be a pseudo-class for different input "kinds", right? Something like input:textbox-kind for text, password, etc and input:checkbox-kind for checkbox and radio - unfortunately such a thing doesn't exist and if introduced tomorrow the W3C's CSS committee probably wouldn't approve it for a few more years at least - so until then we need to explicitly enumerate every input[type=""] that we know about so that we can accurately anticipate how browsers will render them with our type=""-specific style rules instead of throwing everything as input {} and seeing what sticks.
...fortunately the list isn't too long, so I just wrote the rules out just now:
Feel free to copy + paste this; it's hardly even copyrightable. And I want to see how far this spreads across the Internet in my lifetime.
At the bottom is a CSS selector that will select only <input elements that are from the future by using an exhaustive set of :not([type="..."]) selectors, as well as not matching input elements with an empty type="" attribute or missing one entirely.
/* Textbox-kind: */
input[type="text"]:read-only,
input[type="password"]:read-only,
input[type="search"]:read-only,
input[type="tel"]:read-only,
input[type="url"]:read-only,
input[type="email"]:read-only,
input[type="number"]:read-only {
background-color: #ccc;
cursor: 'not-allowed';
}
/* Date/time pickers: */
input[type="date"]:read-only,
input[type="datetime-local"]:read-only,
input[type="time"]:read-only,
input[type="week"]:read-only,
input[type="month"]:read-only {
background-color: #ccc;
cursor: 'not-allowed';
}
/* Button-kind (these are all practically obsolete now btw, as the <button> element is far, far, far superior in every way) */
input[type="button"]:disabled,
input[type="reset"]:disabled,
input[type="submit"]:disabled,
input[type="image"]:disabled {
background-color: #ccc;
border: 1px outset #666;
cursor: 'not-allowed';
color: #666;
text-shadow: 0 1px rgba(255,255,255,0.2);
}
/* Checkbox-kind (Don't use `:read-only` with these): */
input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
/* I'm not setting any properties here because it's impossible to effectively style these elements without resorting to image-replacements using the `:checked` state in selectors for their parent or adjacent `<label>` or ::before/::after` of other proximate elements. */
}
/* Weird-stuff-kind: */
input[type="color"]:read-only,
input[type="file"]:read-only,
input[type="hidden"]:read-only,
input[type="range"]:read-only {
/* Again, due to differences in how different browsers and platforms display (and consequently style) these inputs I don't think it's worth doing anything. */
}
/* If you **really** want to select _future_ <input> elements in-advance... do this: */
input[type]:not([type="text"]):not([type="password"]):not([type="search"]):not([type="tel"]):not([type="url"]):not([type="email"]):not([type="number"]):not([type="date"]):not([type="datetime-local"]):not([type="time"]):not([type="week"]):not([type="month"]):not([type="button"]):not([type="reset"]):not([type="submit"]):not([type="image"]):not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]):not([type="hidden"]):not([type="range"]) {
}
I have the following SCSS code:
input[type="checkbox"] {
...
&:read-only, &[readonly] {
cursor: default;
filter: grayscale(1);
}
}
That is being applied to
<input type="checkbox" id="checkbox" onChange={this.rememberMe} />
Following MDN: :read-only documentation:
it will select any element that cannot be edited by the user.
Why is it being applied on my input that is editable?
The problem is applicable both to Firefox and Chrome.
Because <input type="checkbox" /> and <input type="radio" /> (and most other elements) are inherently read-only.
Unlike an <input type="text" /> or <input type="date" />, when you interact with (i.e. toggle) a checkbox or radio button you are not changing its value, you are changing its checked state.
Yes, I agree it's counter-intuitive.
Consequently...
You should not apply the <input readonly attribute to a radio or checkbox for any purpose.
Because it won't do anything useful.
You should not define a CSS selector that uses the :read-only pseudo-class to select <input> elements that have an explicit HTML <input readonly attribute set.
Instead use the has-attribute-selector: input[readonly].
It's probably a good idea just to avoid using the :read-only pseudo-class entirely because it also selects pretty-much every HTML element on the page too; a function with little practical utility, imo.
From the current WHATWG HTML specification (emphasis mine, especially the last point):
https://html.spec.whatwg.org/multipage/semantics-other.html#selector-read-only
The :read-write pseudo-class must match any element falling into one of the following categories, which for the purposes of Selectors are thus considered user-alterable: [SELECTORS]
<input> elements to which the <input readonly attribute applies, and that are mutable (i.e. that do not have the <input readonly attribute specified and that are not <input disabled).
<textarea> elements that do not have a <textarea readonly attribute, and that are not <textarea disabled.
elements that are editing hosts or editable and are neither <input> elements nor <textarea> elements.
[i.e. contenteditable]
The :read-only pseudo-class must match all other HTML elements.
Now, if you want a "read-only checkbox/radio" then you don't have too many good options, unfortunately; instead you have a mix of terrible options and barely-adequate ones...:
There is this popular QA, however most of the highest-voted answers have suggestions that I think are bad ideas: such as depending upon a client-script to block user-interaction ...very imperfectly (from people who are ignorant of the fact a radio and checkbox can be manipulated in far, far more many ways than just onclick), or using CSS's pointer-events: none; while completely disregarding the fact that computer keyboards both exist and are regularly used by human computer operators.
The least worst suggestion, I think, is using <input type="checkbox/radio" disabled />, as demonstrated with this answer. (The <input type="hidden"> is necessary because disabled (and unchecked) inputs are not submitted, which is another violation of the principle of least astonishment by the then-nascent browser vendors of the late-1990s.
If you want to use the :read-only pseudo-class on all input elements except radio and checkboxes then you need to think carefully (and test it too, using variations on document.querySeletorAll("input:read-only") in your browser's console!)
I recommend that you do not apply any styles using selectors for input elements without also explicitly specifying the [type=""] attribute selector - this is because styles with a selector like "input" (without any attribute-selectors) will be applied to future HTML input elements that we don't know about yet and could be introduced at any point in the near-future, and maybe next week Google Chrome adds a new <input type="human-dna-sample" /> or Microsoft adds <input type="clippy" /> to a particularly retro edition of their Edge browser - so you definitely don't want a :read-only style applied to those elements until you at least know how it will look and work - and so the browser will use its default/native styling which won't violate your users/visitor's expectations if they happen to come across it on your website at some point.
...so it means you need to write out rules for every known <input type="..."> as repetitive input[type=""] style rules, and now you might wonder if there were any pseudo-classes for input elements based on their default native appearance because a lot of them sure do look share similar, if not identical, native appearance and visual-semantics (and shadow DOM structure, if applicable) - for example in desktop Chrome the input types text, password, email, search, url, tel and more are all clearly built around the same native textbox widget, so there surely must be a pseudo-class for different input "kinds", right? Something like input:textbox-kind for text, password, etc and input:checkbox-kind for checkbox and radio - unfortunately such a thing doesn't exist and if introduced tomorrow the W3C's CSS committee probably wouldn't approve it for a few more years at least - so until then we need to explicitly enumerate every input[type=""] that we know about so that we can accurately anticipate how browsers will render them with our type=""-specific style rules instead of throwing everything as input {} and seeing what sticks.
...fortunately the list isn't too long, so I just wrote the rules out just now:
Feel free to copy + paste this; it's hardly even copyrightable. And I want to see how far this spreads across the Internet in my lifetime.
At the bottom is a CSS selector that will select only <input elements that are from the future by using an exhaustive set of :not([type="..."]) selectors, as well as not matching input elements with an empty type="" attribute or missing one entirely.
/* Textbox-kind: */
input[type="text"]:read-only,
input[type="password"]:read-only,
input[type="search"]:read-only,
input[type="tel"]:read-only,
input[type="url"]:read-only,
input[type="email"]:read-only,
input[type="number"]:read-only {
background-color: #ccc;
cursor: 'not-allowed';
}
/* Date/time pickers: */
input[type="date"]:read-only,
input[type="datetime-local"]:read-only,
input[type="time"]:read-only,
input[type="week"]:read-only,
input[type="month"]:read-only {
background-color: #ccc;
cursor: 'not-allowed';
}
/* Button-kind (these are all practically obsolete now btw, as the <button> element is far, far, far superior in every way) */
input[type="button"]:disabled,
input[type="reset"]:disabled,
input[type="submit"]:disabled,
input[type="image"]:disabled {
background-color: #ccc;
border: 1px outset #666;
cursor: 'not-allowed';
color: #666;
text-shadow: 0 1px rgba(255,255,255,0.2);
}
/* Checkbox-kind (Don't use `:read-only` with these): */
input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
/* I'm not setting any properties here because it's impossible to effectively style these elements without resorting to image-replacements using the `:checked` state in selectors for their parent or adjacent `<label>` or ::before/::after` of other proximate elements. */
}
/* Weird-stuff-kind: */
input[type="color"]:read-only,
input[type="file"]:read-only,
input[type="hidden"]:read-only,
input[type="range"]:read-only {
/* Again, due to differences in how different browsers and platforms display (and consequently style) these inputs I don't think it's worth doing anything. */
}
/* If you **really** want to select _future_ <input> elements in-advance... do this: */
input[type]:not([type="text"]):not([type="password"]):not([type="search"]):not([type="tel"]):not([type="url"]):not([type="email"]):not([type="number"]):not([type="date"]):not([type="datetime-local"]):not([type="time"]):not([type="week"]):not([type="month"]):not([type="button"]):not([type="reset"]):not([type="submit"]):not([type="image"]):not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]):not([type="hidden"]):not([type="range"]) {
}
I have an HTML page that is way too junky, so I am trying to trim it down.
I always put type='text' on my inputs, when they are text inputs:
<input type="text" />
However, it doesn't seem that browsers strictly require that.
Is omitting this attribute where it is text considered bad practice?
The type attribute has always been optional, defaulting to text, in all HTML specifications (which start from HTML 2.0) and in all implementations. It is thus safe to omit it, and of course equally safe to include it, when you want to have a text input field.
In the DOM, <input> and <input type=text>, have the same representation (including the presence of a type property of the element node, with the value 'text'), except that only in the latter case the attributes property contains type. So any JavaScript processing that needs the type property works just the same.
It is a matter of opinion and taste whether it is useful to include it for symmetry with other input elements or for explicitness, so that a person reading HTML source will immediately see that we have a text input field, without needing to scan a possibly long list of attributes to see that no type attribute is present.
However, there is a technical difference that may matter, possibly making it advantageous to use the type=text attribute. In CSS, the selector input[type=text] matches only elements that have the attribute type=text explicitly set. If such attributes are used consistently, you can thus set styling properties for text input fields without affecting any other input fields. Otherwise you need a more complicated selector.
To answer to this question we can refer to:
HTML4 SPEC 17.4 The INPUT element
type =
text|password|checkbox|radio|submit|reset|file|hidden|image|button
[CI] This attribute specifies the type of control to create. The
default value for this attribute is "text".
The HTML5 Spec 4.10.5 The input element
The type attribute controls the data type (and associated control) of
the element. It is an enumerated attribute. The missing value default
is the Text state.
So, omitting the attribute is not considerable a bad practice
text is the default value for an input tag's type attribute in most if not all modern browsers. However, it isn't considered a "bad practice" to leave it off, only /good/ practice to include it.
If you are looking at modern browsers, they will surely handle it. But if your users are using older browsers (specially IE-older ones) then gods know what will happen. ;)
I read from this site [Site]: http://msdn.microsoft.com/en-us/library/windows/apps/hh968006.aspx
that aria-multiline is to provide the multi line attribute.
But when i applied to textbox, it doesn't seem to work. Can anyone please tell why. I have one more question, can anyone please tell me the difference between these two elements
<textarea rows="4" cols="50" id="text"></textarea>
<textarea rows="4" cols="50" aria-labelledby="aria-text-label" id="aria-text" role="textbox" aria-multiline="true"></textarea>
Thanks
ARIA attributes are declarative (informative). They inform browsers and especially assistive software what functional properties elements have, mainly due to JavaScript code that processes them, instead of making elements have functional properties. For example, if you used JavaScript to make a div element a multi-line input area, it would be appropriate to set aria-multiline="true" on that element. See the W3C WAI Primer.
Thus, the attribute is redundant for textarea (browsers can be expected to know what that element is). For input type="text" it could be used, but only if you have somehow managed to turn it to a multiline control.
The differences between the two elements presented in the question are:
They assign different id attribute values.
The latter declares a role attribute, which matches the default semantics and is not recommended in Using WAI-ARIA in HTML. (It is allowed, but it may confuse people who read the HTML source and mislead them into thinking that it has some effect.)
It also redundantly declares the element as multiline.
It additionally specifies that the element has a label, which is an element with id="aria-text-label". This is not redundant, but it is normally better, more accessible, to have the label declared in normal HTML markup, using the label element.
Have you read Remarks part of your link? Since textarea is multiline by default, so setting aria-multiline="true" will have no efect. This attribute sets what ENTER key do. In textarea and when aria-multiline="true" it will continue input to second row. But if you set aria-multiline="false" for textarea, it will act as <input type="text"/> - it will submit form on Enter key press and will not jump to second row.
Is there any way to allow a link/anchor within an input field so that whatever text is in the field is ALSO clickable and actionable?
This is unfortunately not possible in HTML 4 or below. Even with HTML5 which has several new INPUT TYPEs, including URL, it only does validation and has some other useful functions, but won't give you want you want.
You might look for some jQuery plugins that can help you do this, most use the same principals behind Rich Text or other online/web-based HTML WYSIWYG editors. I've had trouble locating them myself.
These 3 situations (that I can think of right now) are pretty much what you will face natively with HTML4 or below, as text in an actual HTML4 INPUT textbox is pure text. It is not html and therefore NOT clickable. Here are some variations:
The INPUT tag's VALUE attribute, also referenced as the corresponding DOM object's "value" property (which is basically what you've been doing, and the most you can hope for, if you decide that you MUST have the text that's ACTUALLY inside the textbox (because the text inside the textbox is the VALUE attribute, as I have it with "http://yahoo.com" in this example):
<input id="myTxtbox" type="text" value="http://yahoo.com">
where the INPUT's VALUE = "http://yahoo.com", which you can retrieve with:
in pure javascript:
document.getElementById("myTxtbox").value
in jQuery:
$("myTxtBox").val()
When your link/url is the text in between the <INPUT> and </INPUT>, i.e. the text/innerText of the textbox. This is useless for your question/scenario since it's not clickable, and more importantly NOT INSIDE the textbox. However, someone might want to use this to retrieve any text that you may be using as a label (if you're not using the <label> tag itself already that is):
<input id="myTxtbox" type="text">
http://yahoo.com
</input>
The textbox's text/innerText is NOT an attribute here, only a DOM object property, but can still be retrieved:
pure javascript:
document.getElementById("myTxtbox").innerText
jQuery:
$("myTxtBox").text() -- you would use this to capure any text that you may be using as a label (if you're not using the tag).
The result being: http://yahoo.com
When your link/url is the form of an ANCHOR (<A>) with an HREF to your url (and visible link text) in between the <INPUT> and </INPUT>, i.e. the innerHTML of the textbox. This is getting a bit closer to what you want, as the link will appear as, and function as an actual link. However, it will NOT be inside of the textbox. It will be along side it as in example #2. Again, as stated in example #1, you CANNOT have actual working HTML, and therefore a working 'link' inside of a textbox:
<input id="myTxtbox" type="text">
<a href="http://yahoo.com">
http://yahoo.com
</a>
</input>
Once again, similarly to example #2, the textbox's innerHTML is NOT an attribute here, only a DOM object property, but can still be retrieved:
pure javascript:
document.getElementById("myTxtbox").innerHTML
jQuery:
$("myTxtBox").html()
The result being: http://yahoo.com