【问题标题】:Problematic CSS transition based on em units基于 em 单位的有问题的 CSS 过渡
【发布时间】:2015-12-16 22:58:18
【问题描述】:

我正在尝试创建一种效果,其中位于标题中的锚元素在悬停时自行放大,同时保持元素的宽度和高度,使其适合标题并且不会移动或影响任何其他元素方式。 动画在 Chrome 中运行良好,但在 Mozilla、Firefox 和 Edge/IE 中,过渡效果完全不理想。

  • 标题的高度为 4em。
  • 要设置动画的锚元素的默认字体大小是 2em。宽度和高度也是 2em (2*2 = 4em 所以我得到了完美 适合标题的方块)。
  • 悬停时,我将字体大小更改为 2.5em,宽度和高度都更改为 1.6em(2.5*1.6 = 标题高度的 4em)

我尝试只为高度、字体大小和行高设置动画,但这并不能消除问题。浏览器似乎对 em 单位定义的宽度和高度感到困惑,因此它们首先缩小内容然后再放大。不过,这种行为在 Chrome 中并不存在,一切正常。

这个问题有什么解决方案,因为我想避免使用 px 单位,因为网站的响应性更容易实现。或者我应该改用 px 单位并为网站使用更多媒体查询?

有问题的代码:

<!-- Header -->
        <div id="header">
            <nav class="nav-buttons">
                <a href="#">L1</a>
                <a href="#">L2</a>
                <a href="#">L3</a>
            </nav>
        </div>

CSS:

#header {
  position: fixed;
  height: 4em;
  width: 100%;
}

/* global element settings */
a,
a:link,
a:visited,
a:hover,
a:active{
    text-decoration: none;
}
/* navigation buttons */

.nav-buttons > *,
.nav-buttons > *:visited {
  display: inline-block;
  vertical-align: middle;
  text-align: center;
  font-size: 2em;
  font-weight: 700;
  line-height: 2em;
  margin: 0;
  padding: 0;
  width: 2em;
  height: 2em;
  /*text-shadow: 0 0 0.1em #555555;*/
  transition-property: height, line-height, font-size, text-align, vertical-align;
  transition-duration: 0.3s;
}

.nav-buttons > *:hover,
.nav-buttons > *:active,
.button-active {
  transition-property: height, line-height, font-size, text-align, vertical-align;
  transition-duration: 0.3s;
  font-size: 2.5em;
  line-height: 1.6em;
  width: 1.6em;
  height: 1.6em;
}

伴随的JSFiddle: https://jsfiddle.net/2futafsw/3/

【问题讨论】:

    标签: html css css-transitions em


    【解决方案1】:

    我建议实现相同的目标,但使用不同的方法。我会使用 transform 属性。代码少,效果一样,一般是well supported

    DEMO

    对于您的特定问题,在我看来 font-size 转换由于某种原因在 moz 上触发较晚;我不知道为什么。

    * {
      box-sizing: border-box;
    }
    
    body {
      font-size: 16px;
    }
    
    header {
      position: fixed;
      height: 4em;
      width: 100%;
    }
    
    a {
    	color: inherit;
    	text-decoration: none;
    }
    
    nav a {
    	display: inline-block;
      text-align: center;
      line-height: 2em;
    	font-size: 2em;
    	height: 2em;
    	width: 2em;
      transition: all 300ms;
    }
    
    nav a:hover {
      transform: scale(1.5);
      
    }
    <header>
      <nav>
        <a href="#">L1</a>
        <a href="#">L2</a>
        <a href="#">L3</a>
      </nav>
    </header>

    【讨论】:

    • 在使用这种方法时,我实际上注意到了一些文本混叠问题(文本边缘变得有点模糊),所以我宁愿避免使用它,除非我真的需要使用它。编辑:嗯,我在 webkit 浏览器中注意到了它,并没有费心在其他浏览器中进行测试。
    • 这很整洁。我也注意到了模糊,但我以为只是我,因为我没有戴眼镜。有什么方法可以做到这一点摆脱模糊?
    • 这里其实有一些建议:css-tricks.com/forums/topic/… 虽然有很多解决方案有时有效,有时无效,但不是一个确定的。
    • @AleksandarBencun 你可以摆脱模糊,这只是一个简单的例子,向你展示了一个“更好”的替代方案。只需从已经缩放的元素开始;将需要调整 - DEMO
    • 这是一个很好的解决方法。但是,我将您之前的演示与新演示进行了比较,Chrome 中的别名基本上没有区别。转换非常好,但这次转换必须对我有用,因为我一直在将它们用于其他一些非常依赖于这个的动画系统,现在切换到转换会很痛苦。但是您的回答提供了一个非常巧妙的解决方案。
    【解决方案2】:

    不幸的是,看起来浏览器只是以不同的方式处理转换。您需要做的是将浏览器前缀附加到 transition-property 规则并相应地应用样式。

    对于 FireFox,即 -moz-transition-property,Chrome / Safari 是 -webkit-transition-property

    我已经稍微简化了你的转换。 Chrome 仅使用字体大小就可以正常工作,而 FireFox 需要在边缘添加动画(这很有趣,会弄乱 Chrome 动画)。

    #header {
      position: fixed;
      height: 4em;
      width: 100%;
    }
    
    /* global element settings */
    a,
    a:link,
    a:visited,
    a:hover,
    a:active{
    	text-decoration: none;
    }
    
    .nav-buttons > a,
    .nav-buttons > a:visited {
      display: inline-block;
      vertical-align: middle;
      text-align: center;
      font-size: 2em;
      font-weight: 700;
      line-height: 2em;
      margin: 0;
      padding: 0;
      width: 2em;
      height: 2em;
      -moz-transition-property: font-size, margin;
      -webkit-transition-property: font-size;
      transition-duration: 0.3s;
    }
    
    .nav-buttons > a:hover,
    .nav-buttons > a:active,
    .button-active {
      transition-duration: 0.3s;
      font-size: 2.5em;
      margin: -.20em;
    }
    <!-- Header -->
    <div id="header" class="">
      <nav class="nav-buttons">
        <a href="#" class="glyphicon glyphicon-menu-hamburger">a</a>
        <a href="#">L1</a>
        <a href="#">L2</a>
        <a href="#">L3</a>
      </nav>
    </div>

    【讨论】:

    • 那么,您基本上是在建议我尝试使用负边距来否定悬停时整个元素的缩放?
    • 对于 FireFox,是的。这会导致 Chrome 出现问题。您必须使用 CSS 转换(-moz-webkit-ms 等)单独完成它们,或者使用@Quoid 在他的答案中提供的 CSS 转换。
    • 在尝试了您的解决方案后,我发现它不适用于 IE 和 Edge。我尝试过使用和不使用前缀以及使用和不使用边距转换。看起来我可能不得不切换到转换或避免在 IE/Edge 中为任何东西设置动画。
    猜你喜欢
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2012-10-25
    • 2020-01-11
    • 2012-04-08
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多