【问题标题】:-webkit-appearance forcing transitions?-webkit-appearance 强制转换?
【发布时间】:2023-03-12 06:51:01
【问题描述】:

给定一个基本的 HTML 模板和 CSS 样式,我看到两个不同的元素反应完全不同。

setTimeout(function() {
  document.body.id = 'animate';
}, 100);
#animate input[type="checkbox"]{
  width: 100px;
  height: 100px;
  transition: 2s all;
  -moz-appearance: none;
}
#animate div{
  width: 100px;
  height: 100px;
  background:blue;
  transition: 2s all;
}
<input type="checkbox"/>
<div></div>

如果你在浏览器中打开它,你会看到,在加载时,div 已经有 100 像素的高度/宽度,但复选框在 2 秒内从 0 像素增长到 100 像素的高度/宽度。

为什么input 的行为与div 不同?是因为输入有默认的-webkit-appearance 让它可以在它们之间进行转换吗?

【问题讨论】:

  • 看起来确实如此。虽然我似乎在Webkit's user agent stylesheet, except for in iOS 中找不到input[type=checkbox] 的任何widthheight 声明。我可能是错的。
  • @darrylyeo 我也找不到任何东西,当在元素检查器中切换它们时,它们又回到了 0。这让我更加困惑。
  • 有趣的是,将鼠标悬停在 Chrome 开发者工具的“计算”选项卡中的 widthheight 条目上时,没有箭头可以将您带到源代码!
  • 我相信这是因为 div 没有将高度/宽度设置为默认样式(默认情况下,它的宽度是其容器的 100%,它的高度由它的内容决定),而复选框具有用作起点的默认大小。如果没有起点,过渡后的元素只会以指定的大小开始。

标签: css css-transitions webkit-appearance


【解决方案1】:

div 的默认宽度/高度是自动的,因此它不会动画。

input 具有默认宽度/高度,因此会生成动画。

顺便说一句,过渡确实适用于div,虽然只是为其颜色设置动画,因为可以将颜色从transparent 设置为动画blue

您还应该考虑不要alltransition 一起使用,因为浏览器确实将元素上的某些值设置为默认值,这可能会产生不可预测的结果,有些可以动画,有些不能。

因此,在您的情况下,如果您打算为宽度/高度设置动画,请按如下方式设置:transiton: width 2s ease, height 2s ease;

【讨论】:

  • 这些默认高度/宽度在哪里?如果你在元素检查器中看不到任何东西,它是否存储在 -webkit-appearance: checkbox; 中?
  • @DasBeasto 被替换的元素可以具有固有大小。例如,&lt;img&gt; 元素具有图像的大小,并且该大小不是来自 CSS 级联。
  • @DasBeasto 不,元素默认值在用户代理样式表中设置。如果您使用 Chrome 检查某个元素,其中一些值会以灰色背景显示,而另一些则不是
  • @Oriol 图片好点,我一直认为用户代理样式总是显示,但我意识到有些(很多?)不是,谢谢!
  • @DasBeasto 会发生什么,例如最初的width: auto 可以解析为不同的长度,具体取决于各种情况。 CSS 检查器通常会显示所有声明的值或级联值,因此您可能不会注意到生成的使用值或实际值。
【解决方案2】:

答案很简单。 input 的样式在 DOM 中有一个预加载的值,这就是为什么刚出现在文档中后,就可以平滑地改变他的形状。

div 元素完全相反。在用户设置它们之前,div 在 DOM 中没有任何 预加载的默认值。这就是为什么它以已设置的大小出现在文档中的原因。

重要提示
如果您希望转换工作,它必须有一个设置、起始、默认值和结束值。动画将发生在这两个值之间。 input 已经设置了大小的默认值,这就是动画发生的原因。

您可能会问,为什么background 转换有效?它可以工作,因为background 的默认值是透明

setTimeout(function() {
  $('.xx').addClass('x');
}, 500);
* {
  margin: 0;
  padding: 0;
  border: 0;
}
input[type="checkbox"] {} div {} .x {
  width: 100px;
  height: 100px;
  transition: all 2s ease;
  background: blue;
}
.container {
  display: flex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>

  <input type='checkbox'>
  <div class='xx'></div>
  <input class='xx' type="checkbox">

</div>

【讨论】:

  • @DasBeasto 你让我很失望,即使我提供了最有价值的答案,你还是将另一个标记为最佳答案。我真的很失望。
  • 那不行,@K.Daniek。见stackoverflow.com/help/accepted-answer
  • @K.Daniek LGSon 充分回答了我的问题。在我看来,您的回答提供了与 LGSon 相同的信息。除了他是第一个,所以我接受了。
【解决方案3】:

没有技术含量的简短回答。当有一个先前的状态开始动画时,CSS 过渡将完成它的工作。

默认的div 默认没有任何样式。 input 元素始终在浏览器本身中预先设置样式。

这是一个小提琴,可用于重新创建 OP 提到的行为。它通过简单的 JS 延迟来模拟外部加载。 https://jsfiddle.net/xvt359ju/1/

没关系,另外 2 个答案比我快。

【讨论】:

    【解决方案4】:

    浏览器有自己的基本 CSS 元素样式,复选框也有。当您检查元素时,您可以看到浏览器应用的复选框的宽度和高度,当您的外部样式表加载时,这将被覆盖。并在您对其进行过渡时对其进行动画处理。

    【讨论】:

      猜你喜欢
      • 2017-05-09
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      相关资源
      最近更新 更多