Question

I have this jsfiddle where I'm trying to create an accordion purely with CSS3 and animations.

The setup is fairly simple: a checkbox (with state checked or unchecked) controls whether the content div should be collapsed or not. The checkbox is hidden and controlled by the label.

This principle works fine, the animation however does not. All I want is the div to slide open and closed.

HTML

<div class="accordeon">
    <input type="checkbox" name="accordeon-title" class="accordeon-checkbox" id="accordeon-title" /><label for="accordeon-title" class="accordeon-title-label">Accordeon titel</label>
    <div class="accordeon-content">
        Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet.
    </div>
</div>

CSS3

 /*Init*/
    .accordeon-checkbox {display: none;}
    .accordeon-title-label {cursor: pointer; background: #c4c4c4; display: block;}
    .accordeon-content {height: 0; overflow:hidden; line-height: 0;}

    /*Click functionaliteit*/
    .accordeon:checked + label {background: #e4e4e4;}
    .accordeon-checkbox:checked ~ .accordeon-content {  
        -webkit-animation: slide-up 5s; /* Safari 4+ */
        -moz-animation:    slide-up 5s; /* Fx 5+ */
        -o-animation:      slide-up 5s; /* Opera 12+ */
        animation:         slide-up 5s; /* IE 10+ */

        -webkit-animation-timing-function:ease;
        -moz-animation-timing-function:ease;
        -o-animation-timing-function:ease;
        animation-timing-function:ease;

        line-height: inherit; overflow: visible; height: 100%;
    }   

    /*Animation functionality*/
    @-webkit-keyframes slide-up {
        0%   { height: 0; }
        100% { height: 100%; }
    }
    @-moz-keyframes slide-up {
        0%   { height: 0; }
        100% { height: 100%; }
    }
    @-o-keyframes slide-up {
        0%   { height: 0; }
        100% { height: 100%; }
    }
    @keyframes slide-up {
        0%   { height: 0; }
        100% { height: 100%; }
    }
Was it helpful?

Solution

First of all, please note that once the checkbox is checked, you are re-setting the height, line-height and overflow properties. Hence the animation doesn't have any effect in this case.

Also, height: 100% doesn't affect the element as its parent doesn't have an explicit height. So you'll need to use a fixed value for height property.

In addition, CSS animation is unable to animate the overflow property, and line-height properly (specially by inherit value).

In order to stop the animation at the end keyframe, you should use animation-fill-mode property with forwards value.

Here is the shorthand version:

.accordeon-checkbox:checked ~ .accordeon-content {
    -webkit-animation: slide-up 1s ease forwards;
    /* Safari 4+ */
    -moz-animation: slide-up 1s ease forwards;
    /* Fx 5+ */
    -o-animation: slide-up 1s ease forwards;
    /* Opera 12+ */
    animation: slide-up 1s ease forwards;
    /* IE 10+ */
}

Demo.

An issue with closing the panel

But there's an issue with using animations. Since the animation is applied to the element only when the checkbox is checked, Once you uncheck the checkbox by the second click, the panel will be closed immediately without any animations.

Hence, it's better to use transitions to achieve the desired effect.

Here you go:

.accordeon-content {
    height: 0;
    overflow:hidden;
    background-color: gold;

    /* other vendor-prefixes here... */
    transition: height 1s ease;
}

.accordeon-checkbox:checked ~ .accordeon-content {
    height: 400px;
}

Working Demo.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top