AwokeKnowing
AwokeKnowing

Reputation: 8236

Workaround for :disabled:valid CSS issue

I have some fields that have placeholders and also labels. The labels are hidden until text is entered. When text is in the input box, then the label shows (since the placeholder is now hidden)

The way I implemented this in CSS is to use the :valid selector. I make each input have "required", and then :valid triggers whenever that input has text

.fstyle{font-family:arial,sans-serif;font-size:14px;color:#000}
.fstyle .fbutton{width:50%;margin:18px auto;background-color:#ef8f34;opacity:.5;color:#fff;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;text-align:center;padding:15px 5px;font-size:20px;font-weight:700;overflow:visible;margin-bottom:7px;text-shadow:1px 1px 2px rgba(0,0,0,.5);-webkit-transition:.5s ease-in-out;-moz-transition:.5s ease-in-out;-o-transition:.5s ease-in-out;transition:.5s ease-in-out}
.fstyle .fbutton.active{opacity:1;cursor:pointer;-webkit-box-shadow:2px 2px 3px #888;-moz-box-shadow:2px 2px 3px #888;box-shadow:2px 2px 3px #888}
.fstyle .fbutton.active:hover{background-color:#f29d51;text-shadow:1px 1px 2px rgba(0,0,0,.8);-webkit-transition:.2s;-moz-transition:.2s;-o-transition:.2s;transition:.2s}
.fstyle .finputbtn{display:inline-block;display:none;position:absolute;width:100px;margin:0 0 0 -100px;height:40px;line-height:40px;font-size:16px;color:#fff;background:#ef8f34;text-align:center;cursor:pointer!important}
.fstyle h4{font-size:13px;font-weight:700;color:#4d4d4d;display:block;width:auto;padding:18px 0 4px 4px;margin-bottom:12px;border-bottom:1px solid #9f9f9f}
.fstyle h3{font-size:16px;font-weight:700;color:#4d4d4d;display:block;width:auto;padding:18px 0 4px 4px;margin-bottom:12px;border-bottom:1px solid #9f9f9f}
.fstyle .select-contain{padding:0;margin:0 0 32px;border:2px solid #b7b7b7;width:auto;border-radius:0;overflow:hidden;color:#000;background:#e4e4e4 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAICAYAAADwdn+XAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAANRQAADUUBUfHEqAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADKSURBVCiRfdA/L8NhFMXxzyOa+JPo3MQiNoLVIGKymkwGL8DLUhKJSFgNhs4MTUSYGbwA0qTkWB5NNb+6273ne0/uuQWr2MIr+kkG/qlSyjw2sYx+SaKU0sERFtBDL8nXxGILO9jFAN0kbyXJLzCHQ6zhGadJvqvWxjE6eMFFkk8YGVSwYB97eMIZFnGCJdzhNmNLfwzGjA6wjccaawX3SS4n2dkpv7pBG+u1f8d1EzjTNKwnXuEDQ5wnGTaxjRFGYikbaCV5mMb8AP68TeEXCmHVAAAAAElFTkSuQmCC) no-repeat 95% 50%}
.fstyle select{padding:11px 8px;width:130%;border:none;box-shadow:none;background-color:transparent;background-image:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-size:14px}
.fstyle select:focus{outline:none}
.fstyle label{visibility: hidden;opacity:0;transition: visibility 0s ease-in-out .5s, opacity .5s ease-in-out;position:absolute;top:-12px;left:-2px;padding:2px 4px;margin:0;background:#fff;border:2px solid #b7b7b7;border-bottom:0;border-radius:10px 10px 10px 0;font-size:12px;color:#669}
.fstyle input:valid + label,.fstyle textarea:valid + label{visibility: visible;opacity:1;transition: opacity .5s ease 0s,visibility 0s ease-in-out 0s}
.fstyle .txtinput-contain{position:relative;padding:0;margin:0 0 32px;border:2px solid #b7b7b7;width:auto;border-radius:0;color:#000;background:#fff;text-align:left}

.fstyle .___-_{width:auto;text-align:right;position:relative}
.fstyle .___- {width:60%}
.fstyle    .-_{width:34%;position:absolute;right:0;top:0;margin:0}

.fstyle .__-__{width:auto;text-align:right;position:relative}
.fstyle .__-  {width:47%}
.fstyle   .-__{width:47%;position:absolute;right:0;top:0;margin:0}

.fstyle input{padding:12px 10px;box-sizing:border-box;width:100%;border:none;box-shadow:none;background-color:transparent;background-image:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-size:14px}
.fstyle input:focus{outline:none}
.fstyle input:disabled,.fstyle input:disabled:valid + label{background:#ddd;}
.fstyle textarea{padding:12px 10px;box-sizing:border-box;width:100%;border:none;box-shadow:none;background-color:transparent;background-image:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-family:arial,sans-serif;font-size:14px;height:104px;resize:none}
.fstyle textarea:focus{outline:none}
.fstyle .val-box{font-size:12px;background:#d74b4b;color:#fff;padding:0;top:0;position:relative;margin-top:0;width:auto;opacity:0;height:0;transition:all .2s ease-out}
.fstyle input.isinvalid:not(:focus) ~ .val-box,.fstyle textarea.isinvalid:not(:focus) ~ .val-box{opacity:1;margin-top:-8px;padding:2px 8px;height:14px}
.fstyle .headimg{margin-top:30px;margin-bottom:15px;max-width:100%;max-height:auto}
.fstyle.cozy .select-contain,.fstyle.cozy .txtinput-contain{margin-bottom:14px}
<div class='fstyle cozy'>
      <h4>Welcome, please set up your account</h4>
      <div class='txtinput-contain'>
        <input id="company" type='text' name='company' placeholder='Company / Organization' value="asdfasfdasdf" disabled required/>
        <label for='company'>Company</label>
        <div class='val-box'>Please enter your company name</div>
      </div>
      <div class='txtinput-contain'>
        <input id="username" class="isvalid" type='text' name='email' placeholder='Email / Login' required/>
        <label for='email'>Login</label>
        <div class='val-box'>Please enter a valid email</div>
      </div>
      <div class='__-__'>
        <div class='txtinput-contain __-'>
          <input id="name_f" type='text' name='firstname' placeholder='First name' required/>
          <label for='firstname'>First name</label>
          <div class='val-box'>Required</div>
        </div>
        <div class='txtinput-contain -__' >
          <input id="name_l" type='text' name='lastname' placeholder='Last name' required/>
          <label for='lastname'>Last name</label>
          <div class='val-box'>Required</div>
        </div>
      </div>
      <div class='__-__'>
        <div class='txtinput-contain __-'>
          <input id="password" type='password' name='password' placeholder='Password' required/>
          <label for='password'>Password</label>
          <div class='val-box'>Password is too short</div>
        </div>
        <div class='txtinput-contain -__' >
          <input id="cpass" type='password' name='confirmpassword' placeholder='Confirm password' required/>
          <label for='confirmpassword'>Confirm password</label>
          <div class='val-box'>Password does not match</div>
        </div>
      </div>
      <h4>Tell us about you</h4>
      <div class='txtinput-contain'>
          <textarea name='message' placeholder='Describe your training needs' required></textarea>
          <label for='message'>About you</label>
          <div class='val-box'>Please briefly describe your training needs</div>
</div>
</div

Run the above to see it, and type into a field

If I make a field disabled, the field itself turns grey, but the label does not show (eg the field is disabled but there is text in it, I want the label to show what the text means).

I want it to show like this enter image description here

But instead it shows like this. enter image description here

The line of css that is not working (you can see it in the snipped above)

.fstyle input:disabled,.fstyle input:disabled:valid + label{background:#ddd;}

I'm assuming that input:disabled:valid is the issue, but I don't know how to express it in CSS to get the same result

Edit:

This is the javascript/jquery "solution" to imitate what CSS should be doing. It's truly terrible, so I really hope there's a CSS solution. And to clarify, form templates and their data are loaded separately, so the value of an input, and whether it is disabled can change any time.

setInterval(function(){
    $('.fstyle input:disabled').each(function(){
        if($(this).val()) {
            $(this).siblings('label').css({
               visibility: "visible",
               opacity: 1
            });
        } else {
            $(this).siblings('label').css({
               visibility: "hidden",
               opacity: 0
            });
        }
    });
},100);

Upvotes: 4

Views: 192

Answers (1)

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324840

Aside from the issue with disabled inputs, you will run into other problems such as if you decide to use <input type="email" /> - the label will stop showing up if the input is not a :valid email address.

Unfortunately something like this is going to be outside the scope of CSS. There are plenty of clever tricks to make it "somewhat" work, but for it to work properly you will need to use JavaScript.

Since your (now deleted) sample answer uses jQuery, I'll likewise use jQuery to simplify the example, but of course it can be achieved in vanilla JavaScript easily enough.

$(document.body).on("input change", ".fstyle input", function(e) {
    var input = $(this),
        label = input.next("label");

    if( input.val()) label.addClass("hastext");
    else label.removeClass("hastext");
});
// trigger for initial state:
$(".fstyle input").trigger("change");

Then use the .hastext class to define how the label should be displayed when the input has text.

This avoids restricting the HTML5 validation you can do, and should work reasonably well.

Upvotes: 1

Related Questions