JavaScript slidedown without jQuery

Javascript

Javascript Problem Overview


I wish to have a similar effect to jQuery slidedown but without using jQuery or any other libary. I know it's "possible" as anything in jQuery can be done in plain JavaScript. Just harder.

I cannot use jQuery as everything has to be written in my own code without any libaries used.

Has anyone done something like this or any effects just using plain JavaScript?

Javascript Solutions


Solution 1 - Javascript

Since we are in 2014, why not use CSS transitions and just change the height property of the element? Fiddle

CSS:

.wrapper {
    transition:height 1s ease-out;
    height:0;
    overflow:hidden;
}

HTML:

<div id="wrapper">
//content
</div>

JAVASCRIPT:

document.getElementById("wrapper").style.height = //content height +"px";

2020 EDIT (dealing with unknown height):

So we're in 2020 and it's even more obvious now we should rely on CSS effects for this kind of animations.

However, a valid point has been made against this answer - you need to specify the height of the element that you're animating in the js code, and you might not know this value in advance.

So six years later, I'm adding a couple extra lines of code to cover this case.

So if we use the same CSS and HTML as in our old 2014 example, this is the new JS. New Fiddle!

const slideDown = elem => elem.style.height = `${elem.scrollHeight}px`;

slideDown(document.getElementById("wrapper"));

Solution 2 - Javascript

Here is a nice little piece of code I wrote from scratch.
It is purely time based.

var minheight = 20;
var maxheight = 100;
var time = 1000;
var timer = null;
var toggled = false;

window.onload = function() {
	var controller = document.getElementById('slide');
	var slider = document.getElementById('slider');
	slider.style.height = minheight + 'px'; //not so imp,just for my example
	controller.onclick = function() {  
		clearInterval(timer);
		var instanceheight = parseInt(slider.style.height);  // Current height
		var init = (new Date()).getTime(); //start time
		var height = (toggled = !toggled) ? maxheight: minheight; //if toggled
		
		var disp = height - parseInt(slider.style.height);
		timer = setInterval(function() {
			var instance = (new Date()).getTime() - init; //animating time
			if(instance <= time ) { //0 -> time seconds
				var pos = instanceheight + Math.floor(disp * instance / time);
				slider.style.height =  pos + 'px';
			}else {
				slider.style.height = height + 'px'; //safety side ^^
				clearInterval(timer);
			}
		},1);
	};
};

Test it here: http://jsbin.com/azewi5/5

Solution 3 - Javascript

As an improvement to @Ruben Serrate solution which misses the use case for unknown height, I've created this using CSS3 and javascript (no jQuery):

/**
* getHeight - for elements with display:none
 */
getHeight = function(el) {
    var el_style      = window.getComputedStyle(el),
        el_display    = el_style.display,
        el_position   = el_style.position,
        el_visibility = el_style.visibility,
        el_max_height = el_style.maxHeight.replace('px', '').replace('%', ''),

        wanted_height = 0;


    // if its not hidden we just return normal height
    if(el_display !== 'none' && el_max_height !== '0') {
        return el.offsetHeight;
    }

    // the element is hidden so:
    // making the el block so we can meassure its height but still be hidden
    el.style.position   = 'absolute';
    el.style.visibility = 'hidden';
    el.style.display    = 'block';

    wanted_height     = el.offsetHeight;

    // reverting to the original values
    el.style.display    = el_display;
    el.style.position   = el_position;
    el.style.visibility = el_visibility;

    return wanted_height;
};


/**
* toggleSlide mimics the jQuery version of slideDown and slideUp
* all in one function comparing the max-heigth to 0
 */
toggleSlide = function(el) {
    var el_max_height = 0;

    if(el.getAttribute('data-max-height')) {
        // we've already used this before, so everything is setup
        if(el.style.maxHeight.replace('px', '').replace('%', '') === '0') {
            el.style.maxHeight = el.getAttribute('data-max-height');
        } else {
            el.style.maxHeight = '0';
        }
    } else {
        el_max_height                  = getHeight(el) + 'px';
        el.style['transition']         = 'max-height 0.5s ease-in-out';
        el.style.overflowY             = 'hidden';
        el.style.maxHeight             = '0';
        el.setAttribute('data-max-height', el_max_height);
        el.style.display               = 'block';

        // we use setTimeout to modify maxHeight later than display (to we have the transition effect)
        setTimeout(function() {
            el.style.maxHeight = el_max_height;
        }, 10);
    }
}

