Say that for any reason, a new module of content needs to appear on a page. By simply appending that new module into the DOM it will instantly appear. That might be enough of an “entrance” – or it might be too subtle. I’d think when you add new content to a page, you want people to see it. Animation might be the ticket. It technically slows down the entrance of the new content, but the visual effect will certainly make it more noticeable. Let’s write some code to make all new modules added to a page “fly in.”
Already Existing Content…
You have a site. Site has modules.
<section class="main" id="main">
<div class="module">
...
</div>
<div class="module">
...
</div>
</section>
<aside class="sidebar" id="sidebar">
<div class="module">
...
</div>
<div class="module">
...
</div>
</aside>
New Content Comes In
jQuery style.
$("<div />", {
class: "module",
html: newContent // from an Ajax request or something
}).prependTo("#sidebar");
Option #1: Give New Modules a Class
If you have the ability, it’s probably cleanest to give newly added content a class so you can target it specifically. In this case, we give it the class newly-added
.
$("<div />", {
class: "module newly-added",
html: newContent // from an Ajax request or something
}).prependTo("#sidebar");
Fly in CSS
This new class will have an animation tied to it that does the fly in. It will run immediately after being added to the DOM.
.newly-added {
animation: flyin 1.2s ease forwards;
opacity: 0;
transform: scale(2);
filter: blur(4px);
}
@keyframes flyin {
to {
filter: blur(0);
transform: scale(1);
opacity: 1;
}
}
Note: there are no prefixes being used there. All of animation
, transform
, filter
, and @keyframes
should be prefixed for the best browser support. Consult CSS3 Please for which to use on which. Or, us Sass/Compass and the appropriate mixins. Or, Prefix Free1.
Option #2: Target All New Modules Without a Class
It’s possible you don’t have control over the classes that newly added content has. In that case, you would target all existing content on the page and give them a class to negate the fly in effect.
$(function() {
$(".module").addClass("old-school");
});
Then you could only target new modules with a :not
selector:
.module:not(.old-school) {
/* animation stuff */
}
Demo
See the Pen Fly in new content by Chris Coyier (@chriscoyier) on CodePen.
1 Prefix Free doesn’t work with filter out-of-the-box right now, but you can make it work. See code example from Lea in here.
Nice! I was looking into a solution for a similar setup I am working on and this should work great!
PS, lol, the new merch image of the girl in the footer of your site… haha your face, Like what you see?
Totally agree about the merch image!
Haha Chris, I didn’t mean you had to change it!
Looking good. But seems like
filter: blur()
isn’t animatable (viewing from Chrome). Would’ve been awesome if the blur changed while the content is flying in. It would give a nice focus feel.It seems to animate for me… I’m using Chrome on Mac OSX Lion.
If possible, I would strongly recommend starting with
height:0
and animating toheight:auto
. This way old content is pushed down along with the animation, rather than jumping down immediately once it’s called.Nice stuff, Chris!
I’m beginning to notice that you like the word ‘Module’ don’t you?! Haha.
This could come in handy for a future project!
This is a great article. One question though and please forgive me as I should probably know this.
All my jQuery life I have been adding content this way:
$('<div>css-tricks</div>').preprendTo('.awesomeSites');
However this article made me stop in my tracks with the following bit of code of adding content:
$("<div/>",{...}).preprendTo();
I have never seen this and would like to know if there is a name for this and since what version of jQuery this was introduced. The doco page would be great to know.
Thanks in advance.
First of all,
$()
is shorthand, or syntactic sugar forjQuery()
, so when we call$()
, it’s the same as callingjQuery()
. They literally mean the same thing.From the jQuery documentation:
A map is a generic javascript Object. It’s a set of key-value pairs, and in this case, the keys are the desired attributes of the DOM element we’re looking to create, while the values are what we’d like to assign to those attributes.
So, what happens is what you’d expect: jQuery creates a new DOM element using the parameters we’ve passed to it. So, to use your example:
$('<div>css-tricks</div>')
creates a new div with text “css-tricks”, e.g.<div>css-tricks</div>
. If we wanted this new div to have some attributes, we can use the optional second argument to tell jQuery which attributes these should be, and what values they should have. In demonstration:$('<div>css-tricks</div>', { class: "highlight" })
will create<div class="highlight">css-tricks</div>
Now, you might wonder why we didn’t just write
$('<div class="highlight">css-tricks</div>')
—The reason we don’t is that using the second argument of$()
allows us to pass in variables for both the names of our attributes (if we’re using the newdata-[name]
syntax for custom data elements in html5, for instance) as well as for the values. This lets us avoid “hard-coding” all of the attribute data for our created DOM elements, which is much more powerful.Hope this helps!
Thanks Brendon. Much appreciated!!
Hi, Chris. Thanks for sharing your techniques, although I think it would look better if the elements zoomed in instead of zoomed out. More subtle and slick.
Also, in your first HTML snippet one of the angled brackets is coded as an entity by mistake.
Thanks! You can fork the Pen and swap out some values and see if you can get it zooming in instead of out =)
Awesome. Be neat to see the reversal on removal of content as well.