skip to Main Content

I have an input element and a sibling label element. Upon page load, the label overlaps the input element, serving as a placeholder. When the input is focused and contains a valid value, the label moves to the top of the input.

However, this behavior doesn’t apply to email type inputs because the label should only leave when a valid email value is entered and the input loses focus.

Additionally, if an input is not required, the style will be applied even if it not focused.

I want to prevent that.
Below is my current CSS for achieving this:

.label-animated {
    position: absolute;
    left: 1.6rem;
    top: 1rem;
    cursor: text;
    font-size: medium;
    transition: .5s ease;
    background-color: var(--bg-100) !important;
}

.input.input-form {
    width: 100%;
    font-size: medium;
    padding: 1rem;
    padding-bottom: .5rem;
    border: .0625rem solid var(--border-200);
    border-radius: 30rem; /*max border*/
    outline: none;
    background-color: transparent;
}

.input.input-form:focus~.label-animated,
.input.input-form:valid~.label-animated {
    top: -.72rem !important;
    left: 2rem;
    color: var(--accent-500);
}

Despite extensive searching for a solution, I have been unable to find any resources or guidance regarding this issue. It appears that there is currently no available information or solutions that address this specific problem. I can select an input that has no value input[value=""] but that has value, I don’t really know. Can I fix this problem by just only using CSS?

2

Answers


  1. You can apply styles to an input field based on whether it is empty or not using CSS alone by utilizing the :placeholder-shown pseudo-class along with the adjacent sibling combinator (+). Here’s an The input:not(:placeholder-shown) selector applies styles to the input field when it’s not empty. You can modify these styles as needed.
    The input:placeholder-shown + .error-message selector targets the adjacent .error-message element when the input field is empty. You can use this to display an error message or apply any other styling as needed.

    Login or Signup to reply.
  2. You do not provide your html code, so fair enough if I use mine for the answer. But the point line is that, as already rejoiced, you should use pseudo-class :placeholder-shown.
    And you also need to consider :autofill.
    Here is a simple example:

    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    .fields {
      display:grid;
      max-width: 280px;
      gap: 24px;
      padding: 24px;
    }
    
    label {
      --padding: 12px;
      --height: 40px;
      --bg: white;
      display: inline-block;
      position: relative;
    }
    
    label:before {
      --left: calc(.5 * var(--padding));
      content: attr(aria-label);
      position: absolute;
      top: calc(.5 * var(--height) - .5lh);
      left: var(--left);
      max-width: calc(100% - 2 * var(--left));
      transition: transform .4s;
      display: flex;
      flex-direction: column;
      justify-content: center;
      padding: 0 calc(.5 * var(--padding));
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      pointer-events: none;
      transform-origin: left;
      background-color: var(--bg);
    }
    
    input {
      display: block;
      padding: 0 var(--padding);
      height: var(--height);
      width: 100%;
      background: var(--bg);
    }
    
    input:autofill {
      box-shadow: inset 0 0 0 666vw var(--bg);
    }
    
    input::placeholder {
      color: transparent;
    }
    
    label:has(input:focus):before,
    label:has(input:autofill):before,
    label:has(:not(input:placeholder-shown)):before {
      transform: translateY(calc(-.5 * var(--height))) scale(.8);
    }
    <div class="fields">
      <label aria-label="Name">
        <input type="text" placeholder="Name" name="name">
      </label>
      <label aria-label="Email">
        <input type="email" placeholder="Email" name="email" required>
      </label>
      <label aria-label="Password">
        <input type="password" placeholder="Password" name="password" required>
      </label>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search