【问题标题】:transform: translateY(-50%) causes 1px jump/shift in IE and EDGEtransform: translateY(-50%) 在 IE 和 EDGE 中导致 1px 跳跃/移位
【发布时间】:2017-10-22 08:53:39
【问题描述】:

请参阅 jsfiddle 中的示例。 https://jsfiddle.net/0uwmxt02/1/

在 IE 和 EDGE 中,transform: translateY(-50%) 会导致动画开始和结束时上下跳跃 1px。在 Chrome 中,位移仍然会发生,但它是平滑的。知道是什么原因造成的吗?

.submenu-arrow-hover {
  position: relative;
  width: 200px;
  top:50px;
 }
  
 .submenu-arrow-hover:after {
    //background: rgba(155, 173, 188, 0.9);
    position:absolute;
    content:'';
    width: 1px;
    height: 28px;
    border: 1px solid red;
    border-right:0;
    border-top:0;
    top:50%;
    right:-1px;
    transform-origin: 0 0;
    transform: translateY(-50%);
    transition-duration: .3s;
  }
  
.submenu-arrow-hover:hover::after {
      //background: rgba(155, 173, 188, 0.9);
      position:absolute;
      content:'';
      width: 20px;
      height:20px;
      border: 1px solid red;
      border-right:0;
      border-top:0;
      top:50%;
      right:-1px;
      transform-origin: 0 0;
      transform: translateY(-50%) rotate(45deg);
}
<div class="submenu-arrow-hover">HOVER ME</div>

【问题讨论】:

    标签: css css-transitions


    【解决方案1】:

    似乎在平移和旋转之间存在某种混淆。作为一种解决方法,请尝试完全删除 translateY() 要求:

    .submenu-arrow-hover {
      position: relative;
      width: 200px;
      top: 50px;
      
      /* outline and excess height added as a test */
      outline: 1px dotted #ccc;
      height: 100px;
    }
    
    .submenu-arrow-hover::after {
      position: absolute;
      content: '';
      width: 1px;
      height: 28px;
      border: 0;
      border-left: 1px solid red;
      border-bottom: 1px solid transparent;
      right: -1px;
      transform-origin: 0 0;
      transition-duration: .3s;
      
      /* position top of pseudo element halfway down */
      top: 50%;
      margin-top: -14px; /* accurately centre by offsetting by half the height */
    }
    
    .submenu-arrow-hover:hover::after {
      width: 20px;
      height: 20px;
      border-bottom-color: red;
      transform: rotate(45deg);
    }
    <div class="submenu-arrow-hover">HOVER ME</div>

    编辑:更新以确保箭头在父 <div/> 中垂直居中。

    【讨论】:

    • 我需要 translateY,将箭头水平准确地定位在父 div 的中间。
    • 因为元素将具有可变高度(例如,当屏幕尺寸减小时折叠成两行)我不能使用像素值。我最终不得不使用 jQuery 来动态调整位置...
    【解决方案2】:
    • 等于 .submenu-arrow-hover:afterheight.submenu-arrow-hover:hover::after 的 (20px),否则高度异步会使其反弹。

    .submenu-arrow-hover {
      position: relative;
      width: 200px;
      top: 50px;
    }
    
    .submenu-arrow-hover:after {
      //background: rgba(155, 173, 188, 0.9);
      position: absolute;
      content: '';
      width: 1px;
      height: 20px;
      border: 1px solid red;
      border-right: 0;
      border-top: 0;
      top: 50%;
      right: -1px;
      transform-origin: 0 0;
      transform: translateY(-50%);
      transition-duration: .3s;
    }
    
    .submenu-arrow-hover:hover::after {
      //background: rgba(155, 173, 188, 0.9);
      position: absolute;
      content: '';
      width: 20px;
      height: 20px;
      border: 1px solid red;
      border-right: 0;
      border-top: 0;
      top: 50%;
      right: -1px;
      transform-origin: 0 0;
      transform: translateY(-50%) rotate(45deg);
    }
    <div class="submenu-arrow-hover">HOVER ME</div>

    【讨论】:

      【解决方案3】:

      我最终不得不使用 jQuery,因为元素将具有可变高度,并且在调整屏幕大小和元素改变大小/位置时需要调整箭头位置。

          function setMargins(arrow) {
          parentHeight = $(arrow).parent().height();  
          arrowHeight = $(arrow).height();  
          topMargin = (parentHeight - (arrowHeight - 1)) / 2 ;    
          $(arrow).css("margin-top", topMargin);    
      }
      
      
      $(document).ready(function(){
          $('.submenu-arrow-hover--arrow').each(function() {
          setMargins(this);
      })
      });
      
      // timeout function needed as there is transition on the menu elements so
      // function has to fire few milliseconds after the transitions have finished animating
      
      $(window).resize(function() {
          setTimeout(function(){
          $('.submenu-arrow-hover--arrow').each(function() {
      
              setMargins(this)            
          })    
      }, 600);
      });
      

      【讨论】:

        【解决方案4】:

        对于 Chrome,this StackOverflow answer 工作得非常好!

        将此添加到已应用 translateY 的元素:-webkit-backface-visibility: hidden;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-22
          • 2015-01-10
          • 1970-01-01
          • 2020-01-17
          • 2017-06-18
          相关资源
          最近更新 更多