3

Sorry for the generically worded title, anyway, I have some simple HTML like so:

<div class="block flex-1 mx-4 relative w-1/2">
    <div class="form-group label-floating">
        <label class="control-label">Password</label>
        <input class="form-control" placeholder="" type="password">
        <span class="material-input"></span>
    </div>
</div>

Now, whenver a person clicks the input, I am shrinking the label size like so:

Password field with shrunk label

With the following css:

&.label-floating {

    &:focus-within {
        & > .control-label {
            top: 10px;
            font-size: 11px;
            line-height: 1.07143;
        }
    }
}

Now, my problem is, if the input is not empty and the user leaves the input, the label will return to the normal size. So I have tried things like so:

Password field with text entered and full-size label

with the following css:

&.label-floating {

    &:focus-within {
        & > .control-label {
            top: 10px;
            font-size: 11px;
            line-height: 1.07143;
        }
    }

    & input:not(:empty){
        & .control-label {
            top: 10px;
            font-size: 11px;
            line-height: 1.07143;
        }
        & < .control-label {
            top: 10px;
            font-size: 11px;
            line-height: 1.07143;
        }
    }
}

With no avail, so, my question is, is there a way to achieve what I want, with pure css?

edit: can someone please edit the OP to embed the images, please.

Updated with pure css:

.form-group {
  margin-bottom: 1.5rem;
  position: relative;
}

.form-group > .control-label {
  color: #888da8;
}

.form-group.label-floating:focus-within > .control-label {
  top: 10px;
  font-size: 11px;
  line-height: 1.07143;
}

.form-group.label-floating input:not(:empty) .control-label {
  top: 10px;
  font-size: 11px;
  line-height: 1.07143;
}
kukkuz
  • 41,512
  • 6
  • 59
  • 95
  • 1
    Welcome to StackOverflow! It looks like you're using some kind of CSS preprocessor, like LESS or SASS. You might want to add the appropriate one as a question tag. – Harry Cutts Mar 19 '19 at 01:30
  • @HarryCutts SASS/LESS aren't relevant to the question even if used, this is a pure CSS issue – Temani Afif Mar 19 '19 at 01:31
  • 1
    Updated with pure css for those who don't know sass/less. – DumbAnswersForDumbQuestions Mar 19 '19 at 01:42
  • `/* active state */ input:focus ~ label, input:valid ~ label { top:-20px; font-size:14px; color:#5264AE; } ` https://codepen.io/chrisoncode/pen/IdGKH – Kunal Awasthi Mar 19 '19 at 01:42
  • @KunalAwasthi if a user enters an invalid email it won't work because the state will be 'invalid' and won't this require all my inputs to be 'required' even if I want some optional? https://codepen.io/thedeepnate/pen/PLBmWa – DumbAnswersForDumbQuestions Mar 19 '19 at 02:13
  • Possible duplicate: https://stackoverflow.com/questions/16952526/detect-if-an-input-has-text-in-it-using-css-on-a-page-i-am-visiting-and-do-no – Scrimothy Mar 19 '19 at 02:47
  • Possible duplicate of [Detect if an input has text in it using CSS -- on a page I am visiting and do not control?](https://stackoverflow.com/questions/16952526/detect-if-an-input-has-text-in-it-using-css-on-a-page-i-am-visiting-and-do-no) – Scrimothy Mar 19 '19 at 02:47

1 Answers1

1

You cannot target an input that contains a value without checking if the content is valid. You can, however, use a round-about way to check if the input has no value.

Your input has a placeholder attribute. The CSS selector :placeholder-shown will target inputs which are showing a placeholder; that is, inputs that have a placeholder attribute specified and are not empty.

You must therefore style the empty input's label.

.form-control:placeholder-shown ~ .control-label {
  font-size: 20px;
  color: red;
}

.label-floating:focus-within > .control-label,
.form-control ~ .control-label {
  font-size: 11px;
    color: blue;
}
<div class="form-group label-floating">
    <input class="form-control" placeholder="" type="password">
    <label class="control-label">Password</label>
</div>

Note that :placeholder-shown is not implemented in IE/Edge, despite being highly requested; there are, however, polyfills available.

jla
  • 4,191
  • 3
  • 27
  • 44
  • 1
    I have accepted the answer, can you please put a note at the bottom stating the placeholder workaround does not work in IE/edge in case anyone sees this answer in the future? – DumbAnswersForDumbQuestions Mar 19 '19 at 02:46