首页 > 解决方案 > 输入焦点时 CSS 过渡的方向发生变化

问题描述

在尝试使用 CSS 为输入设置动画以滑出的过程中,我遇到了一些我不理解的行为,希望有人能帮助我理解。本质上,只要输入在转换期间没有获得焦点,转换就会按照我的预期运行。然而,一旦在过渡期间获得焦点,过渡突然看起来“右对齐”而不是“左对齐”,正如我所期望的那样。

这是一个MWE来说明我的意思。如果您不将输入集中得太快,则以下代码段可以正常工作:

let b = document.getElementsByTagName("button")[0];
let container = document.getElementsByClassName("container")[0];

b.addEventListener("click", () => {
  container.classList.toggle("expanded");
});   
.container {
  overflow: hidden;
  width: 0;
  
  transition: 1s width ease;
}

.container.expanded {
  width: 22ch;
}

.margin {
  background: green;
  width: 20ch;
}

input {
  margin-left: 2ch;
  width: 20ch;
}
<button>Press for magic!</button>

<div class="container">
  <div class="margin"><input type="text" value="A quick brown fox..."/></div>
</div>

但是,如果你足够快地聚焦输入,你会得到类似这样的结果(中间转换的屏幕截图):

糟糕的过渡

相比之下,这是我对过渡中期的期望:

良好的过渡

主要区别在于,当不聚焦时,内容显示从左到右(这是我所期望的),而当聚焦时,内容显示从右到左。

谁能向我解释为什么会发生这种行为?我查看了 Chrome 和 Firefox 中输入的用户代理样式,没有看到任何可能导致这种情况的东西。我怀疑这源于我自己对 CSS 过渡如何工作(或者可能是一些 CSS 布局的东西)的误解,所以任何帮助理解这背后的原因将不胜感激!

让我知道我是否应该在这篇文章中添加任何内容来改进它。

标签: htmlcss

解决方案


即使没有过渡,我们也可以重现该问题。只需将输入放在一个较小的容器中并专注于它即可获得奇怪但合乎逻辑的结果:

.container {
  overflow: hidden;
}

.container.expanded {
  width: 100px;
}

.margin {
  background: green;
  width: 20ch;
}

input {
  margin-left: 2ch;
  width: 100%;
}
<div class="container expanded">
  <div class="margin"><input type="text" value="A quick brown fox..."/></div>
</div>

您的输入溢出了容器,而您隐藏了溢出。如果您添加滚动,您会更好地理解

.container {
  overflow: auto;
}

.container.expanded {
  width: 100px;
}

.margin {
  background: green;
  width: 20ch;
}

input {
  margin-left: 2ch;
  width: 100%;
}
<div class="container expanded">
  <div class="margin"><input type="text" value="A quick brown fox..."/></div>
</div>

专注于输入将滚动容器,就这么简单。唯一的区别是您隐藏了滚动,但这并不意味着容器不能滚动。

我无法找到描述此行为的位置1但对我来说这似乎是一个直观的行为,因为我们需要显示焦点元素,为了做到这一点,我们需要滚动一些元素。

这是页面上有许多输入的另一个示例,您可以清楚地看到每次我们需要滚动以显示下一个:

.container {
  overflow: hidden;
  width: 100px;
  white-space:nowrap;
}
input {
  margin-left: 2ch;
  width: 100%;
}
<div class="container expanded">
  <input type="text" value="One"/>
  <input type="text" value="two"/>
  <input type="text" value="three"/>
  <input type="text" value="Four"/>
</div>



  <input type="text" value="five" style="margin-top:200vh"/>

1:应该在规范的这一部分:https ://www.w3.org/TR/html51/editing.html#focus


推荐阅读