Here is the demo: http://jsfiddle.net/pgfk2mvo/

Please let me know if you can find any improvements to this as I always try to improve my code. Happy coding ! :D

Solution 4 - Javascript

>> can be done in plain JavaScript. Just harder.

Actually it's not too hard. You just need to get comfortable with setTimeout() (which is a good idea anyway since it teaches you the programming style of node.js). The most bare-bones implementation (does not have all of jQuery's features, that's left as homework for the reader):

function slideDown (element, duration, finalheight, callback) {
    var s = element.style;
    s.height = '0px';

    var y = 0;
    var framerate = 10;
    var one_second = 1000;
    var interval = one_second*duration/framerate;
    var totalframes = one_second*duration/interval;
    var heightincrement = finalheight/totalframes;
    var tween = function () {
        y += heightincrement;
        s.height = y+'px';
        if (y<finalheight) {
            setTimeout(tween,interval);
        }
    }
    tween();
}

Of course, that's not the shortest possible way to write it and you don't have to declare all those variables like one_second etc. I just did it this way for clarity to show what's going on.

This example is also shorter and easier to understand than trying to read jQuery's source code.


>> Has anyone done something like this or any effects just using plain JavaScript?

Oh yeah, sure, it's the sort of thing I do for fun on weekends:

Solution 5 - Javascript

Here's the solution to use slideDown, slideUp animation with an unknown content height element. https://jsfiddle.net/gebpjo1L/18/

It based on the CSS 3 height animation, but the animation requires a specified content height, so you need to get the height of the content via JavaScript before you expanding it.

var container = document.querySelector('div')
var button    = document.querySelector('button')

button.addEventListener('click', () => {
    /** Slide down. */
    if(!container.classList.contains('active')) {
        /** Show the container. */
    	container.classList.add('active')
        container.style.height = "auto"
        
        /** Get the computed height of the container. */
    	var height = container.clientHeight + "px"

        /** Set the height of the content as 0px, */
        /** so we can trigger the slide down animation. */
        container.style.height = "0px"

        /** Do this after the 0px has applied. */
        /** It's like a delay or something. MAGIC! */
        setTimeout(() => {
            container.style.height = height
        }, 0) 
    
	/** Slide up. */
    } else {
    	/** Set the height as 0px to trigger the slide up animation. */
    	container.style.height = "0px"
        
        /** Remove the `active` class when the animation ends. */
    	container.addEventListener('transitionend', () => {
        	container.classList.remove('active')
        }, {once: true})
    }
})

div {
    transition: height .5s ease;
    overflow  : hidden;
}

div:not(.active) {
    display: none;
}

<div>
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
    I'm an unknown content height element. 
</div>
<button>Slide Toggle</button>

Solution 6 - Javascript

The problem with the earlier answers is you need to know the height before you start. Many times you do not. I built a slid down the you first build a holder div, put the object to ge the slide down inside set the display of the object to block and get the height and use this for the sind. When the side is finished the holder is rmoved do the slide down when done remove it. below is the example.

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <div >
            <div id="test" style="height: 150px; width: 100px; background-color: yellowgreen; display:none">block</div>
        </div>
        <div>&nbsp;</div>
        <div onclick="slideUp(document.getElementById('test'));">slide Up</div>
        <div>&nbsp;</div>
        <div onclick="slideDown(document.getElementById('test'))">slide down</div>
        <script>
            function slideDown(obj, speed) {
                var mySpeed = speed || 300;
                var intervals = mySpeed / 30; // we are using 30 ms intervals
                alert('intervals = ' + intervals);
                var holder = document.createElement('div');//
                var parent = obj.parentNode;
                holder.setAttribute('style', 'height: 0px; overflow:hidden');
                parent.insertBefore(holder, obj);
                parent.removeChild(obj);
                holder.appendChild(obj);
                obj.style.display = obj.getAttribute("data-original-display") || "";
                var height = obj.offsetHeight;
                var sepHeight = height / intervals;
                //  alert(sepHeight)
                var timer = setInterval(function() {
                    var holderHeight = holder.offsetHeight;
                    if (holderHeight + sepHeight < height) {
                        holder.style.height = (holderHeight + sepHeight) + 'px';
                    } else {
                        // clean up
                        holder.removeChild(obj);
                        parent.insertBefore(obj, holder);
                        parent.removeChild(holder);
                        clearInterval(timer);
                    }
                }, 30);
            }

            function slideUp(obj, speed) {
                var mySpeed = speed || 300;
                var intervals = mySpeed / 30; // we are using 30 ms intervals
                var height = obj.offsetHeight;
                var holder = document.createElement('div');//
                var parent = obj.parentNode;
                holder.setAttribute('style', 'height: ' + height + 'px; overflow:hidden');
                parent.insertBefore(holder, obj);
                parent.removeChild(obj);
                holder.appendChild(obj);
                var originalDisplay = (obj.style.display !== 'none') ? obj.style.display : '';
                obj.setAttribute("data-original-display", originalDisplay);
                var sepHeight = height / intervals;
                //  alert(sepHeight)
                var timer = setInterval(function() {
                    var holderHeight = holder.offsetHeight;
                    console.log(holderHeight);
                    if (holderHeight - sepHeight > 0) {
                        holder.style.height = (holderHeight - sepHeight) + 'px';
                    } else {
                        // clean up
                        obj.style.display = 'none';
                        holder.removeChild(obj);
                        parent.insertBefore(obj, holder);
                        parent.removeChild(holder);
                        clearInterval(timer);
                    }
                }
                , 30);
            }

        </script>
    </body>
