基于 em 单位的有问题的 CSS 转换

Problematic CSS transition based on em units

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

我尝试仅对高度、font-size 和 line-height 进行动画处理,但这并不能解决问题。似乎浏览器对 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/

不幸的是,浏览器似乎只是以不同的方式处理转换。您需要做的是将浏览器前缀附加到 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>

我建议实现相同的目标,但使用不同的方法。我会使用 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>