Q:

HTML5 + CSS3 + Firefox issue

I have the following problem. I am trying to run this example on my project http://designscrazed.org/css-html-login-form-templates/.
Here is my HTML:
<p id="firstname_line">
    <label>First Name:</label>
    <input type="text"  name="firstname" id="firstname" required pattern="^[a-zA-Z]+$"><span title="Name should contain only letters!"></span>
</p>

My CSS:
#firstname_line input:invalid ~ span:after {
    opacity: 1;
    color:green;
}
#firstname_line input ~ span:after {
    content:attr(title);
    color:red;
    margin-left:.6rem;
    opacity: 0;
    transition: 1s 1s opacity linear;
}
#firstname_line span {
    color: red;
    display: block;
}

When I try to apply the example on my project, I have a strange problem on all browsers.
On load, in the case that the input field is empty, it should be treated as a ":valid" field, or non ":invalid" and the CSS class #firstname_line input:invalid ~ span:after shouldn't be applied. Instead of that, both of the classes #firstname_line input:invalid ~ span:after and #firstname_line input ~ span:after { are applied on load and the  is visible. As you can see in the example, the  shouldn't be visible on load.
Can someone please propose where may the problem be?

A:

Let's simplify first:

div input ~ span:after {
  content: attr(title);
  display: none;
}

div input:invalid ~ span:after {
  display: inline;
  color: red;
}
<div>
  <input type="text" required pattern="^[a-zA-Z]+$">
  <span title="Name should contain only letters!"></span>
</div>

The reason the span's picking up the :invalid pseudo-selector styling is because the required attribute on the input makes the initially blank field invalid.
Remove the required attribute, and the :invalid pseudo-selector will not get picked up with a blank field value.

div input ~ span:after {
  content: attr(title);
  display: none;
}

div input:invalid ~ span:after {
  display: inline;
  color: red;
}
<div>
  <input type="text" pattern="^[a-zA-Z]+$">
  <span title="Name should contain only letters!"></span>
</div>

The issue with this solution is the field is no longer required to submit the form. If the field value is left blank, the regex test will not be performed, and the form will submit. 
There is no way with pure CSS to determine if a field value is blank or not beyond the initial load of the page (the DOM is not updated as a user types). This is a reason why using Javascript is a safer/cleaner/more reliable way of validating a form client-side.