</html>

Solution 7 - Javascript

After tinkering a little with Symba's answer I came up with this to take into account padding and borders:

toggleSlide = function (el) {
    var el_max_height = 0;
    if (el.getAttribute('data-max-height')) {
        if (el.style.maxHeight.replace('px', '').replace('%', '') === '0') {
            el.style.maxHeight = el.getAttribute('data-max-height');
            el.style.paddingTop = el.getAttribute('data-pad-top');
            el.style.paddingBottom = el.getAttribute('data-pad-bottom');
            el.style.borderTop = el.getAttribute('data-border-top');
            el.style.borderBottom = el.getAttribute('data-border-bottom');
        } else {
            el.style.maxHeight = '0';
            el.style.paddingTop = '0';
            el.style.paddingBottom = '0';
            el.style.borderBottom = '0';
            el.style.borderTop = '0';
        }
    } else {
        el_max_height = getHeight(el) + 'px';
        el.style['transition-property'] = 'max-height, padding-top, padding-bottom, border-bottom, border-top';
        el.style['transition-duration'] = '0.5s';
        el.style['transition-timing-function'] = 'ease-in-out';
        el.style.overflowY = 'hidden';
        el.style.maxHeight = '0';
        el.setAttribute('data-max-height', el_max_height);
        el.setAttribute('data-pad-top', el.style.paddingTop);
        el.setAttribute('data-pad-bottom', el.style.paddingBottom);
        el.setAttribute('data-border-top', el.style.borderTop);
        el.setAttribute('data-border-bottom', el.style.borderBottom);
        el.style.display = 'block';
        setTimeout(function () { el.style.maxHeight = el_max_height; }, 10);
    }
}

There's a bit of flicker at top border when expanding transition begins and I don't know (yet) how to fix that.

I didn't modify Symba's getHeight function; for that see his answer.

Solution 8 - Javascript

this pure js solution doesn't require knowing the the max-height beforehand, and uses css-transitions.

it will set max-height to 2x browser window's height during transition, and then the remove max-height after the transition is done.

full slideDown, slideUp demo @ https://kaizhu256.github.io/node-swagger-lite/build..alpha..travis-ci.org/app/index.html

css

.swggAnimateSlide {
    overflow-y: hidden;
    transition: all 500ms linear;
}
.swggAnimateSlideUp {
    border-bottom: 0 !important;
    border-top: 0 !important;
    margin-bottom: 0 !important;
    margin-top: 0 !important;
    max-height: 0 !important;
    padding-bottom: 0 !important;
    padding-top: 0 !important;
}

js

domAnimateSlideDown = function (element) {
/*
 * this function will slideDown the dom-element
 */
    if (element.style.maxHeight || element.style.display !== 'none') {
        return;
    }
    element.classList.add('swggAnimateSlideUp');
    element.classList.add('swggAnimateSlide');
    element.style.display = '';
    setTimeout(function () {
        element.style.maxHeight = 2 * window.innerHeight + 'px';
        element.classList.remove('swggAnimateSlideUp');
    }, 50);
    setTimeout(function () {
        element.style.maxHeight = '';
        element.classList.remove('swggAnimateSlide');
    }, 500);
};


