DEV Community

Andrew
Andrew

Posted on

CSS Selectors Related to Form Control

Nowadays, we tend to use JavaScript to validate the form. Then adding some classes to help us style the input elements. In some cases, we probably no need to create extra classes because there are already some CSS selectors that can help us do the job. In this article, I will introduce some CSS selectors related to form control which you might not know before.

Agenda

Form Related CSS Selectors

This image is coming from the State of CSS 2019. Some of the CSS selectors related to form control had not used by many developers.

css-selectors

:require & :placeholder-shown

required

The first example is :required. Because we can't use Pseudo-elements for the input element, Therefore I add an extra div after the input element to display the message.

<label>
  <span>Name</span>
  <input type="text" name="name" placeholder="your name" required />
  <div></div>
</label>
Enter fullscreen mode Exit fullscreen mode

Then we can use :required to add some style for the input which is must fill up.

input:required + div::before {
  content: "(required)";
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

If we want to hide the warning message after the user fills up the input, we can use :placeholder-shown to do the trick.

input:required + div::before {
  display: none;
}
input:placeholder-shown + div::before {
  display: block;
}
Enter fullscreen mode Exit fullscreen mode

:out-of-range

out-of-range

If we have set a range for the input, then we can use :out-of-range to alert the user when the input value is not within the limit.

<label>
  <span>Years of Experience</span>
  <input type="number" min="0" max="100" />
  <div></div>
</label>
Enter fullscreen mode Exit fullscreen mode
input:out-of-range + div::before {
  content: "(out-of-range)";
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

:invalid

invalid

If there was some error on the content that the user provides, we might want to notify the user that the form is not completed yet. Here we can apply :invalid to display the result.

<form>
  <label>
    <span>Name</span>
    <input type="text" name="name" placeholder="your name" required />
    <div></div>
  </label>
  <button type="submit"></button>
</form>
Enter fullscreen mode Exit fullscreen mode
button:before {
  content: "Ready to Submit";
}
form:invalid > button {
  background: darkgray;
}
form:invalid > button:before {
  content: "Not Ready";
}
Enter fullscreen mode Exit fullscreen mode

:default

default

Sometimes we will set a default option for the checkbox or radio. It's good to let the user know this option is checked by default. We can use :default to add extra style for that.

<div>
  <span>Fields</span>
  <label>
    <input type="checkbox" value="fe" checked />
    Front-End Developer
    <div></div>
  </label>
  <label>
    <input type="checkbox" value="be" />
    Back-End Developer
    <div></div>
  </label>
</div>
Enter fullscreen mode Exit fullscreen mode
input:default + div::before {
  content: "(default)";
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

:read-only

read-only

When the user is editing the form, we might not allow them to edit certain columns (ex. user id). So we can use :read-only display a different style to identity that.

<label>
  <span>Referred by</span>
  <input type="text" value="oahehc@gamil.com" readonly />
  <div></div>
</label>
Enter fullscreen mode Exit fullscreen mode
input:read-only + div::before {
  content: "(read-only)";
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

Here is an example to display all the above scenarios.

Browser Support

Here is the status of the browser support for all those Pseudo-classes. (2020-03-22)

:required
:placeholder-shown
:out-of-range
:invalid
:default
:read-only


Conclusion

Frankly, handling form validation through JavaScript can provide maximum flexibility, and we can easily create extra classes for style the input elements base.

If the use case is simple and we can implement the form validation by using HTML attributes. Then using CSS selectors to style the input elements will be a good solution.

The code will be easier to read because we have standard syntax. And HTML now already have enough attributes to help us validate the input for most of the use case.

Constraint Validation HTML Input Attributes

The downside of using HTML attributes to do the form validation is the style will be inconsistent in different browsers.

browser-validate-all

--

Reference

Latest comments (3)

Collapse
 
youpiwaza profile image
max

Amazing article, I had no idea most of this stuff existed o_ô. A big thank you.

But on thing bugs my mind, it's the application of :invalid. I know it's for the example, but don't just set the background to grey :

  • Form can still be submitted
  • Pretty sure it's not accessible

And pay attention to form validation. Html & JS form validation are useless to stop hackers.
Make sure to verify & sanitize fields, value and type in the backend before using the data :)

Collapse
 
oahehc profile image
Andrew

Thanks a lot for the feedback.

  • Security is definitely an issue when doing the validation on the client-side. We should always validate the data on the backend server again. Thanks for reminding that.
  • For accessible, I should add aria-label for the button.
<button type="submit" aria-label="submit"></button>
  • Form submit event will be blocked if any of the input is invalid.
<form onsubmit={xxx}>...</form>

But If we use the button click event to submit the result, then we will need to add extra CSS to prevent the click event.

form:invalid > button {
  background: darkgray;
  pointer-events: none;
}
Collapse
 
youpiwaza profile image
max

Just keep in mind that anyone (with a little tech background) can edit html/css/js with browser inspector, or even forge requests from scratch ^^'

For the accessibility, I was thinking about add/removing the disabled attribute on the button, to inform that the user can't send the form if it isn't properly filled (especially for color blind people or those who uses readers) ; and prefer the submit event on form, instead of banking on the button :p

Anyway, still a great post !

Cheers