user14872626
user14872626

Reputation:

how to make a outlined input with floating label with custom css?

I want to make an input with the floating label. Exactly like the material-ui for react.

Material UI Code :

<TextField
  id="outlined-basic"
  label="E-Mail"
  variant="outlined"
  placeholder="Enter E-Mail"
  /> 

Link for seeing output for the above code : Code

What I want is, the label must be inside the input field. When the user is clicking the input field, the label should float and the placeholder should be shown. If the user doesn't enter anything and if the focus changes, again the placeholder must be hidden and the label must comeback to initial position

What I have tried so far is :

.container {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    }

    .material-textfield {
    position: relative;
    }

    label {
    position: absolute;
    font-size: 1rem;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    background-color: white;
    color: gray;
    padding: 0 0.3rem;
    margin: 0 0.5rem;
    transition: 0.1s ease-out;
    transform-origin: left top;
    pointer-events: none;
    }
    input {
    font-size: 1rem;
    outline: none;
    border: 1px solid gray;
    border-radius: 5px;
    padding: 1rem 0.7rem;
    color: gray;
    transition: 0.1s ease-out;
    }
    input:focus {
    border-color: #6200ee;
    }
    input:focus + label {
    color: #6200ee;
    top: 0;
    transform: translateY(-10%) scale(0.9) !important;
    }
    input:not(:placeholder-shown) + label {
    top: 0;
    transform: translateY(-50%) scale(0.9) !important;
    }

    input:empty + label {
    transform: translateY(75%);
    font-weight: bold;
    }

    input:empty:not(:placeholder-shown) + label {
    top: 0;
    transform: translateY(-50%) scale(0.9) !important;
    }

    input:empty::-webkit-input-placeholder {
    opacity: 0;
    }
<div class="container">
    <div class="material-textfield">
      <input placeholder="placeholder" type="text" />
      <label> label</label>
    </div>
  </div>

Upvotes: 0

Views: 5472

Answers (1)

Zachary Haber
Zachary Haber

Reputation: 11027

You were mostly there with your code. The most important thing to note, :empty means nothing for inputs. It will always be applied because inputs can't have children.

Though the :placeholder-shown is pretty much the main workaround to styling an empty input.

I removed most of the :empty styles and replaced some with :placeholder-shown.

The other thing I did was I set up the focus and not-empty transitions to be the same.

input:not(:focus)::placeholder {
  opacity: 0;
}

This makes it so the placeholder is hidden only when it's not focused.

Here's the full results:

.container {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.material-textfield {
  position: relative;
}

label {
  position: absolute;
  font-size: 1rem;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  background-color: white;
  color: gray;
  padding: 0 0.3rem;
  margin: 0 0.5rem;
  transition: 0.1s ease-out;
  transform-origin: left top;
  pointer-events: none;
}

input {
  font-size: 1rem;
  outline: none;
  border: 1px solid gray;
  border-radius: 5px;
  padding: 1rem 0.7rem;
  color: gray;
  transition: 0.1s ease-out;
}

input:focus {
  border-color: #6200ee;
}

input:focus+label {
  color: #6200ee;
  top: 0;
  transform: translateY(-50%) scale(0.9) !important;
}

input:not(:placeholder-shown)+label {
  top: 0;
  transform: translateY(-50%) scale(0.9) !important;
}

input:not(:focus)::placeholder {
  opacity: 0;
}


}
<div class="container">
  <div class="material-textfield">
    <input placeholder="placeholder" type="text" />
    <label> label</label>
  </div>
</div>

That all being said, there are some accessibility issues with the Material Design shrink labels. So, just make sure you are aware of potential issues.

https://www.matsuko.ca/blog/stop-using-material-design-text-fields/

Upvotes: 6

Related Questions