Add CSS3 transition expand/collapse

JavascriptHtmlCss

Javascript Problem Overview


How do I add an expand/collapse transition?

function showHide(shID) {
    if (document.getElementById(shID)) {
        if (document.getElementById(shID + '-show').style.display != 'none') {
            document.getElementById(shID + '-show').style.display = 'none';
            document.getElementById(shID).style.display = 'block';
        } else {
            document.getElementById(shID + '-show').style.display = 'inline';
            document.getElementById(shID).style.display = 'none';
        }
    }
}

.more {
    display: none;
    padding-top: 10px;
}

a.showLink,
a.hideLink {
    text-decoration: none;
    -webkit-transition: 0.5s ease-out;
    background: transparent url('down.gif') no-repeat left;
}

a.hideLink {
    background: transparent url('up.gif') no-repeat left;
}

Here is some text.
<div class="readmore">
    <a href="#" id="example-show" class="showLink" onclick="showHide('example');return false;">Read more</a>
    <div id="example" class="more">
        <div class="text">Here is some more text: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae urna nulla. Vivamus a purus mi. In hac habitasse platea dictumst. In ac tempor quam. Vestibulum eleifend vehicula ligula, et cursus nisl gravida sit amet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</div>
        <p><a href="#" id="example-hide" class="hideLink" onclick="showHide('example');return false;">Hide</a></p>
    </div>
</div>

http://jsfiddle.net/Bq6eK/1

Javascript Solutions


Solution 1 - Javascript

This is my solution that adjusts the height automatically:

function growDiv() {
  var growDiv = document.getElementById('grow');
  if (growDiv.clientHeight) {
    growDiv.style.height = 0;
  } else {
    var wrapper = document.querySelector('.measuringWrapper');
    growDiv.style.height = wrapper.clientHeight + "px";
  }
  document.getElementById("more-button").value = document.getElementById("more-button").value == 'Read more' ? 'Read less' : 'Read more';
}

#more-button {
  border-style: none;
  background: none;
  font: 16px Serif;
  color: blue;
  margin: 0 0 10px 0;
}

#grow input:checked {
  color: red;
}

#more-button:hover {
  color: black;
}

#grow {
  -moz-transition: height .5s;
  -ms-transition: height .5s;
  -o-transition: height .5s;
  -webkit-transition: height .5s;
  transition: height .5s;
  height: 0;
  overflow: hidden;
}

<input type="button" onclick="growDiv()" value="Read more" id="more-button">

<div id='grow'>
  <div class='measuringWrapper'>
    <div class="text">Here is some more text: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae urna nulla. Vivamus a purus mi. In hac habitasse platea dictumst. In ac tempor quam. Vestibulum eleifend vehicula ligula, et cursus nisl gravida sit
      amet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</div>
  </div>
</div>

I used the workaround that r3bel posted: https://stackoverflow.com/questions/3149419/can-you-use-css3-to-transition-from-height0-to-the-variable-height-of-content

Solution 2 - Javascript

this should work, had to try a while too.. :D

function showHide(shID) {
  if (document.getElementById(shID)) {
    if (document.getElementById(shID + '-show').style.display != 'none') {
      document.getElementById(shID + '-show').style.display = 'none';
      document.getElementById(shID + '-hide').style.display = 'inline';
      document.getElementById(shID).style.height = '100px';
    } else {
      document.getElementById(shID + '-show').style.display = 'inline';
      document.getElementById(shID + '-hide').style.display = 'none';
      document.getElementById(shID).style.height = '0px';
    }
  }
}

#example {
  background: red;
  height: 0px;
  overflow: hidden;
  transition: height 2s;
  -moz-transition: height 2s;
  /* Firefox 4 */
  -webkit-transition: height 2s;
  /* Safari and Chrome */
  -o-transition: height 2s;
  /* Opera */
}

a.showLink,
a.hideLink {
  text-decoration: none;
  background: transparent url('down.gif') no-repeat left;
}

a.hideLink {
  background: transparent url('up.gif') no-repeat left;
}

Here is some text.
<div class="readmore">
  <a href="#" id="example-show" class="showLink" onclick="showHide('example');return false;">Read more</a>
  <div id="example" class="more">
    <div class="text">
      Here is some more text: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae urna nulla. Vivamus a purus mi. In hac habitasse platea dictumst. In ac tempor quam. Vestibulum eleifend vehicula ligula, et cursus nisl gravida sit amet.
      Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
    </div>
    <p>
      <a href="#" id="example-hide" class="hideLink" onclick="showHide('example');return false;">Hide</a>
    </p>
  </div>
</div>

Solution 3 - Javascript

http://jsfiddle.net/Bq6eK/215/

I did not modify your code for this solution, I wrote my own instead. My solution isn't quite what you asked for, but maybe you could build on it with existing knowledge. I commented the code as well so you know what exactly I'm doing with the changes.

As a solution to "avoid setting the height in JavaScript", I just made 'maxHeight' a parameter in the JS function called toggleHeight. Now it can be set in the HTML for each div of class expandable.

I'll say this up front, I'm not super experienced with front-end languages, and there's an issue where I need to click the 'Show/hide' button twice initially before the animation starts. I suspect it's an issue with focus.

The other issue with my solution is that you can actually figure out what the hidden text is without pressing the show/hide button just by clicking in the div and dragging down, you can highlight the text that's not visible and paste it to a visible space.

My suggestion for a next step on top of what I've done is to make it so that the show/hide button changes dynamically. I think you can figure out how to do that with what you already seem to know about showing and hiding text with JS.

Solution 4 - Javascript

OMG, I tried to find a simple solution to this for hours. I knew the code was simple but no one provided me what I wanted. So finally got to work on some example code and made something simple that anyone can use no JQuery required. Simple javascript and css and html. In order for the animation to work you have to set the height and width or the animation wont work. Found that out the hard way.

<script>
        function dostuff() {
            if (document.getElementById('MyBox').style.height == "0px") {

                document.getElementById('MyBox').setAttribute("style", "background-color: #45CEE0; height: 200px; width: 200px; transition: all 2s ease;"); 
            }
            else {
                document.getElementById('MyBox').setAttribute("style", "background-color: #45CEE0; height: 0px; width: 0px; transition: all 2s ease;"); 
             }
        }
    </script>
    <div id="MyBox" style="height: 0px; width: 0px;">
    </div>

    <input type="button" id="buttontest" onclick="dostuff()" value="Click Me">

Solution 5 - Javascript

Here's a solution that doesn't use JS at all. It uses checkboxes instead.

You can hide the checkbox by adding this to your CSS:

.container input{
    display: none;
}

And then add some styling to make it look like a button.

Here's the source code that I modded.

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
QuestionFelixView Question on Stackoverflow
Solution 1 - JavascriptFelixView Answer on Stackoverflow
Solution 2 - Javascriptr3belView Answer on Stackoverflow
Solution 3 - Javascriptuser1530315View Answer on Stackoverflow
Solution 4 - JavascriptDeathstalkerView Answer on Stackoverflow
Solution 5 - Javascriptuser1530315View Answer on Stackoverflow