Div transitions
Namaste!
Well, luckily with animation, fantasy is your friend.
Steven Spielberg This tutorial was once again inspired by a question from Facebook. Not on my prefered page (Divi Theme Tutorials), but I won’t hold it against them! The person was looking at Elegant Themes newly designed page and noticed that there was a CTA just above the footer that changed size when it scrolled into view. They wanted to know how that was accomplished, and that is the goal of this tut! We will be using a little javascript plus CSS3 transitions and transformations. Note: I altered this after the original posting to incorporate an alternative method that Divi permits by taking advantage of the waypoint.js library that is already loaded! Scroll to the end for this update. The original method outlined by this post will work on any site that has vanilla jQuery running. I’ve posted a demo of what we are building here. This will be a really basic page with a header element and section inserted as spacers to keep the element we are going to transform out of view until we scroll. Next is a section with the module we want to transform. At the very bottom, I’m adding in a code module to hold the javascript I’ll be writing. I would probably put the script into its own file and enqueue it for a production site. First, let’s focus on the module we want to transform. Within our script we need to be able to identify what we want to transform, so click on the row settings button for the third section (the three lines in the teal colored box on the left). Next, go into the “Custom CSS” tab and give the row a “CSS ID:” of expanding-divYou can choose to cause a whole section or one module within a row to transform in this same way. Next up, let’s add our javascript. In this case, we want to monitor where on the page the viewer is located and apply a new class when the element moves into view.
jQuery(document).ready(function($){ var $body = $('body'), $theDiv = $('#expandingDiv'); $(window).scroll(function() { var scroll = $(window).scrollTop(), objectPosition = $theDiv.offset().top - 500; if (scroll > objectPosition) { $body.addClass("grow_the_div"); } else { $body.removeClass("grow_the_div"); } }); });
Let’s step through the code.
jQuery(document).ready(function($){
first I’m wrapping everything in a jQuery statement that, not surprissingly, says not to fire the script until the DOM is all loaded. Otherwise, we would end up trying to target elements that aren’t there yet. The other thing this does is allow us to use the “$” with jQuery for the rest of the enclosed script. WordPress is normally in no-conflict mode, so we would have to write out jQuery each time.
var $body = $('body'), $theDiv = $('#expandingDiv');
This next set of lines identifies our two targets. The first sets the variable “$body” to be the entire body of the page. This might look a little confusing to you, but I often like to track my global variables that are available to multiple functions, by adding a “$” in front of them. So the first “$” says body is a global variable (and is optional), while the second is saying that we are using jQuery. The next line sets the variable “$theDiv” to be equal to the CSS ID we added earlier. As when writing styling rules, we prepend a “#” to the ID we defined to let jQuery know it is an ID, not a class.
$(window).scroll(function() {
We next set up our scroll listener. Basically, anything wrapped within the “{}” of this will be executed anytime the user scrolls.
var scroll = $(window).scrollTop(), objectPosition = $theDiv.offset().top - 500;
As soon as the user scrolls, we want to set the “scroll” variable to where the top of the windo is located. Note, here we aren’t pre-pending the variable with a “$” because it is only used within this function. The next variable to set is the current position of our target. I chose to subtract 500px from its location as the place I wanted the animation to start. Basically, if you don’t subtact anything, the changes will trigger at the top of the screen. In this case, it will trigger 500px down from the top.
if (scroll > objectPosition) { $body.addClass("grow_the_div"); } else { $body.removeClass("grow_the_div"); }
Lastly, we add in some conditional logic to add our new class if the item we want to change is at the right place in the viewport. Note, within the code module you need to wrap this whole thing in script tags – my code embedder doesn’t allow that here. Lastly, we need to add in our styling. I advocate always using a child theme and separate style sheet.
#expanding_div { margin: 0 auto 0 auto; transition: all .8s ease; -moz-transition: all .8s ease; -webkit-transition: all .8s ease; } .grow_the_div #expanding_div { margin: 0 auto 0 auto; -webkit-transform: scale(1.1); transform: scale(1.1); max-width: 100%; }
The first set of styling sets up what we want the target to look like at the beginning. And then it sets the “transition” property. In this case, I’m saying that when there is a change in styling applied to this element it should change “all” the properties over a period of “.8” seconds and use the “ease” speed curve. If you only wanted one property to change with this duration you could specify it instead of all, for example “opacity” to make something appear. These animations can become quite complex when you specify a set of “keyframes”, but that is a topic for another tut! The “speed curve” portion of transitions takes several potential values:
ease | specifies a transition effect with a slow start, then fast, then end slowly (this is default) |
linear | specifies a transition effect with the same speed from start to end |
ease-in | specifies a transition effect with a slow start |
ease-out | specifies a transition effect with a slow end |
ease-in-out | specifies a transition effect with a slow start and end |
cubic-bezier(n,n,n,n) | lets you define your own values in a cubic-bezier function |
You can play with this option to see what you like best. The last bit of styling specifies how we want that same element to look at the end of the transition. In this case we are increasing the scale using “transform”. When this class is added by javascript the element will grow from its initial 100% size to 110% over 0.8 seconds. So that is it for this tutorial. As usual, reach out in the comments or by e-mail if there is something you don’t understand or want expanded.
Metta!!
UPDATE! ****** Namaste!
So the wondrous SJ James who posts amazing tutorials and sells the ever popular Divi Switch plugin at his site, Divi Space (not an affiliate link) posted on the original inspiration for this tutorial. He proposed an alternative method that takes advantage of a library that Divi is already using to power its own animations. The waypoints.js library is compact and really easy to use. To use SJ’s method, as we did above, assign an idetifier to the section that you want to change scale on scroll. SJ is choosing to use a Class of “grow-section” instead of an ID as we did above. This allows you to tag multiple sections that this waypoint will impact. The styling that SJ uses is very similiar to what was discussed above, so we will delve into the javascript first.The jQuery of SJ’s original solution was as follows:
jQuery(document).ready(function( $ ) { $('.grow-section').waypoint(function() { $('.grow-section').addClass('grow-now'); }, { offset: '50%' }); });
Starting at the top, we are telling jQuery not to run anything until the page is loaded up and enabling the use of a “$”.
$('.grow-section').waypoint(function() { xxxxxxxx }, { offset: '50%' });
Next, we set a waypoint function by identifying the section using the assigned class name (remember to prepend the period!). The offset specified at the end indicates where on the page we want our trigger. In this case, 50% of the way down the viewport. Note, you can assign negative values (will trigger above the viewport) and values over 100% (will trigger before section comes into viewport). We will go into why we would want to do this later.
$('.grow-section').addClass('grow-now');
This, hopefully obvious, line of code tells jQuery to add a new class of “grow-now” to the section with class “grow-section”. Note that we could target any element, not just the one that triggered the waypoint. When that class gets added there will be new styling added to the section that changes the scale, as above.
.grow-section { transform: scale(0.9); transition: 1s ease all; } .grow-section.grow-now { transform: scale(1); }
I didn’t discuss it out in the original tut, but as SJ pointed out on Facebook, this can all be added to Divi > Theme Options > Integrations > Add to head. Make sure your javascript is wrapped in <script></script> tags and your CSS in <style></style> tags.
Okay, to wrap up I just want to leave you with a slight modification to SJ’s original. I like it when certain animations reset. With the original code you would only get the animation one time as you scroll down the page. Waypoints.js gives us another additional variable we can pass into our function, “direction”. That way you can tell if the user is scrolling down or back up and trigger things accordingly.
jQuery(document).ready(function( $ ) { $('.grow-section').waypoint(function( direction ) { if ( direction == 'down' ){ $('.grow-section').addClass('grow-now'); console.log('scrolled to waypoint down'); } else { $('.grow-section').removeClass('grow-now'); console.log('scrolled to waypoint up'); } }, { offset: '50%' }); });
I’m not going to go through the code except to say that the console.log statements are just for instruction so that you can see where the trigger is happening. Remove them if you use this on a live site.
Overall, using this basic pattern or the one described in the original post, you can make animations that are pretty complex and responsive to your user. Good Luck and please reach out if you need more explanation.
Great write-up. Thanks.
You are welcome! I actually plan on updating this later today with an alternative posted on Facebook by the great SJ James. He proposed using a different way of examining position in the viewport. I just want to check it out first
I was always looking for methods for spicing up original Divi’s possibilities. Your tutorials open this path widely! Thank you Bob for the next portion of the very useful knowledge. Waiting for more 🙂
You are welcome!