domAnimateSlideUp = function (element) {
/*
 * this function will slideUp the dom-element
 */
    if (element.style.maxHeight || element.style.display === 'none') {
        return;
    }
    element.style.maxHeight = 2 * window.innerHeight + 'px';
    element.classList.add('swggAnimateSlide');
    setTimeout(function () {
        element.classList.add('swggAnimateSlideUp');
        element.style.maxHeight = '0px';
    }, 50);
    setTimeout(function () {
        element.style.display = 'none';
        element.style.maxHeight = '';
        element.classList.remove('swggAnimateSlide');
        element.classList.remove('swggAnimateSlideUp');
    }, 500);
};

Solution 9 - Javascript

I spent a lot of time to develop these functions and make them the most similar to JQuery's ones, I think they are some details to be optimized in the morph function mainly on length

function morph( element, options, animationTime, callback ) { 
// options is an array with the same structural of Properties and DiffValues and which contains the properties values we want the animation make
	var ComputedElementStyle = window.getComputedStyle(element,null);
	var AttrElementStyle = element.style;
	var Properties = { // the actuals computed properties
		width: 		parseInt( ComputedElementStyle.getPropertyValue("width")),
		height: 	parseInt( ComputedElementStyle.getPropertyValue("height")),
		padding: {
			top: 	parseInt(ComputedElementStyle.getPropertyValue("padding-top")),
			right: 	parseInt(ComputedElementStyle.getPropertyValue("padding-right")),
			bot: 	parseInt(ComputedElementStyle.getPropertyValue("padding-bottom")),
			left:	parseInt(ComputedElementStyle.getPropertyValue("padding-left"))
			},
		margin:{
			top: 	parseInt(ComputedElementStyle.getPropertyValue("margin-top")),
			right: 	parseInt(ComputedElementStyle.getPropertyValue("margin-right")),
			bot: 	parseInt(ComputedElementStyle.getPropertyValue("margin-bottom")),
			left:	parseInt(ComputedElementStyle.getPropertyValue("margin-left"))
			} 
	};
	var DiffValues = { // the differences between actual properties values and values we want to
		width:		(options['width']!=null) ? (options['width'] - Properties['width']) : 0,
		height:		(options['height']!=null) ? (options['height'] - Properties['height']) : 0,
		padding: {
			top: 	(options['padding']&&options['padding']['top']!=null) ? options['padding']['top'] - Properties['padding']['top'] : 0,
			right: 	(options['padding']&&options['padding']['right']!=null) ? options['padding']['right'] - Properties['padding']['right'] : 0,
			bot: 	(options['padding']&&options['padding']['bot']!=null) ? options['padding']['bot'] - Properties['padding']['bot'] : 0,
			left: 	(options['padding']&&options['padding']['left']!=null) ? options['padding']['left'] - Properties['padding']['left'] : 0
			},
		margin:{
			top: 	(options['margin']&&options['margin']['top']!=null) ? options['margin']['top'] - Properties['margin']['top'] : 0,
			right: 	(options['margin']&&options['margin']['right']!=null) ? options['margin']['right'] - Properties['margin']['right'] : 0,
			bot: 	(options['margin']&&options['margin']['bot']!=null) ? options['margin']['bot'] - Properties['margin']['bot'] : 0,
			left: 	(options['margin']&&options['margin']['left']!=null) ? options['margin']['left'] - Properties['margin']['left'] : 0
			}
	};
	var beginTime = new Date().getTime(); // time at begining of animation
	animationTime = (animationTime!=null) ? animationTime : 250;
	AttrElementStyle.overflow = "hidden"; // disable the potentials scrollbars
	
	var sinceBeginTime; // time since the begining
	var progressFactor; // coeficient that correspond to the advancement of the animation
	
	timer = setInterval(function() { // begin of the animation
		sinceBeginTime = new Date().getTime() - beginTime;
		if( sinceBeginTime < animationTime ) {
			progressFactor = sinceBeginTime / animationTime;
			AttrElementStyle.width=(Properties['width'] + DiffValues['width'] * progressFactor)		+"px";
			AttrElementStyle.height=(Properties['height'] + DiffValues['height'] * progressFactor)	+"px";
			AttrElementStyle.padding=
				(Properties['padding']['top'] + DiffValues['padding']['top'] * progressFactor)		+"px "+
				(Properties['padding']['right'] + DiffValues['padding']['right'] * progressFactor)	+"px "+
				(Properties['padding']['bot'] + DiffValues['padding']['bot'] * progressFactor)		+"px "+
				(Properties['padding']['left'] + DiffValues['padding']['left'] * progressFactor)	+"px";
			AttrElementStyle.margin=
				(Properties['margin']['top'] + DiffValues['margin']['top'] * progressFactor)		+"px "+
				(Properties['margin']['right'] + DiffValues['margin']['right'] * progressFactor)	+"px "+
				(Properties['margin']['bot'] + DiffValues['margin']['bot'] * progressFactor)		+"px "+
				(Properties['margin']['left'] + DiffValues['margin']['left'] * progressFactor)		+"px";
		}else {
			AttrElementStyle.width=options['width']		+"px";
			AttrElementStyle.height=options['height']	+"px";
			AttrElementStyle.padding=
				(Properties['padding']['top'] + DiffValues['padding']['top'])		+"px "+
				(Properties['padding']['right'] + DiffValues['padding']['right'])	+"px "+
				(Properties['padding']['bot'] + DiffValues['padding']['bot'])		+"px "+
				(Properties['padding']['left'] + DiffValues['padding']['left'])		+"px";
			AttrElementStyle.margin=
				(Properties['margin']['top'] + DiffValues['margin']['top'])			+"px "+
				(Properties['margin']['right'] + DiffValues['margin']['right'])		+"px "+
				(Properties['margin']['bot'] + DiffValues['margin']['bot'])			+"px "+
				(Properties['margin']['left'] + DiffValues['margin']['left'])		+"px";
			clearInterval( timer ); // end of the animation
			if( callback!=null ) // if there is a CALLBACK then call it
				callback(Properties);
		}
	},15);
}
function slideUp( element, animationTime , callback) {
	morph( element, {
			height:0,
			padding:{
				top:0,
				bot:0
			},
			margin:{
				top:0,
				bot:0
			} },  animationTime, function(Properties) {
			// at the end of the slideUp we display: none the element and clean the other properties from style attribute
			var AttrElementStyle = element.style;
			AttrElementStyle.width="";
			AttrElementStyle.height="";
			AttrElementStyle.padding="";
			AttrElementStyle.margin="";
			element.style.display = 'none';
			if(callback)
				callback();
	});
}

