Search code examples
htmlcssformstexttransition

CSS text transition only works when HTML input has "required" tag


I have text input fields in a form that I styled so that the labels start in the boxes, then slide up when a field is in focus. However, this only works for the "required" fields, and all of the other ones have the labels already above the boxes. How do I make those ones behave like the rest?

Picture of the form fields in question

HTML:

        <div class="tGroup">
            <input  id="email" maxlength="80" name="email" size="20" type="text" required>
            <span class="bar"></span>
            <label for="email">Email</label>
        </div>
        
        <div class="tGroup">
            <input  id="company" maxlength="40" name="company" size="20" type="text" required>
            <span class="bar"></span>
            <label for="company">Company</label>
        </div>

        <div class="tGroup">
            <input  id="url" maxlength="80" name="url" size="20" type="text">
            <span class="bar"></span>
            <label for="url">Website</label>
        </div>

        <div class="tGroup">
            <input  id="city" maxlength="40" name="city" size="20" type="text">
            <span class="bar"></span>
            <label for="city">City</label>
        </div>

CSS:

.tGroup { 
    position:relative; 
    margin-bottom:45px; 
    float:left;
    margin-right: 40px;
}

.tGroup input {
    font-size:.9em;
    padding:10px 0px;
    display:block;
    width:300px;
    border:none;
    color: #fff;
    background-color: transparent;
    border-bottom:1px solid #757575;
}

.tGroup input:focus { outline:none; }

.tGroup label {
    color:rgb(255, 255, 255); 
    font-size: .9em;
    font-weight:normal;
    position:absolute;
    pointer-events:none;
    top:10px;
    transition:0.2s ease all; 
    -moz-transition:0.2s ease all; 
    -webkit-transition:0.2s ease all;
}
  
/* active state */
.tGroup input:focus ~ label, input:valid ~ label {
    top:-20px;
}

Solution

  • The problem was with input:valid ~ label because you are saying that you want the inputs that are valid to have applied that specific style on the label, but since the last 2 don't have a required attribute they don't classify. You can just remove that.

    body{
      background:black;
    }
    .tGroup { 
        position:relative; 
        margin-bottom:45px; 
        float:left;
        margin-right: 40px;
         margin-top: 30px;
    }
    
    .tGroup input {
        font-size:.9em;
        padding:10px 0px;
        display:block;
        width:300px;
        border:none;
        color: #fff;
        background-color: transparent;
        border-bottom:1px solid #757575;
    }
    
    .tGroup input:focus { outline:none; }
    
    .tGroup label {
        color:rgb(255, 255, 255); 
        font-size: .9em;
        font-weight:normal;
        position:absolute;
        pointer-events:none;
        top:10px;
        transition:0.2s ease all; 
        -moz-transition:0.2s ease all; 
        -webkit-transition:0.2s ease all;
    }
      
    /* active state */
    .tGroup input:focus ~ label  {
        top:-20px;
    }
    <div class="tGroup">
                <input  id="email" maxlength="80" name="email" size="20" type="text" required>
                <span class="bar"></span>
                <label for="email">Email</label>
            </div>
            
            <div class="tGroup">
                <input  id="company" maxlength="40" name="company" size="20" type="text" required>
                <span class="bar"></span>
                <label for="company">Company</label>
            </div>
    
            <div class="tGroup">
                <input  id="url" maxlength="40" name="url" size="20" type="text">
                <span class="bar"></span>
                <label for="url">Website</label>
            </div>
    
            <div class="tGroup">
                <input  id="city" maxlength="40" name="city" size="20" type="text">
                <span class="bar"></span>
                <label for="city">City</label>
            </div>