I found solution for :required
inputs but nothing for :optional
.
Thank you for help and sorry for my English, this isn't my native language.
I found solution for :required
inputs but nothing for :optional
.
Thank you for help and sorry for my English, this isn't my native language.
Found this solution, using :placeholder-shown
:
input:placeholder-shown {
border: 1px solid #f5f5f5;
}
input {
background: #ffffff;
border: 10px solid;
border-image-slice: 1;
border-width: 1px;
border-image-source: linear-gradient(
171.2deg,
#ffc1d4 15.78%,
#ff866c 76.58%
);
}
<form>
<input type="text" name="name1" id="" placeholder="placeholder1" optional>
<input type="text" name="name2" id="" placeholder="placeholder2" optional>
</form>
Note: If you're targeting modern browsers and using a placeholder (or you can use a placeholder), you can use Irina's :placeholder-shown
pseudo-class below rather than .empty)
and do away with the JavaScript. It doesn't work in IE or Edge v44 or earlier, but works in all up-to-date modern browsers. But: You can use -ms-input-placeholder
for IE and Edge v44 and earlier, making the JavaScript part of the below defunct. But I don't want to edit it to use :placeholder-shown
and :-ms-input-placeholder
because that duplicates Irina's answer (somewhat), and I can't remove this answer because it's accepted. See the end of the answer for an example, though.
I found solution for :required inputs but nothing for :optional.
Two ways you can do that:
You can use :not(:required)
. :not
is the negation pseudoclass. It accepts a simple selector and inverts its meaning. "Not required" is "optional."
You can style all of the inputs in the "optional" way, then override that styling for :required
elements.
Unfortunately, though, the "empty" part of your question can't be answered with CSS alone for input
elements that are optional (more here).
Here's an example of #1, using JavaScript to add/remove a class when the input is/isn't empty:
"use strict";
function toggleEmptyClass(el) {
if (el.tagName === "INPUT") {
// If you need IE compatibility, you'll need an `if`/`else`;
// IE doesn't support the second argument for `toggle`
el.classList.toggle("empty", !el.value);
}
}
document.querySelectorAll("input").forEach(toggleEmptyClass);
document.addEventListener("input", function() {
toggleEmptyClass(event.target);
});
input:not(.empty):required {
background-color: #FF8000;
}
input:not(.empty):not(:required) {
background-color: #0080FF;
}
<div>
<label>
Required:
<input type="text" required value="required">
</label>
</div>
<div>
<label>
Required and (initially) empty:
<input type="text" required>
</label>
</div>
<div>
<label>
Optional:
<input type="text" value="optional">
</label>
</div>
<div>
<label>
Optional and (initially) empty:
<input type="text">
</label>
</div>
Or you can just style all input
elements with the "optional" style, and then override it for :required
elements:
Example:
"use strict";
function toggleEmptyClass(el) {
if (el.tagName === "INPUT") {
// If you need IE compatibility, you'll need an `if`/`else`;
// IE doesn't support the second argument for `toggle`
el.classList.toggle("empty", !el.value);
}
}
document.querySelectorAll("input").forEach(toggleEmptyClass);
document.addEventListener("input", function() {
toggleEmptyClass(event.target);
});
input:not(.empty) {
background-color: #0080FF;
}
input:not(.empty):required {
background-color: #FF8000;
}
<div>
<label>
Required:
<input type="text" required value="required">
</label>
</div>
<div>
<label>
Required and (initially) empty:
<input type="text" required>
</label>
</div>
<div>
<label>
Optional:
<input type="text" value="optional">
</label>
</div>
<div>
<label>
Optional and (initially) empty:
<input type="text">
</label>
</div>
Here's a full example showing doing the above with :placeholder-shown
and the older Microsoft-specific -ms-input-placeholder
:
input:not(:placeholder-shown):required {
background-color: #FF8000;
}
input:not(:placeholder-shown):not(:required) {
background-color: #0080FF;
}
/* IE and Edge <= v44 support: */
input:not(:-ms-input-placeholder):required {
background-color: #FF8000;
}
input:not(:-ms-input-placeholder):not(:required) {
background-color: #0080FF;
}
<div>
<label>
Required:
<input type="text" placeholder="placeholder" required value="required">
</label>
</div>
<div>
<label>
Required and (initially) empty:
<input type="text" placeholder="placeholder" required>
</label>
</div>
<div>
<label>
Optional:
<input type="text" placeholder="placeholder" value="optional">
</label>
</div>
<div>
<label>
Optional and (initially) empty:
<input type="text" placeholder="placeholder">
</label>
</div>
Or, again, styling all of them and then overriding just the :required
to be different:
input:not(:placeholder-shown) {
background-color: #0080FF;
}
input:not(:placeholder-shown):required {
background-color: #FF8000;
}
/* IE and Edge <= v44 support: */
input:not(:-ms-input-placeholder) {
background-color: #0080FF;
}
input:not(:-ms-input-placeholder):required {
background-color: #FF8000;
}
<div>
<label>
Required:
<input type="text" placeholder="placeholder" required value="required">
</label>
</div>
<div>
<label>
Required and (initially) empty:
<input type="text" placeholder="placeholder" required>
</label>
</div>
<div>
<label>
Optional:
<input type="text" placeholder="placeholder" value="optional">
</label>
</div>
<div>
<label>
Optional and (initially) empty:
<input type="text" placeholder="placeholder">
</label>
</div>
Here's a solution using javascript and css
CSS:
.highlighted
{
border: hsl(180, 60%, 60%) 2px solid;
}
JS:
let inputs = document.querySelectorAll('input:optional');
for (let input of inputs)
{
input.addEventListener('change',function(e)
{
if (this.value != '')
{
this.classList.add('highlighted');
}
else
{
this.classList.remove('highlighted');
}
});
}