function slideDown( element, animationTime , callback) {
	var AttrElementStyle = element.style;
	var ComputedElementStyle = window.getComputedStyle(element,null);
	
	AttrElementStyle.display="block";
	
	var options = { // the computed properties when element is displayed
	width: 		parseInt( ComputedElementStyle.getPropertyValue("width")),
	height: 	parseInt( ComputedElementStyle.getPropertyValue("height")),
	padding: {
		top: 	parseInt(ComputedElementStyle.getPropertyValue("padding-top")),
		bot: 	parseInt(ComputedElementStyle.getPropertyValue("padding-bottom"))
		},
	margin:{
		top: 	parseInt(ComputedElementStyle.getPropertyValue("margin-top")),
		bot: 	parseInt(ComputedElementStyle.getPropertyValue("margin-bottom"))
		} 
	};
	// after getting the actuals properties values of the element we flatten it
	AttrElementStyle.height="0";
	AttrElementStyle.paddingTop="0";
	AttrElementStyle.paddingBottom="0";
	AttrElementStyle.marginTop="0";
	AttrElementStyle.marginBottom="0";
	
	morph( element, options , animationTime, function() { // morph the element from flat to the options properties that are right
		// at the end of slideDown we clean up the style but keep the display: block if the element is display: none in the stylesheet
		AttrElementStyle.width="";
		AttrElementStyle.height="";
		AttrElementStyle.padding="";
		AttrElementStyle.margin="";
		element.style.display = 'block';
		if(callback) // if there is a CALLBACK then call it (we are in the morph() callback)
			callback();
	})
}

p{
  width:50%;
  height:auto;
  padding:40px 0 10px;
  margin: 10px 0 40px;
  border:2px solid red
}
div{
  border:1px solid blue;
  padding:10px
}

<div>
  <p id='p'>loiloilozoifboiygdouhbodihfgsd</br>rihgdggisbifghbsoifnsf</br>giodsbgsigfbsjgsgs</p>
