Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expandable Div with Transition in CSS

I have a div at the top of my page, containing some header text, which, upon mouseenter, should expand (in height), to reveal some smaller text. Then, upon mouseleave, it should then retract. This is harder than it sounds...

The solution must:

  1. Go from a height to fit just the header, to a height to fit all the text.
  2. Transition from one to the other.
  3. Try to use pure CSS.
  4. Have the expanding animation pause if the mouse leaves, and visa versa (default in CSS, but not in jQuery).

I have tried:

  1. Using :hover in my stylesheet, to change from a set pixel value, to auto, as seen in this question (but in mine it is pure CSS). This did not transition.
  2. Using a set height upon expansion, which does not work on different viewport sizes.
  3. Using max-height, and expanding it to something larger than the actual expanded div would get, as seen in this question. This meant that the transitions don't work properly, and look different on different devices.
  4. Using jQuery .animate(), using the pixel value of auto, to then create a transition, as seen in this question, but the animation has to finish before starting the next one, meaning that a series of animations could continue for a long time after the user's mouse if far away from the div.

See all four above examples here.

As said, pure CSS would be ideal, but if not possible, I would be fine with JavaScript (and I prefer jQuery).

Thanks! :)

like image 973
Luke Avatar asked Feb 13 '16 21:02

Luke


People also ask

Can you have multiple transitions CSS?

Transitioning two or more propertiesYou can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.

Can height be transitioned CSS?

We can't transition height , but we can transition max-height , since it has an explicit value. At any given moment, the actual height of the element will be the minimum of the height and the max-height .

Which CSS property is used for transition effect?

The transition-property CSS property sets the CSS properties to which a transition effect should be applied.


2 Answers

I am not aware of any pure CSS solution for this – transitioning values to auto is something the specification did not include; I think that was even an explicit decision based on that there might be implementation problems.

But for a “simple” jQuery solution, I’d just wrap the paragraph content inside an additional span, set the initial paragraph height to 0 and overflow:hidden, leave the transition for the height in place – and then let jQuery only do one thing, read the height of the span element, set that height for the paragraph, and then set it to 0 again to fade the text out again.

.details {
  height: 0;
  margin: 0; 
  overflow: hidden;
  transition: height 1s;
}

 

$("div").mouseenter(function() {
  $(this).find('p').css('height', $(this).find('span').height());
})

$("div").mouseleave(function() {
  $(this).find('p').css('height', 0);
})

That way, CSS still does the “heavy lifting” of handling the height change via transition (that might should be optimized in browsers), and jQuery/JavaScript is only used to give it the little “nudge” it needs to know what to do. (Pretty sure jQuery is doing the same thing internally as well nowadays with animate(), if the browser supports it – added benefit there would be that jQuery takes care of a fallback implementation, should a really old browser not support transition; in my solution the height would just change instantly, without any transition.)

https://jsfiddle.net/ypwu9n0g/7/

Please notice that in that example, the method is the same for all four items, and I did not bother to change the text content ;-)

like image 65
CBroe Avatar answered Oct 17 '22 05:10

CBroe


A css approach utilizing height , line-height , font-size , opacity

[id^="title"] p {
  overflow:hidden;
  font-size:0em;
  line-height:0em;
  /* height:0px; */
  opacity:0;
  -webkit-transition: height 1s;
  transition: /* height 1s,*/ opacity 1s, line-height 0.1s;
}

[id^="title"]:hover p {
  /* height:auto; */
  opacity:1;
  line-height:1em;
  font-size:1em;
  opacity:1;
  text-overflow: ellipsis;
}
<div id="title1">Title 1<p id="details">Height working, but not transition. Height working, but not transition. Height working, but not transition. Height working, but not transition. Height working, but not transition. Height working, but not transition. Height working, but not transition. Height working, but not transition.</p></div>
<div id="title2">Title 2<p id="details">Transition working, but only on one viewport size... Transition working, but only on one viewport size... Transition working, but only on one viewport size... Transition working, but only on one viewport size... Transition working, but only on one viewport size... Transition working, but only on one viewport size... Transition working, but only on one viewport size...</p></div>
<div id="title3">Title 3<p id="details">Height working, but transitions looking different on different viewport sizes. Height working, but transitions looking different on different viewport sizes. Height working, but transitions looking different on different viewport sizes. Height working, but transitions looking different on different viewport sizes. Height working, but transitions looking different on different viewport sizes. </p></div>
<div id="title4">Title 4<p id="details">Height and transition working - just one catch - the animation does not pause when a new one starts, creating a kind of animation stack that is annoying... Height and transition working - just one catch - the animation does not pause when a new one starts, creating a kind of animation stack that is annoying... Height and transition working - just one catch - the animation does not pause when a new one starts, creating a kind of animation stack that is annoying... </p></div>

jsfiddle https://jsfiddle.net/ypwu9n0g/17/

like image 31
guest271314 Avatar answered Oct 17 '22 04:10

guest271314