Question

I'm trying to build a list of elements with dynamic height and number, that slide up and down when a user clicks on them. The thing is, only one of them must be revealed at the time, while the others automatically slide up after it is clicked on.

I'm having issues with the elements located below the one that is being slid down. They seem to jump down, then up again to their correct place, by about 7px (I assume it's the 5px margin-top of div.text + 2px of a border).

The sliding div:

<div class="slide">
    <div class="bar">
        <a href="#" class="title">Slide #1</a>
    </div>
    <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sed odio nulla. Pellentesque auctor molestie ipsum, ut lobortis mauris laoreet id. Praesent ut dolor sed dui euismod mattis a at nisl. Etiam mi dolor, placerat eget feugiat nec, tempus id risus. Ut sed lobortis arcu. Fusce vestibulum enim sed quam tristique sagittis. Etiam at tempor enim. 
    </div>
</div>

The script I use to slide them up/down.

$('.text').hide();
$('.slide .bar a').click(function(){
    if($(this).parent().next('.text').is(':hidden')){
        $('.text').slideUp(200);
        $(this).parent().next('.text').slideDown(200);
    }
    else if($(this).parent().next('.text').is(':visible')){
        $(this).parent().next('.text').slideUp(200);
    }

});

To better illustrate, a fiddle: http://jsfiddle.net/Q682D/1/

Any simple way to fix this? I'd like to keep the border and margin, or at least keep the div.texts looking the same way as they do now.

Was it helpful?

Solution

I was able to get the look you were after, with out the "jumping", with the Accordion method below, it seems that this will likely be the better of the two options.

Accordion Method

jQuery UI Accordion

jsFiddle

css

a {
    text-decoration: none;
    color: #252525;
}
.bar {
    border-radius: 6px;
    box-shadow: 0 0 0 1px #bbb;
    height: 34px;
    border: 1px solid #eacec3 !important;
    background: #ddb09e;
    /* Old browsers */
    filter: none !important;
    box-shadow: inset 0 -17px 30px 0 #c98c75, 0 0 0 1px #84413f;
    width: 400px;
    margin-bottom:0.5em;
}
.text {
    background: #fff;
    border: 1px solid #aaa;
    border-radius: 6px;
    font: 14px'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;
    padding: 10px;
    width: 365px;
}
.title {
    float: left;
    font: bold 17px'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;
    line-height: 35px;
    margin-left: 12px;
    text-decoration: none !important;
    text-shadow: -1px -1px 0px rgba(0, 0, 0, 0.2), 1px 1px 0px rgba(255, 255, 255, 0.3);
    vertical-align: middle;
}
.ui-accordion .ui-accordion-header {
    display: block;
    cursor: pointer;
    position: relative;
    padding:0;
}
.ui-accordion .ui-accordion-content {
    padding: 1em 1.2em;
    border-top: 1px solid #aaa;
    overflow: auto;
}
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited {
    color: #000;
    text-decoration: none;
}
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
    background:none;
    font-weight: normal;
    color: #fff;
    width:400px;
    border: 1px solid #fff;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
    position: absolute;
    left: 0;
    top: 40%;
    margin-top: -8px;
}

js

 $(function () {
     $("#accordion").accordion({
         collapsible: true,
         active: false
     });
 });

html

<div id="accordion">
    <div>
        <div class="bar"> <a href="#" class="title">Slide #1</a>
        </div>
    </div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        <br>
        <form>Text:
            <input type="text">
            <br>
            <input type="checkbox">
            <br>
            <input type="radio">
            <br>
            <input type="button" value="Button">
        </form>
    </div>

slideDown / slideUp Method

Not as clean, but I got most of the jump out using box-sizing:border-box; and reorganizing things a bit. There is still a slight flicker, but maybe this will steer you in the right direction.

jsFiddle2

css

a {
    text-decoration: none;
    color: #252525;
}
.slide {
    padding-bottom: 15px;
    width: 400px;
}
.bar {
    border-radius: 6px;
    box-shadow: 0 0 0 1px #bbb;
    height: 34px;
    border: 1px solid #eacec3 !important;
    background: #ddb09e;
    /* Old browsers */
    filter: none !important;
    box-shadow: inset 0 -17px 30px 0 #c98c75, 0 0 0 1px #84413f;
    width: 400px;
    margin-bottom:0.25em;
}
.text {
    background: #fff;
    border: 1px solid #aaa;
    border-radius: 6px;
    font: 14px'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;
    padding: 10px;
    width: 400px;
    box-sizing:border-box;
    -moz-box-sizing:border-box;
}
.title {
    float: left;
    font: bold 17px'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;
    line-height: 35px;
    margin-left: 12px;
    text-decoration: none !important;
    text-shadow: -1px -1px 0px rgba(0, 0, 0, 0.2), 1px 1px 0px rgba(255, 255, 255, 0.3);
    vertical-align: middle;
}

Update: I suspect that there may be a bug in the .slideDown() and .slideUp() animation calculations, if you change it to .show() and .hide() the jump disappears.

jsFiddle3

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