</div>

<button onClick="slideUp( document.getElementById('p') ,500)">testUp</button>
<button onClick="slideDown( document.getElementById('p') ,500)">testDown</button>

<button id='btn1' onClick="morph( document.getElementById('btn1'),{ width: 120,height:130,padding:{top:70,left:50},margin:{right:40}} ,1000)">morphIt</button>
<button onClick="document.getElementById('btn1').style=''">reset btn1</button>

Solution 10 - Javascript

Make it shorter:

<button onclick="slide()"></button>

<div id="box"></div>

JS:

slide(){document.getElementById("box").classList.toggle('hide');}

#box {
  overflow: hidden;
  transition: all .5s ease-in-out;
  -webkit-transition: all 0.5s ease-in-out;
  -moz-transition: all 0.5s ease-in-out;
  -ms-transition: all 0.5s ease-in-out;
  -o-transition: all 0.5s ease-in-out;
}
.hide {
  height: 0px !important;
}

Solution 11 - Javascript

Building on Yami Odymels answer here is a version that takes top- and bottom-padding into account, less relies on values set in css beforehand and also removes inline-styles after finishing the animation which prevents problems with viewport-resizes.

const container = document.querySelector('.the-wrap')
const button = document.querySelector('.the-button')

button.addEventListener('click', function() {

    // slide down
    if(!container.classList.contains('active')) {

        // show/remove display: none;
        container.classList.add('active')

        // get current height
        const height = container.clientHeight + "px"

        // remove height to 0
        container.style.height = 0;
        container.style.paddingTop = 0;
        container.style.paddingBottom = 0;
        container.style.overflow = "hidden";

        // this triggers applying the height and padding-values; does not show up on screen
        setTimeout(() => {

            // register removing properties after end of transition
            container.addEventListener('transitionend', () => {
                container.style.height = "";
                container.style.transition = "";
                container.style.overflow = "";
            }, {once: true})

            // set transition
            container.style.transition = "height 0.5s ease, padding-top 0.5s ease, padding-bottom 0.5s ease";

            // set values to trigger transition
            container.style.height = height;
            container.style.paddingTop = "";
            container.style.paddingBottom = "";

        }, 0);

    }
    // slide up
    else {

        // explicitly set height, transitioning to auto-values is not included in spec
        container.style.height = container.clientHeight + "px";
        container.style.overflow = "hidden";
        container.style.transition = "height 0.5s ease, padding-top 0.5s ease, padding-bottom 0.5s ease";

        // again wait
        setTimeout(() => {

            // register cleanup
            container.addEventListener('transitionend', () => {
                container.classList.remove('active')
                container.style.height = "";
                container.style.transition = "";
                container.style.overflow = "";
                container.style.paddingTop = "";
                container.style.paddingBottom = "";
            }, {once: true});

            // set to visually hidden, thus triggering transition
            container.style.height = 0;
            container.style.paddingTop = 0;
            container.style.paddingBottom = 0;

        }, 0);

    }

});

*,
*:before,
*:after {
  box-sizing: border-box;
}

.the-wrap {
    outline: 2px solid crimson;
    margin-top: 50px;
    padding: 20px;
}

.the-wrap:not(.active) {
    display: none;
}

<button class="the-button">toggle</button>

<div class="the-wrap">
    <h1>Headline</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

Solution 12 - Javascript

Have a look at the jQuery source for that effect (slideDown calls show).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionElliottView Question on Stackoverflow
Solution 1 - JavascriptRuben SerrateView Answer on Stackoverflow
Solution 2 - Javascriptuser372551View Answer on Stackoverflow
Solution 3 - JavascriptClaudiuView Answer on Stackoverflow
Solution 4 - JavascriptslebetmanView Answer on Stackoverflow
Solution 5 - JavascriptYami OdymelView Answer on Stackoverflow
Solution 6 - Javascriptjoel MosesView Answer on Stackoverflow
Solution 7 - JavascriptScreView Answer on Stackoverflow
Solution 8 - Javascriptkai zhuView Answer on Stackoverflow
Solution 9 - JavascriptFrançois HamonicView Answer on Stackoverflow
Solution 10 - JavascriptDAVID AJAYIView Answer on Stackoverflow
Solution 11 - JavascriptSteffen WenzelView Answer on Stackoverflow
Solution 12 - JavascriptSkilldrickView Answer on Stackoverflow