为溢出属性设置动画

时间:2015-06-26 07:50:53

标签: css css3 overflow css-animations keyframe

我需要为高度设置动画,并为第一个关键帧设置overflow: hidden,为最后一个关键帧设置overflow: visible(并保留)。

我正在尝试这一点,但最后,overflow仍然是hidden

我该如何解决这个问题?

2包括仅仅是SCSS polifill mixins。

@include keyframes(open) {
  0% {
    height: 0;
    overflow: hidden;
  }
  100% {
    height: $main_menu_height;
    overflow: visible;
  }
}


#main-menu-box {
    overflow: hidden;
    height: 0;

    &.opened{
       @include animation('open 200ms ease-out 0s 1 normal forwards');
    }
}

3 个答案:

答案 0 :(得分:2)

溢出属性无法使用CSS进行动画处理。请参阅此处的W3规范:overflow properties

  

动画:否

您还可以在MDN上查看可设置动画的属性列表:Animated properties

解决方法:

如果需要更改overflow属性,可以使用JS。这是jQuery库的一个例子。

overflow属性随类切换而变化。单击div时会触发它:



$('#w').click(function() {
  $(this).toggleClass('open');
});

#w {
  width: 100px;
  height: 100px;
  border: 1px solid red;
  overflow: hidden;
}
#w.open {
  overflow: visible;
}
#w div {
  height: 200px;
  width: 50px;
  background: gold;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="w">
  <div></div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

The solution is to use AnimationEvent listeners. Here's my raw implementation:

CSS

• 2 animations (open, close)

• 2 classes (opened, closed)

• 2 states (overflow hidden/visible)

opened and closed are always toggled at animationstart, while hidden/visible states are differently worked out on animationend.

Note: you'll see a #main-menu element: it's an UL with transitioned translations on y-axis, because the whole thing is a menu slide-down/up effect.

    @include keyframes(open) {
       0% {
         height:0;
       }
       100% {
         height:$main_menu_height;
       }
    }

    @include keyframes(close) {
       0% {
         height:$main_menu_height;
       }
       100% {
         height:0;
       }
    }


 #main-menu-box{
    overflow-y:hidden;
    height:0; // js

    &.closed{
        @include animation('close 200ms ease-out 0s');
    }

    &.opened{
        @include animation('open 200ms ease-out 0s 1');

        //#main-menu{
        //  @include translate(0, 0);
        //}
    }

    &.overflow-hidden{
        overflow-y:hidden;
    }

    &.overflow-visible{
        overflow-y:visible;
    }
 }

JS

• hamburger is a simple on/off button

• for now I had to use both jquery and vanilla selectors..

function poly_event_listener(element, type, callback) {
    var pfx = ['webkit', 'moz', 'MS', 'o', ''];
    for(var i=0; i<pfx.length; i++) {
        if (pfx[i] === '') type = type.toLowerCase();
        element.addEventListener(pfx[i]+type, callback, false);
    }
}

var hamburger = $('header .hamburger');
var main_menu_box = $('#main-menu-box');
var main_menu_box_std = document.querySelector('#main-menu-box');
var init_menu = true;

hamburger.click(function(){
  if(init_menu){
    main_menu_box.addClass('opened');
    init_menu = false;
    return;
  }

  main_menu_box.toggleClass('opened closed');
});

poly_event_listener(main_menu_box_std,'AnimationStart',function(e){
  main_menu_box.addClass('overflow-hidden');
  main_menu_box.removeClass('overflow-visible');
});

poly_event_listener(main_menu_box_std,'AnimationEnd',function(e){

  // in all the other cases I want hidden:true, visible:false
  // if class == closed, since animationend comes after animationstart, the state will already be hidden:true, visible:false
  // so non need to check for 'closed' here
  if(main_menu_box.hasClass('opened')){
    main_menu_box.addClass('overflow-visible');
    main_menu_box.removeClass('overflow-hidden');
  }
});

This works for me.

答案 2 :(得分:0)

在大多数现代浏览器中,clip-path(在Safari中以-webkit-前缀)是可设置动画的属性,有时可以用作overflow的替代品。

以原始示例为例,最接近的使用clip-path模拟最后一帧上的overflow翻转的方式如下所示:

@include keyframes(open) {
  0% {
    height: 0;
    clip-path: inset(0);
  }
  99.99999% {
    clip-path: inset(0);
  }
  100% {
    height: $main_menu_height;
    clip-path: inset(-100vh -100vw);
  }
}

#main-menu-box {
  clip-path: inset(0);
  height: 0;

  &.opened {
     @include animation('open 200ms ease-out 0s 1 normal forwards');
  }
}

由于此动画是简单的线性动画,因此甚至可以用常规的CSS过渡替换:

#main-menu-box {
  clip-path: inset(0);
  height: 0;
  transition: clip-path 0s ease-out, height 200ms ease-out;

  &.opened {
    height: $main_menu_height;
    clip-path: inset(-100vh -100vw);
    transition-delay: 200ms, 0s;
  }
}

但是,clip-pathoverflow之间存在两个显着差异,这使其不适用于所有情况。

首先,与具有overflow: visible的元素不同,具有任何clip-path的元素具有stacking context,因此呈现溢出内容的方式将有所不同-尽管在菜单中包含大量内容,您可能还是想要这样做!

第二,不同于overflow仅剪切子元素,clip-path剪切 entire 元素。这意味着,如果您有边框,框阴影等,它们也会被剪切。根据容器的设计,有时可以通过将夹子应用于子包装器元素来解决此问题。