Is there any CSS selector that select changed element? - css

I want to select a text input element that has been changed or typed? is it possibe to do that? like
input:changed {
/* my own rule*/
}

I´ve created a jsfiddle for a solution with jquery, where I add a class to the element when the value in the input is changed: http://jsfiddle.net/aSX5A/ :
<input type="text" class="textinput" />
$('.textinput').change(function () {
$(this).addClass("changedInput");
});
Edit:
With pure javascript:
<input type="text" id="textinput" onchange="updateClass()"/>
<script>
function updateClass(){
document.getElementById("textinput").className = "changedInput";
}
</script>

you'd need to implement this with javascript somehow.
<input onkeydown="javascript:myFunctionToChangeState(this);" />
where myFunctionToChangeState() is a function you write that modifies the state of the element it is passed.

You are not being very specific but i guess this is what you need
input:focus {
/* your own rule*/
}

Related

CSS only input range to change background color [duplicate]

Is it possible to use a CSS selector to target an input that has a specific value?
Example: How can I target the input below based on the value="United States"
<input type="text" value="United States" />
Dynamic Values (oh no! D;)
As npup explains in his answer, a simple css rule will only target the attribute value which means that this doesn't cover the actual value of the html node.
JAVASCRIPT TO THE RESCUE!
Ugly workaround: http://jsfiddle.net/QmvHL/
Original Answer
Yes it's very possible, using css attribute selectors you can reference input's by their value in this sort of fashion:
input[value="United States"] { color: #F90; }​
• jsFiddle example
from the reference
[att] Match when the element sets the "att" attribute, whatever the
value of the attribute.
[att=val] Match when the element's "att"
attribute value is exactly "val".
[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.
[att|=val] Represents an element with the att
attribute, its value either being exactly "val" or beginning with
"val" immediately followed by "-" (U+002D). This is primarily intended
to allow language subcode matches (e.g., the hreflang attribute on the
a element in HTML) as described in BCP 47 ([BCP47]) or its successor.
For lang (or xml:lang) language subcode matching, please see the :lang
pseudo-class.
css attribute selectors reference
It is possible, if you're using a browser which supports the CSS :valid pseudo-class and the pattern validation attribute on inputs -- which includes most modern browsers except IE9.
For instance, to change the text of an input from black to green when the correct answer is entered:
input {
color: black;
}
input:valid {
color: green;
}
<p>Which country has fifty states?</p>
<input type="text" pattern="^United States$">
Yes, but note: since the attribute selector (of course) targets the element's attribute, not the DOM node's value property (elem.value), it will not update while the form field is being updated.
Otherwise (with some trickery) I think it could have been used to make a CSS-only substitute for the "placeholder" attribute/functionality. Maybe that's what the OP was after? :)
As mentioned before, you need more than a css selector because it doesn't access the stored value of the node, so javascript is definitely needed. Heres another possible solution:
<style>
input:not([value=""]){
border:2px solid red;
}
</style>
<input type="text" onkeyup="this.setAttribute('value', this.value);"/>
Sure, try:
input[value="United States"]{ color: red; }
jsFiddle example.
You can use Css3 attribute selector or attribute value selector.
/This will make all input whose value is defined to red/
input[value]{
color:red;
}
/This will make conditional selection depending on input value/
input[value="United States"]{
color:red;
}
There are other attribute selector like attribute contains value selector,
input[value="United S"]{
color: red;
}
This will still make any input with United state as red text.
Than we attribute value starts with selector
input[value^='united']{
color: red;
}
Any input text starts with 'united' will have font color red
And the last one is attribute value ends with selector
input[value$='States']{
color:red;
}
Any input value ends with 'States' will have font color red
Refreshing attribute on events is a better approach than scanning value every tenth of a second...
http://jsfiddle.net/yqdcsqzz/3/
inputElement.onchange = function()
{
this.setAttribute('value', this.value);
};
inputElement.onkeyup = function()
{
this.setAttribute('value', this.value);
};
In Chrome 72 (2019-02-09) I've discovered that the :in-range attribute is applied to empty date inputs, for some reason!
So this works for me: (I added the :not([max]):not([min]) selectors to avoid breaking date inputs that do have a range applied to them:
input[type=date]:not([max]):not([min]):in-range {
color: blue;
}
Screenshot:
Here's a runnable sample:
window.addEventListener( 'DOMContentLoaded', onLoad );
function onLoad() {
document.getElementById( 'date4' ).value = "2019-02-09";
document.getElementById( 'date5' ).value = null;
}
label {
display: block;
margin: 1em;
}
input[type=date]:not([max]):not([min]):in-range {
color: blue;
}
<label>
<input type="date" id="date1" />
Without HTML value=""
</label>
<label>
<input type="date" id="date2" value="2019-02-09" />
With HTML value=""
</label>
<label>
<input type="date" id="date3" />
Without HTML value="" but modified by user
</label>
<label>
<input type="date" id="date4" />
Without HTML value="" but set by script
</label>
<label>
<input type="date" id="date5" value="2019-02-09" />
With HTML value="" but cleared by script
</label>
Following the currently top voted answer, I've found using a dataset / data attribute works well.
//Javascript
const input1 = document.querySelector("#input1");
input1.value = "0.00";
input1.dataset.value = input1.value;
//dataset.value will set "data-value" on the input1 HTML element
//and will be used by CSS targetting the dataset attribute
document.querySelectorAll("input").forEach((input) => {
input.addEventListener("input", function() {
this.dataset.value = this.value;
console.log(this);
})
})
/*CSS*/
input[data-value="0.00"] {
color: red;
}
<!--HTML-->
<div>
<p>Input1 is programmatically set by JavaScript:</p>
<label for="input1">Input 1:</label>
<input id="input1" value="undefined" data-value="undefined">
</div>
<br>
<div>
<p>Try typing 0.00 inside input2:</p>
<label for="input2">Input 2:</label>
<input id="input2" value="undefined" data-value="undefined">
</div>

Styling bootstrap input-group-addon on input focus

Even if I don't really have hope, I want to style bootstrap input-group-addon in css only when the related input is focused. If the input is before the addon, like this:
<input class="form-control" type="email" placeholder="Enter email">
<div class="input-group-addon">#</div>
No problem, a simple :
input:focus + .input-group-addon {
background: $color;
color: white;
}
But assumed it can be placed after as well, if someone has a css based solution in this case, it would be wonderful.
You can't do that using pure CSS but using JQuery you can add these few simple lines to your code:
$( ".form-control" ).focus(function() {
$(this).prev('.input-group-addon').removeClass().addClass('input-group-addon-focus');
$(this).next('.input-group-addon').removeClass().addClass('input-group-addon-focus');
});
$( ".form-control" ).focusout(function() {
$(this).prev('.input-group-addon-focus').removeClass().addClass('input-group-addon');
$(this).next('.input-group-addon-focus').removeClass().addClass('input-group-addon');
});
If your "addon" not placed before or after Control EXACTLY, you can wrap control and addon in a wrapper and modify code using
.parent('.wrapperClass').children('.input-group-addon')
The complete code: JSFiddle Sample

Is it possible to use an input value attribute as a CSS selector?

Is it possible to use a CSS selector to target an input that has a specific value?
Example: How can I target the input below based on the value="United States"
<input type="text" value="United States" />
Dynamic Values (oh no! D;)
As npup explains in his answer, a simple css rule will only target the attribute value which means that this doesn't cover the actual value of the html node.
JAVASCRIPT TO THE RESCUE!
Ugly workaround: http://jsfiddle.net/QmvHL/
Original Answer
Yes it's very possible, using css attribute selectors you can reference input's by their value in this sort of fashion:
input[value="United States"] { color: #F90; }​
• jsFiddle example
from the reference
[att] Match when the element sets the "att" attribute, whatever the
value of the attribute.
[att=val] Match when the element's "att"
attribute value is exactly "val".
[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.
[att|=val] Represents an element with the att
attribute, its value either being exactly "val" or beginning with
"val" immediately followed by "-" (U+002D). This is primarily intended
to allow language subcode matches (e.g., the hreflang attribute on the
a element in HTML) as described in BCP 47 ([BCP47]) or its successor.
For lang (or xml:lang) language subcode matching, please see the :lang
pseudo-class.
css attribute selectors reference
It is possible, if you're using a browser which supports the CSS :valid pseudo-class and the pattern validation attribute on inputs -- which includes most modern browsers except IE9.
For instance, to change the text of an input from black to green when the correct answer is entered:
input {
color: black;
}
input:valid {
color: green;
}
<p>Which country has fifty states?</p>
<input type="text" pattern="^United States$">
Yes, but note: since the attribute selector (of course) targets the element's attribute, not the DOM node's value property (elem.value), it will not update while the form field is being updated.
Otherwise (with some trickery) I think it could have been used to make a CSS-only substitute for the "placeholder" attribute/functionality. Maybe that's what the OP was after? :)
As mentioned before, you need more than a css selector because it doesn't access the stored value of the node, so javascript is definitely needed. Heres another possible solution:
<style>
input:not([value=""]){
border:2px solid red;
}
</style>
<input type="text" onkeyup="this.setAttribute('value', this.value);"/>
Sure, try:
input[value="United States"]{ color: red; }
jsFiddle example.
You can use Css3 attribute selector or attribute value selector.
/This will make all input whose value is defined to red/
input[value]{
color:red;
}
/This will make conditional selection depending on input value/
input[value="United States"]{
color:red;
}
There are other attribute selector like attribute contains value selector,
input[value="United S"]{
color: red;
}
This will still make any input with United state as red text.
Than we attribute value starts with selector
input[value^='united']{
color: red;
}
Any input text starts with 'united' will have font color red
And the last one is attribute value ends with selector
input[value$='States']{
color:red;
}
Any input value ends with 'States' will have font color red
Refreshing attribute on events is a better approach than scanning value every tenth of a second...
http://jsfiddle.net/yqdcsqzz/3/
inputElement.onchange = function()
{
this.setAttribute('value', this.value);
};
inputElement.onkeyup = function()
{
this.setAttribute('value', this.value);
};
In Chrome 72 (2019-02-09) I've discovered that the :in-range attribute is applied to empty date inputs, for some reason!
So this works for me: (I added the :not([max]):not([min]) selectors to avoid breaking date inputs that do have a range applied to them:
input[type=date]:not([max]):not([min]):in-range {
color: blue;
}
Screenshot:
Here's a runnable sample:
window.addEventListener( 'DOMContentLoaded', onLoad );
function onLoad() {
document.getElementById( 'date4' ).value = "2019-02-09";
document.getElementById( 'date5' ).value = null;
}
label {
display: block;
margin: 1em;
}
input[type=date]:not([max]):not([min]):in-range {
color: blue;
}
<label>
<input type="date" id="date1" />
Without HTML value=""
</label>
<label>
<input type="date" id="date2" value="2019-02-09" />
With HTML value=""
</label>
<label>
<input type="date" id="date3" />
Without HTML value="" but modified by user
</label>
<label>
<input type="date" id="date4" />
Without HTML value="" but set by script
</label>
<label>
<input type="date" id="date5" value="2019-02-09" />
With HTML value="" but cleared by script
</label>
Following the currently top voted answer, I've found using a dataset / data attribute works well.
//Javascript
const input1 = document.querySelector("#input1");
input1.value = "0.00";
input1.dataset.value = input1.value;
//dataset.value will set "data-value" on the input1 HTML element
//and will be used by CSS targetting the dataset attribute
document.querySelectorAll("input").forEach((input) => {
input.addEventListener("input", function() {
this.dataset.value = this.value;
console.log(this);
})
})
/*CSS*/
input[data-value="0.00"] {
color: red;
}
<!--HTML-->
<div>
<p>Input1 is programmatically set by JavaScript:</p>
<label for="input1">Input 1:</label>
<input id="input1" value="undefined" data-value="undefined">
</div>
<br>
<div>
<p>Try typing 0.00 inside input2:</p>
<label for="input2">Input 2:</label>
<input id="input2" value="undefined" data-value="undefined">
</div>

CSS apply style to empty inputs ([value=''])

I would like to apply a special style to all inputs in my form that are required and empty at that.
It does work when i write in my css
input[required='required'] {
bla-bla-bla;
}
but it doesn't work, when i write
input[value=''] {
bla-bla-bla;
}
I know i can do that using jQuery, but i would like to do that in pure css, if it is possible.
Can that be done?
Thank you in advance,
Timofey.
If you don't have to support older IE versions, you can set the placeholder attribute on your input to something (can be whitespace, but must be something) and use :placeholder-shown to target that input.
<input type="text" class="custom-input" placeholder=" ">
.custom-input:placeholder-shown {
/* Your rules */
}
You can use the Pseudo-Selecot :invalid for this - it will match an input only when the browser-validation fails for the element. If you set the element required it will be invalid as long as it is empty.
And all moder browsers support this CSS-class: Browser Compatibility
input:invalid {
border-color: red;
}
<input type="text" required>
Searched css style empty inputs and found the following:
Matching an empty input box using CSS
You need to use JavaScript.
To use the CSS style, you would have to type in the attribute: value='' in your HTML, but then the CSS would match regardless of if the value changes mid-session.
Try this
<input type="text" value="">
input:not([value=""]) {
/* Your code */
}

Is there a CSS selector to detect if an input has a text file selected?

I'm trying to have some file inputs, and have them only show up if the previous one has been filled. This can use css 3 as well.
An example worth thousands words: Display X input, one at a time
The idea is simple, if an input set as required is empty, it's invalid. From there, all you have to do is set all input as required and use the :invalid pseudo class. Should work great with label too.
input:invalid~input:invalid {
display: none;
}
<input type="file" required>
<input type="file" required>
<input type="file" required>
To expand on Yi Jiang's comment, selectors against the "value" attribute won't notice changes to the "value" property. The "value" attribute is bound to the "defaultValue" property, while the "value" property isn't bound to any attribute (thanks to porneL for pointing this out).
Note there's a similar relationship with the "checked" attribute and "defaultChecked" and "checked" properties; if you use an attribute selector [checked] rather than the pseudo-class :checked, you won't see style change when a checkbox's state changes. Unlike the "checked" family, "value" doesn't have a corresponding pseudo-class that you could use.
Try the following test page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Dynamic attribute selectors</title>
<style type="text/css">
input:not([value]), div:not([value]) {
background-color: #F88;
}
input[value], div[value] {
border: 5px solid #8F8;
}
input[value=""], div[value=""] {
border: 5px solid #F8F;
}
input:not([value=""]), div:not([value=""]) {
color: blue;
border-style: dashed;
}
*.big {
font-size: 200%;
}
</style>
<script>
function getElt() {
var id=prompt("Enter ID of element", "d1");
if (id) {
return document.getElementById(id);
} else {
return {className: ''};
}
}
function embiggen() {
getElt().className="big";
return false;
}
function smallify() {
getElt().className="";
return false;
}
</script>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<div id="d1">no value</div>
<div id="d2" value="">empty value</div>
<div id="d3" value="some">some value</div>
<p><label for="foo">foo:</label> <input name="foo" id="foo" /></p>
<p><label for="bam">bam:</label> <input name="bam" id="bam" value="bug-AWWK" /></p>
<p><label for="file">File to upload:</label> <input type="file" name="file" id="file" onchange="setValueAttr(this)"/></p>
<input type="button" value="Embiggen" onclick="return embiggen()" />
<input type="button" value="Smallify" onclick="return smallify()" />
</body>
</html>
Changing the value of anything and the style won't change. Change the class of anything and the style will change. If you add the following JS function and bind it to a change event on an input, the background style will change.
function bindValue(elt) {
var oldVal=elt.getAttribute('value');
elt.setAttribute('value', elt.value);
var newVal=elt.getAttribute('value');
if (oldVal != newVal) {
alert('Had to change value from "'+oldVal+'" to "'+newVal+'"');
}
}
This binds the "value" property to the "value" attribute, so updates to the former by user input will propagate to the latter (programmatically setting the "value" property won't cause a change event).
In examining the JS properties of file inputs before and after (by use of the following script), the only one with an appreciable change was "value". From this, I doubt there are any other HTML attributes that change and could hence be used in an attribute selector.
<script>
var file = {blank: {}, diff: {}};
var fInput = document.getElementById('file');
for (p in fInput) {
try {
file.blank[p] = fInput[p];
} catch (err) {
file.blank[p] = "Error: setting '"+p+"' resulted in '"+err+"'";
}
}
function fileDiff() {
for (p in fInput) {
try {
if (file.blank[p] != fInput[p]) {
file.diff[p] = {orig: file.blank[p], now: fInput[p]};
}
} catch (err) {
//file.diff[p] = "Error: accessing '"+p+"' resulted in '"+err+"'";
}
}
}
if (fInput.addEventListener) {
fInput.addEventListener('change', fileDiff, false);
} else if (fInput.attachEvent) {
fInput.attachEvent('onchange', fileDiff);
} else {
fInput.onchange = fileDiff;
}
</script>
You can hack together something using a link to a non-existent fragment and the :visited pseudo class, but it's quite egregious.
<style>
a input {
display: none;
}
:not(a) + a input,
a:visited + a input
{
display: block /* or "inline" */ ;
}
</style>
...
<input type="file" ... />
<input type="file" ... />
<input type="file" ... />
You'd need to generate unvisited targets for the links every time the page is loaded. Since you'd have to do it server side, you couldn't do this with complete certainty, though you could get the probability of generating a previously visited target arbitrarily close to 0. It also doesn't work on all browsers, such as Safari. I suspect this is due to the following from CSS2 and CSS3:
Note: It is possible for style sheet authors to abuse the :link and :visited pseudo-classes to determine which sites a user has visited without the user's consent.
UAs may therefore treat all links as unvisited links, or implement other measures to preserve the user's privacy while rendering visited and unvisited links differently.
You might be able to hack something together using other selectors on other elements, but I suspect this can't be done cleanly.
To select empty fields you can try
input[type=file][value=""] {
background-color: red;
}
I tested it on jsfiddle. There at least, I needed to define an empty value attribute on the input tag for it to work
<input type="file" id="test" value="">
Using the '+' operator as you've done in your example would match two separate file inputs, one right after the other. It doesn't examine two attributes of the same tag as you appear to want.

Resources