   ###
   open: ->
     @height ?= @getHeight()
-    goog.style.setElementShown @dropupElement, true
+    goog.style.setElementShown(@dropupElement, true)
     animation = @getAnimation(0, @height)
+    CLS = wzk.ui.dropup.Dropup.CLS
+
+    animation.listen goog.fx.Animation.EventType.BEGIN, (event) =>
+      for el in @getAllElements()
+        goog.dom.classes.addRemove(el, CLS.CLOSED, CLS.OPENED)
 
     animation.listen goog.fx.Animation.EventType.FINISH, (event) =>
-      goog.dom.classes.remove el, wzk.ui.dropup.Dropup.CSS.COLLAPSE for el in [@dropupElement, @dropupButton]
+      goog.dom.classes.remove(@dropupElement, CLS.COLLAPSE)
       @swapClasses()
 
     animation.play()

    animation

  ###*
    @return {number} actual computed height of element
  ###
  getHeight: ->

  ###
  decorate: (@dropupButton) ->
    # arrow span, allowing change of icon according to state
    @caretElement = @dom.cls(wzk.ui.dropup.Dropup.CLS.CARET, @dropupButton)

    # id of tag to dropup
    dropupSelector = goog.dom.dataset.get(@dropupButton, wzk.ui.dropup.Dropup.DATA.TARGET)
    unless dropupSelector?
      throw new Error "Dropup button element has no '#{wzk.ui.dropup.Dropup.DATA.TARGET}' attribute!"

    # find element with id or class
    @dropupElement = @dom.one "##{dropupSelector}, .#{dropupSelector}", @dom.getDocument()
    unless @dropupElement?
      console.warn("Dropup element with specified id or class  '#{dropupSelector}', does not exist!")
      return

    # hide dropupElement right after registering
    goog.style.setElementShown(@dropupElement, false)

    # set overflow property
    goog.style.setStyle(@dropupElement, 'overflow', 'hidden')

    # when animation is running, lock is set to true
    @animationLock = false

    # register handler for button
    goog.events.listen(@dropupButton, goog.events.EventType.CLICK, @toggle)

  ###*
    @protected
