Grow your CSS skills. Land your dream job.

Fly in Newly Added Content to a Page

Published by Chris Coyier

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 class="module">

<aside class="sidebar" id="sidebar">
  <div class="module">
  <div class="module">

New Content Comes In

jQuery style.

$("<div />", {
  class: "module",
  html: newContent // from an Ajax request or something

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

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() {

Then you could only target new modules with a :not selector:

.module:not(.old-school) {
  /* animation stuff */


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.


  1. Travis
    Permalink to comment#

    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?

  2. Madara Uchiha
    Permalink to comment#

    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.

  3. Covarr
    Permalink to comment#

    If possible, I would strongly recommend starting with height:0 and animating to height:auto. This way old content is pushed down along with the animation, rather than jumping down immediately once it’s called.

  4. Permalink to comment#

    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!

  5. 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 for jQuery(), so when we call $(), it’s the same as calling jQuery(). They literally mean the same thing.

      From the jQuery documentation:

      As of jQuery 1.4, the second argument to jQuery() can accept a map consisting of a superset of the properties that can be passed to the .attr() method.

      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 new data-[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!!

  6. 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.

  7. Jason
    Permalink to comment#

    Awesome. Be neat to see the reversal on removal of content as well.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".