首页 > 解决方案 > 聚焦或包含文本时在文本输入上浮动标签

问题描述

我有一个要设置动画的搜索栏,以便标签从文本输入上方移动到其上方。我在 fireship.io 视频中找到了一个很好的例子,它使用了这里找到的 CSS 和 html

在那个例子中,我得到了我想要的行为和样式,当输入文本时,Label 会移动到上面并停留在那里,或者如果你不输入任何内容,就会向下移动,这与 Material UI 中的内容非常相似

当我尝试它时,我得到了一半的行为,当我专注于文本输入时,我让标签移动,但不管我是否输入文本,它都会向后移动:

文本已输入,但仍聚焦

输入文本但未聚焦后,标签应保持在上方

这是我正在使用的特定 HTML 和 CSS,它们位于 React 应用程序和使用 VSCode 的 Live SASS Watcher 扩展“编译”的 SCSS 文件中:

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);    
    }
}

我已经尝试了一些不同的修复,我在 StackOverflow 和其他地方都找到了。首先是使用“必需”属性,如下所示:

<input type="text" name="Search" class="input" required/>

.SearchBar:focus-within {
    border-color: transparent;
    .label, .input:valid + .label {
        transform: scale(0.8) translateY(-5rem);    
    }
}

这会产生相同的结果:

我还尝试移动:

.label, .input:valid + .label {
    transform: scale(0.8) translateY(-5rem);    
}

所以它在上述两种解决方案的“.SearchBar:focus-within”类和伪类之外,我得到了同样的东西。

接下来的事情就是在这里找到的。虽然这是专门针对自动填充的,但我想我会试一试,再一次,结果和以前一样......

我尝试过的另一件事是使用“&”而不是像上面那样嵌套类:

.SearchBar:focus-within {
    border-color: transparent;
    .input {
        &:focus, &:not(:placeholder-shown) &:-webkit-autofill{
            &+label {
                transform: scale(0.8) translateY(-5rem);
            }
        }    
    }   
}

再一次,这产生了完全相同的东西。我显然错过了一些东西,但似乎无法确定它是什么。我可以像现在一样让标签在聚焦或不聚焦时移动,或者让它永久位于文本输入上方,这是我想要的“最终”状态。

任何想法,将不胜感激

标签: htmlcssreactjssass

解决方案


您可以使用 :valid css 选择器来确保输入中有文本并保持 :focus

HTML:

<div class="SearchBar">
   <input type="text" name="Search" class="input" required/>
   <label class="label" for="Search">Search</label>
</div>

CSS:

.SearchBar {
  position: relative;
  width: 400px;
  margin: 5rem auto;
}

.input {
  display: block;
  border: 1px solid #000;
  outline: none;
  padding: 1rem;
  font-size: 2rem;
  font-weight: bold;
  z-index: 2;
  width: 400px;
}

.label {
  z-index: 1;
  font-size: 2rem;
  color: #888;
  position: absolute;
  top: 15px;
  left: 1rem;
  vertical-align: middle;
  transform-origin: 0%;
  transition: all ease-in-out 400ms;
  pointer-events: none;
}

.SearchBar {
  .input:valid + .label {
    color: #000;
    transform: scale(0.75) translateY(-4rem) translateX(-0.8rem);
  }
}

这里的工作示例


推荐阅读