0

I want to change the appearance of this email form element when the inserted email address does not match the pattern which I stated, but I am not sure what to use, I tried using :invalid but I'm not sure if it works or not, so I would like to hear from you guys.

The code is:

<input type="email" name="email" required placeholder="Your Email" pattern="[a-zA-Z1-9]+@[a-zA-Z1-9]+\.[a-zA-Z]{2,}"/>
        [type="email"]{
            padding:.7rem;
            border-radius:.3rem;
            border:none;
            margin-right:2rem;

            &:invalid{
                outline:none;
                border:1px solid red;
            } 
        }
Liquorice
  • 21
  • 4
  • You shouldn’t try to add yet another restriction with an incorrect pattern. The browser already has a pattern implemented. See https://stackoverflow.com/questions/46155/how-can-i-validate-an-email-address-in-javascript for how that pattern would need to look for not discriminating against some users – Andy Jan 23 '23 at 17:30
  • Why are you not sure whether it works? – Andy Jan 23 '23 at 17:38
  • @Andy I was not sure initially because the red border showed even when the email input was empty and I didn't want that. – Liquorice Jan 26 '23 at 10:39
  • 1
    I see. I added that aspect to my answer. – Andy Jan 26 '23 at 11:25

3 Answers3

1

Except for the pattern everything is alright and works. You can test it here:

[type="email"] {
  padding: .7rem;
  border-radius: .3rem;
  border: 1px solid gray;
  margin-right: 2rem;
}

[type="email"]:invalid {
  border: 1px solid red;
}
<label>Your Email
  <input type="email" name="email" required placeholder="you@example.com" />
</label>

Not showing errors on empty inputs

It‘s not a good practice to greet the user with a bunch of errors before they entered any data.

Bootstrap uses a .was-validated class on the <form>, to hide the error states until that class was added via JavaScript.

.was-validated input:invalid

Another solution without CSS might be the use of the :placeholder-shown pseudo-class to hide the error state.

This needs a placeholder attribute, which can be set to placeholder="".

input:invalid:not(:placeholder-shown) {
  border-color: red;
}

/* or, backwards-compatible */
input:invalid {
  border-color: red;
}

input:placeholder-shown {
  border-color: initial;
}
<label>Your Email
  <input type="email" name="email" required placeholder="you@example.com" />
</label>

Beware of restrictive patterns/regex

You should not provide yet another pattern for validation. The browser already has a pattern implemented based on tons of research and with the help of a lot of engineers.

See How can I validate an email address in JavaScript? for some ideas on what you are missing.

I find it important to point this out, as restricting input data is effectively discriminating against users who’s data patterns were missed in the design. This is especially true for groups who are underrepresented in engineering staff.

Andy
  • 4,783
  • 2
  • 26
  • 51
  • Do you have a link to a website that speaks more about the already applied pattern in browsers? – Liquorice Jan 26 '23 at 10:40
  • I don’t know one by heart. [MDN’s HTML5 input types](https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types) lists the possible values of the `type` attribute. But to actually get the underlying regex pattern, I guess you’d need to read the browsers’ source codes. – Andy Jan 26 '23 at 11:07
  • But usually, what is valid data is defined in RFCs like [RFC 2822 ](https://www.rfc-editor.org/rfc/rfc2822#section-3.4.1) for email addresses. Since the ecosystem not necessarily stuck to these norms, validation can be more lax. – Andy Jan 26 '23 at 11:09
  • thanks, I will be sure to check it out. – Liquorice Jan 26 '23 at 12:10
0

You should add "input" after [type="email"] example: input[type="email"] and I tried it and everything is alright

input[type="email"]:invalid {
    border: 1px solid red;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
      <input type="email" name="email" required placeholder="Your Email" pattern="[a-zA-Z1-9]+@[a-zA-Z1-9]+\.[a-zA-Z]{2,}"/>
    </body>
</html>
  • Adding input is not necessary in fact. It’s changing the selector’s specificity, but that’s not an issue. – Andy Jan 23 '23 at 17:41
-2

You can do this

<!DOCTYPE html>
<html lang="en">

    <head>
        
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>

        <style>
            input:valid {
                background-color: palegreen;
            }

            input:invalid {
                background-color: lightpink;
            }

            input {
                display: block;
            }

        </style>

    </head>

    <body>

        <label for="emailA">With no character:</label>
        <input type="email" name="emailA" pattern="[a-zA-Z1-9]+@[a-zA-Z1-9]+\.[a-zA-Z]{2,}" required />

        <label for="emailB">With good email:</label>
        <input type="email" name="emailB" pattern="[a-zA-Z1-9]+@[a-zA-Z1-9]+\.[a-zA-Z]{2,}" value="mail@example.com" required />

        <label for="emailC">With bad email:</label>
        <input type="email" name="emailC" pattern="[a-zA-Z1-9]+@[a-zA-Z1-9]+\.[a-zA-Z]{2,}" value="badmail@@example.com" required />
    
    </body>

</html>
avieville
  • 58
  • 1
  • 5
  • That's great but I don't want the "mail@example.com" to appear, it should be empty. – Liquorice Jan 23 '23 at 12:41
  • I edited by adding a case without the example mail. – avieville Jan 23 '23 at 12:55
  • You shouldn’t try to add yet another restriction with an incorrect pattern. The browser already has a pattern implemented. See https://stackoverflow.com/questions/46155/how-can-i-validate-an-email-address-in-javascript – Andy Jan 23 '23 at 17:29
  • Well done for the proper HTML markup with labels, though! (: – Andy Jan 23 '23 at 17:30