Jakub Chaloupka
Jakub Chaloupka

Reputation: 177

How to add a CSS transition when there are no changing properties?

I know this may sound weird but how could I add a transition to a header when it changes it's size? The thing is that it has no height related css value, It's only text with top and bottom padding, and as the text changes, the height does too. So how could I implement something like a transition? Let me demonstrate what I mean through code:

$(document).ready(function() {
    $('.header').click(function() {
      if ($('.header').html() == 'Hello World (Click this header)') {
          $('.header').html('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent dapibus. Nullam eget nisl. Nunc auctor. Morbi leo mi, nonummy eget tristique non, rhoncus non leo. Praesent vitae arcu tempor neque lacinia pretium. Morbi leo mi, nonummy eget tristique non, rhoncus non leo. Duis sapien nunc, commodo et, interdum suscipit, sollicitudin et, dolor. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Sed ac dolor sit amet purus malesuada congue. Pellentesque arcu.');
      } else {
          $('.header').html('Hello World (Click this header)');
      }
  });
});
    
.header {
  color: #fff;
  font-family: helvetica;
  position: fixed;
  right: 0px;
  left: 0px;
  top: 0px;
  padding: 30px 15px;
  background-color: #4d5366;
  cursor: pointer;
  transition: all 0.3s ease-in-out;
  user-select: none;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="header">Hello World (Click this header)</nav>

Upvotes: 7

Views: 523

Answers (3)

user1247034
user1247034

Reputation:

Okay, So you want to set the height of .header to auto first of all. Then when you change it's contents get the height of .header using JQuery, so use var headerHeight = $('.header').outerHeight(); then set .headers height to that height, rather than auto using $('.header').css({'height': headerHeight}). But every time you add new content you have to set the height back to auto, in order to get the height of the new .header div with the new content in it.

Obviously you then want to add to .header the transition as follows or something similar: transition: height 0.25s ease-in-out;. I hope that helps. Let me know if I've misunderstood your question or if I can help further. : )

Upvotes: 0

Brian Peacock
Brian Peacock

Reputation: 1849

The text-swap occurs instantaneously between screen refreshes, so unless you can explicitly define and set/reset the height of the element (inline or stylesheet) it will not 'grow or shrink' when you swap the text.

A way around this is to poll the dimensions of your header with long and short text-snippets, store these values, and explicitly define the height of the element when the event is triggered according to each state.

Here's a quick and dirty explanation of the principle in vanilla JavaScript...

<!-- HTML -->
<div id="header" class="offpage">Hello World!</div>

/*** CSS ***/
#header {
    position: fixed;
    right: 0; left: 0; top: 0;
    height:auto;

    color: #fff;
    background-color: #4d5366;

    font-family: helvetica;
    font-size:1rem;
    line-height:1.6;

    padding: 2rem 1rem;

    cursor: pointer;
    transition: all 0.3s ease-in-out;
    user-select: none;
    overflow: hidden;
}
#header.offpage {
    top: -110%;
}

/*** JS ***/
var text = {
    longText: "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.",
    shortText: "Hello World!"
};

var header;

function setHeaderDimensions() {
    /* grab the height of default text 
       and store it in inline data-* attribute */
    var headerHeight = header.clientHeight
    header.setAttribute("data-dims-shortText", headerHeight);

    /* swap text and grab height of longText */
    header.textContent = text.longText;
    header.setAttribute("data-dims-longText", header.clientHeight);

    /* reset default text */
    header.textContent = text.shortText;

    /* define explicit height of default state */
    header.style.height = headerHeight + "px";

    /* display to page */
    header.classList.remove("offpage");
}

function changeHeaderText(e) {
    /* poll current state */
    var flag = header.classList.contains("long");

    /* set text accordingly */
    header.textContent = text[flag ? "shortText" : "longText"];

    /* grab required stored height */
    header.style.height = header.getAttribute(
        flag ? "data-dims-shortText" : "data-dims-longText"
    ) + "px";

    /* toggle state */
    header.classList.toggle("long");

}

function onPageLoaded() {
    header = document.getElementById("header");

    /* grab and set #header dimensions
       for each text-state (long & short) */
    setHeaderDimensions();

    /* add event handler */
    header.addEventListener("click", changeHeaderText, !1);
}

document.addEventListener("DOMContentLoaded", onPageLoaded, !1);

That's the theory anyway. Hopefully you can take that and run with it. :D

Upvotes: 0

Temani Afif
Temani Afif

Reputation: 272713

Here is an idea adjusting the bottom value that will control the height:

$(document).ready(function() {
  $('.header').css('bottom', 'calc(100vh - ' + $('.header div').css('height') + ' - 60px)')
  $('.header').click(function() {
    if ($('.header div').html() == 'Hello World (Click this header)') {
      $('.header div').html('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent dapibus. Nullam eget nisl. Nunc auctor. Morbi leo mi, nonummy eget tristique non, rhoncus non leo. Praesent vitae arcu tempor neque lacinia pretium. Morbi leo mi, nonummy eget tristique non, rhoncus non leo. Duis sapien nunc, commodo et, interdum suscipit, sollicitudin et, dolor. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Sed ac dolor sit amet purus malesuada congue. Pellentesque arcu.');
    } else {
      $('.header div').html('Hello World (Click this header)');
    }
    $('.header').css('bottom', 'calc(100vh - ' + $('.header div').css('height') + ' - 60px)')
  });
});
.header {
  color: #fff;
  font-family: helvetica;
  position: fixed;
  width: 100%;
  left: 0px;
  top: 0px;
  padding: 30px 15px;
  box-sizing: border-box;
  background-color: #4d5366;
  cursor: pointer;
  transition: all 0.3s ease-in-out;
  user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="header">
  <div>Hello World (Click this header)</div>
</nav>

Upvotes: 1

Related Questions