I am trying to create an animated search bar where the label moves from being over the text input to above it. I came across a helpful example in a fireship.io video, which includes the CSS and HTML code available here
The example I found demonstrates the behavior and style I want, with the label moving above and staying there when text is entered, similar to Material UI.
However, when I implement it, I only get half of the desired behavior - the label moves when I focus on the text input but then moves back regardless of entering text:
https://i.stack.imgur.com/q4pu4.jpg
https://i.stack.imgur.com/g0GXq.jpg
https://i.stack.imgur.com/xDcPB.jpg
Below is the specific HTML and CSS code I am using within a React App and SCSS file compiled using VSCode's Live SASS Watcher extension:
function searchBar() {
return (
<div class="SearchBar">
<input type="text" name="Search" class="input" placeholder=""/>
<label class="label" for="Search">Search...</label>
</div>
)
}
.SearchBar {
@extend .base;
flex-direction: column;
position: relative;
border-bottom: 2px dashed var(--text-primary);
width: 50vw;
margin: 3vh auto 3vh;
.input {
border: none;
outline: none;
overflow: hidden;
justify-content: center;
align-content: center;
padding: 1rem;
background: none;
color: var(--text-primary);
letter-spacing: normal;
text-transform: none;
font-size: 2rem;
font-weight: bold;
z-index: 2;
width: 75vw;
}
.label {
color: var(--text-primary);
z-index: 1;
position: absolute;
transform-origin: 0%;
transition: transform 400ms;
}
}
.SearchBar::after {
content: "";
position: relative;
display: block;
height: 4px;
width: 50vw;
background: #1625ff;
transform: scaleX(0);
transform-origin: 0%;
transition: transform 500ms ease;
top: 2px;
}
.SearchBar:focus-within {
border-color: transparent;
.label, .input:not(:placeholder-shown) + .label {
transform: scale(0.8) translateY(-5rem);
}
}
I have tried various fixes suggested in StackOverflow and other platforms without success. For instance, adding the "required" attribute did not yield the desired outcome:
<input type="text" name="Search" class="input" required/>
.SearchBar:focus-within {
border-color: transparent;
.label, .input:valid + .label {
transform: scale(0.8) translateY(-5rem);
}
}
Similarly, moving the transformation outside the ".SearchBar:focus-within" class did not resolve the issue:
.label, .input:valid + .label {
transform: scale(0.8) translateY(-5rem);
}
I also attempted a solution related to autofill scenarios, as recommended here, but encountered the same problem once again.
Furthermore, experimenting with alternate syntax like using "&" instead of nesting classes produced no different outcome:
.SearchBar:focus-within {
border-color: transparent;
.input {
&:focus, &:not(:placeholder-shown) &:-webkit-autofill{
&+label {
transform: scale(0.8) translateY(-5rem);
}
}
}
}
I seem to be overlooking something crucial and unable to pinpoint the issue. At this stage, I can either achieve the label movement upon focus or have it permanently positioned above the text input, which is the final state I desire. Any insights or suggestions would be greatly appreciated.