How to refactor input placeholder class? - html

I have this HTML:
<input type="text" class="example" placeholder="Example"><br><br>
<input type="text" class="example" placeholder="Example"><br><br>
<input type="text" class="example" placeholder="Example"><br><br>
<input type="text"><br><br>
<input type="text"><br><br>
<input type="text"><br><br>
When I use this CSS, it works (https://jsfiddle.net/sv1sqgq4/1/):
.example::-webkit-input-placeholder {
color: red;
}
.example:-moz-placeholder {
color: red;
}
.example::-moz-placeholder {
color: red;
}
.example:-ms-input-placeholder {
color: red;
}
But, when I do it like this, it's not working (https://jsfiddle.net/sv1sqgq4/):
.example::-webkit-input-placeholder,
.example:-moz-placeholder,
.example::-moz-placeholder,
.example:-ms-input-placeholder {
color: red;
}
How do I refactor this CSS? Am I missing something?

tl;dr: the classes with those pseudo-selectors have to be seperate.
Explanation:
Refactoring the CSS in that way is not possible. It has to do with the way the pseudo elements for the specific vendors work. Since one vendor's browser doesn't "get" the prefixes of the other browsers, it disregards any rules that contain unrecognized prefixes in pseudo-class/element selectors.
From the docs:
4.1.7 Rule sets, declaration blocks, and selectors
When a user agent cannot parse the selector (i.e., it is not valid CSS
2.1), it must ignore the selector and the following declaration block (if any) as well. CSS 2.1 gives a special meaning to the comma (,) in
selectors. However, since it is not known if the comma may acquire
other meanings in future updates of CSS, the whole statement should be
ignored if there is an error anywhere in the selector, even though the
rest of the selector may look reasonable in CSS 2.1.

Please see reason here :
Why isn't it possible to combine vendor-specific pseudo-elements/classes into one rule set?

Related

Input checkbox supposedly not set as read-only but css selector picking up styling as if it were read-only [duplicate]

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"]) {
}

Why is :read-only CSS pseudo-class being applied on this checkbox?

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"]) {
}

Apply default class to all types of *n*

Is there a way to apply a class by default to an element? Let's say for example I wanted to apply the class foo to all input elements:
.foo { ... }
My limited knowledge leads me to believe I need to mark that up every single time:
<input type='text' class='foo' />
<input type='password' class='foo' />
...
But, clearly I was hoping I could apply that class by default to all input elements in the CSS somehow. I look forward to your answers!
UPDATE
In an attempt to clarify myself, I do not want to duplicate the CSS that already exists for foo because I wouldn't want to have to change that in multiple places if I needed to change the style for foo. Further, I will be applying it to more than just all input elements.
If you mean you want to take all the styles in your .foo rule and apply them to inputs as well, just select both of them:
.foo, input { ... }
You can add a class to elements easily using a framework like jQuery:
$(document).ready(function() {
$('input').addClass('foo');
});
EDIT: To address your latest update...
If you want to "extend" a class for only certain conditions, you can add a second class for that case... e.g.:
<input class="foo bar" />
<style type="text/css">
.foo.bar {
color: #123;
}
</style>
This will only apply your elements that are both .foo and .bar, and won't affect global .foo styles, which will still be applied to all .foo elements (including these)
You could use javascript's document.getElementsByTagName(tag); function.
Example:
var tags = document.getElementsByTagName("input");
for(i = 0;i<tags.length;i++){
tags[i].className = "foo";
}
If you want to keep the current classes on it just make sure to do if(tags[i].className != ""){tags[i].className = tags[i].className + " foo";}. It'll carry over the current classes.
You might try looking into a stylesheet preprocessor like LESS or SASS. These will allow you to use variables and other tricks here and there to help you avoid duplicating CSS. There are Javascript implementations of these as well as server-side ones if you would like to process it before giving it to the user.
Of course, the CSS ends up with duplicate code anyway, but you wouldn't have to write the same thing twice yourself.
For example, in LESS:
.foo {
color: #222222;
padding: 10px;
}
input {
.foo;
}
input[type=text]{
color:#123;
}
this is the code to apply css

Overriding IE default CSS for disabled inputs

IE 7 applies its own font color to disabled inputs. How can I override this and set my own font color?
IE7 supports the [attr] selector, so you can simply use:
input[disabled]
{
color: red;
}
This may cause issues with DHTML (you'll have to try it), in which case you may want to additionally set a class when working on dynamic elements:
input.disabled,
input[disabled]
{
color: red;
}
Note that [attr] is the "has attribute" selector, there are a bunch of other selectors in the CSS spec. Because disabled is a boolean attribute, you only have to check for its existence rather than any particular value.
Give your input a class and add the styling via css.
Html:
<input class="dis" disabled="disabled" value="something"></input>
CSS
.dis{color:red;}
Working Example: http://jsfiddle.net/TQUhD/1
As Diodeus comments :disabled is not supported in IE: http://reference.sitepoint.com/css/pseudoclass-disabled
There is no style for disabled. CSS3 supports :disabled, but IE7 doesn't.
kmb385's suggestion is probably the best you can do.
No need to overrride CSS use class based approach and play with events works perfectly
You can do one thing:
<button class="disabled" onmousedown="return checkDisable();" >
function checkDisable() {
if($(this).hasClass('disabled') { return false;}
}

CSS Input Type Selectors - Possible to have an "or" or "not" syntax?

If they exist in programming),
If I have an HTML form with the following inputs:
<input type="text" />
<input type="password" />
<input type="checkbox" />
I want to apply a style to all inputs that are either type="text" or type="password".
Alternatively, I would settle for all input's where type != "checkbox".
It seems like I to have to do this:
input[type='text'], input[type='password']
{
// my css
}
Isn't there a way to do:
input[type='text',type='password']
{
// my css
}
or
input[type!='checkbox']
{
// my css
}
I had a look around, and it doesn't seem like there is a way to do this with a single CSS selector.
Not a big deal of course, but I'm just a curious cat.
Any ideas?
CSS3 has a pseudo-class called :not()
input:not([type='checkbox']) {
visibility: hidden;
}
<p>If <code>:not()</code> is supported, you'll only see the checkbox.</p>
<ul>
<li>text: (<input type="text">)</li>
<li>password (<input type="password">)</li>
<li>checkbox (<input type="checkbox">)</li>
</ul>
Multiple selectors
As Vincent mentioned, it's possible to string multiple :not()s together:
input:not([type='checkbox']):not([type='submit'])
CSS4, which is supported in many of the latest browser releases, allows multiple selectors in a :not()
input:not([type='checkbox'],[type='submit'])
Legacy support
All modern browsers support the CSS3 syntax. At the time this question was asked, we needed a fall-back for IE7 and IE8. One option was to use a polyfill like IE9.js. Another was to exploit the cascade in CSS:
input {
// styles for most inputs
}
input[type=checkbox] {
// revert back to the original style
}
input.checkbox {
// for completeness, this would have worked even in IE3!
}
input[type='text'], input[type='password']
{
// my css
}
That is the correct way to do it. Sadly CSS is not a programming language.