From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
Medium, a blogging platform which has gained popularity over the past several months, has one of the smoothest, most polished user interfaces on the web. As you click and touch the interface, you’ll notice that great attention has been paid to transitions, white space, color, fonts, imagery, and iconography.
In this article, I will outline how to achieve Medium’s page transition effect—an effect that can be seen by clicking anywhere on the “Read Next” footer at the bottom of the page. This effect is characterized by the lower article easing upward as the current article fades up and out. See the animation below for an illustration of this effect.
HTML
In this demo, the page first loads with barebones HTML, which we’ll use as a template that will be filled in later with Ajax’d-in data. Below is what our <body>
looks like on initial page load. One main <article>
tag. Pretty simple, eh?
<body> <article class='page hidden'> <div class='big-image'></div> <div class='content'></div> </article> </body>
Once the content is Ajax’d-in, the <body>
looks something like so:
<body> <article class='page current'><!--other HTML --></article> <article class='page next '><!--other HTML --></article> <body>
The page currently being viewed has a class of current
, and the next article has a class of next
. The next article only has its large image being shown at the bottom of the page, which, when clicked on, brings it into focus.
CSS
The styles in this demo which control the article transitions are both applied dynamically via jQuery’s css()
method, as well as by applying classes to the <article>
elements using jQuery’s addClass()
method.
Here’s a rundown of the pertinent classes used:
article.page.hidden { display: none } article.page.content-hidden .content { display: none } article.fade-up-out { opacity: 0; transform: scale(0.8) translate3d(0, -10%, 0); transition: all 450ms cubic-bezier(0.165, 0.840, 0.440, 1.000); } article.easing-upward { transition: all 450ms cubic-bezier(0.165, 0.840, 0.440, 1.000); }
Javascript
Before getting into the Javascript code, I want to first outline the algorithm used to transition the “next” article upward, and transition the “current” article up and away.
User clicks on big image of next article:
- Disable scrolling on the page
- Fade current article to opacity of 0, a scale of 0.8, and move it upward by 10%.
- Show the next article’s content, give it smooth transitions, then move it upward to the top of the window
- After 500ms:
- Remove the current article from the DOM
- Remove smooth transitions from next article
- Scroll to top of page programmatically.
- Make next article the current article
- Enable scroll on the page
- Make Ajax request for next article’s content
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
The Code
ArticleAnimator.animatePage = function(callback){ var self = this; var translationValue = this.$next.get(0).getBoundingClientRect().top; this.canScroll = false; this.$current.addClass('fade-up-out'); this.$next.removeClass('content-hidden next') .addClass('easing-upward') .css({ "transform": "translate3d(0, -"+ translationValue +"px, 0)" }); setTimeout(function(){ scrollTop(); self.$next.removeClass('easing-upward') self.$current.remove(); self.$next.css({ "transform": "" }); self.$current = self.$next.addClass('current'); self.canScroll = true; self.currentPostIndex = self.nextPostIndex( self.currentPostIndex ); callback(); }, self.animationDuration + 300 ); }
Throughout the CSS & Javascript code, you’ll notice that, in order to achieve fluid animations, I am using transform: translate3d(x,y,z)
to move my DOM elements. By doing this, we “hardware accelerate” the DOM elements movement. This method is preferred over animating an element using top/left
or transform: translate(x,y,z)
, which are not hardware accelerated by default.
Side notes
As outlined earlier, the page is populated by making Ajax requests to static json
files. Page state is managed using the PushState API and location.hash
.
Photos in the demo were used courtesy of Unsplash. The page font is set in PT Serif and the headings in Source Sans.
So coooooooooool! Thank you!
Great Just loved it!! i was searching for this trick but i didn’t found the best one but now i think i found it thank’s very much!!
This is by far one of the best page transition I have ever seen. Simple and saves me the from the dreaded infinite scrolling.
This is completely awesome… thank you so much.
Awesome! Love your ideas and solutions. Keep on the good work!
If I download the code, it does not load any content, I tried it on WAMP and on my website as well, but it does not work…
What do I need to setup to get the AJAX loading?
DESIGNfromWITHIN,
Since the page uses ajax, it’s best to serve the “index.html” with a true http server, and not from file. I like to use a Ruby gem called serve to achieve this.
Simply
gem install serve
, then typeserve
from with the project’s root, and you’ll be able to access the page at localhost:4000. Hope this helps!Thanks, got it.
But what about on a live site? If I use this in a blog, how do I ‘serve’ it?
If you’re not serving the page from the root of your site, you’d need to remove the slash from the following line and/or change it to the correct path in which you’re serving your json data:
https://github.com/briangonzalez/codrops-medium-style-page-transitions/blob/master/js/app.js#L63
So, in the end it would look like (no slash):
$.getJSON('data/post_'+ index +'.json', function(d){
Thanks for the gem, pretty sweet and great article btw!
very interesting transition
Work well on Mozilla / Safari / IE
but doesn’t work on Google Chrome
Works fine for me..
Works perfectly on Chrome for me
Same for me
Using windows XP, it doesn’t work on Google Chrome
so i ve tested on mac and widows
it’s work fine on chrome version Version 30.0.1599.101 on mac book pro
but not work on chrome windows 7 (the same version Version 30.0.1599.101 )
strange…
Great ! very nice 🙂
Wow! Simply beautiful – imagine a parallax effect on the top image as well!
Great job!
It’s really frustrating to find the scrollbar missing in the demo page, it’s unaccessible for me as my mouse does not have a scrolling wheel – any possibility of fixing it?
Click and then use down arrow…
The scroll bar is there but it’s only 1px wide on chrome. Not all of us use a Macbook with gestures or even a mouse with a scroll wheel. Very unusable.
Clicking and using the down arrow is not an acceptable solution as it’s not natural behavior for most people.
Blown Away!!!
It cheers to see people doing such an awesome job !
Thanks Brian!
Really cool idea!
Looks like won’t work on IE8.
Agreed. It just shows few words such as “next”, and a mark “X” in right top corner.
Does anything cool work in IE8? 🙂
Great job!
Awesome.
Just a question, how did you do the gif animation above?
Maybe a tutorial on that.
=)
The gif animation above was made using Adobe After Effects.
What about a “Back” button or “Last Article”? It seems like should work just tagging the link on a #NUMBER.
Right?
By the way, it’s pretty awesome!
Nice, but…
Doesn’t work on Chrome. No Scrollbar.
Version 30.0.1599.101 m / Win7
Awesome work as usual! Definitely a ghost theme 🙂
Sweet article Brian!
One question though. What would i need to change if i didn’t want the pages to loop once it reached the end of my articles?
Any help would be much appreciated 🙂
Same issue for me
The demo already has this built in. Is that not working for you?
For example, http://tympanus.net/Tutorials/MediumStylePageTransition/#5 should take you back to page #1. Hope this helps!
Hum… Just a bit issue, I think its not working on Chrome. Hope it maybe fixed soon 🙂
Hi Adam, what’s it doing for you? What’s the problem?
Great article, I like the serve gem as well.
@Brian, to get it to work, I had to change the path in app.js to remove ‘/MediumStylePageTransition/’ so it was just ‘$.getJSON(‘data/post_’+ ….’
@brianh
Thanks for the heads up! We changed the code for the demo and forgot to change it back for everyone else. The ZIP file now links to github, where you’ll be able to find the latest code.
https://github.com/briangonzalez/codrops-medium-style-page-transitions/archive/master.zip
try to update youe chrome because it’s workin’ fine with my chrome 😉
Wow! awesome, great way to let the viewer see what’s next and smooth transition! I’m going to have to give this a try.
I visited Medium’s website a day ago and was interesting how this page transition works…. Thank you for explanation and great article! 🙂 Just in time!
Waaaw great transitions 🙂
Nice one Brian
Can it be used also to go back to the top of the page quicker than via scolling ?
Not really, that’s a different technique 🙂
Really, really nice.
Safari version 6.0.5 (8536.30.1), when you click on the next article at the bottom of the page, new article opens and scrolls down and does not stay on the top of the page. how to fix it? thank for the sharing, very very good work!
thanks for your great work. It’s indeed very nice ;P
Very cool mechanic, but there seems to be some serious lag involved where if you click ‘back’ too quickly there is no action (chrome 30, win7). the view stays the same. If you wait a while before going back it seems to go fine
Great tutorial. Do you have a javascript books to recommend? Completely of the topic here, But i was wondering how you created that swipe animated gif?
There are a lot of Javascript books covering a lot of topics. If you’re looking to get good at vanilla Javascript, Crockford’s “Javascript: The Good Parts” is universally recommended.
http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742
Also, the gif in this tutorial was created using Adobe After Effects.
Thanks much appreciated Brian
Great, exactly what I needed !
However, I don’t think that ajax’ing the content of the main article is a good thing because people who do not have javascript enabled wouldn’t be able to see any content.
So many people have disabled javascript… It shouldn’t be an issue, however if it really is a concern to you: use regular <a href rel=”nofollow”> to the next page. Fetch the click action with javascript for people who have javascript enabled and serve it with ajax. People who have it disabled just go to a new page. Hope that makes sense.
How would you add the title to the url?
Excellent post. Thanks for sharing.
Hi, I have downloaded the file but it doesn’t work at all. Is there something that I suppose to change?
How easy would this be to implement on WordPress?
Took me about 2 hours, planning on using it as part of a new theme on themeforest soon.
Did you end using this on wordpress… I would love to see it… ContactOmarNow@gmail.com
Great article 🙂
Howerver, the content is injected via Ajax ? How about SEO ?
this is great work. Can we disable looping. Also can we put static text after that like contact form or something in the index file itself?
I downloaded and dosnt work at all, the images dont load and it says file:///data/post_1.json?_=1384654457169 failed to load resource in the console log.
Make sure URL data path is correct.
Anybody figured out how to implement a second picture? If you look at “Medium” you’ll see pictures in the middle of the article. I already tried to put am tag in the ajax data, but this will crash the site. I hope you can help me out 🙂
Hey guys!
I read trough the comments and saw that certain ppl had the sam issue as me, then I downloaded the updated example from gitHub BUT it’s still not working. I still get a ‘white’ page with:
– Published by
– Read Next
There are no images displaying (even if I detect them with MOZ/Firebug), no text, Links not working ecc.
Resume: The entire page isn’t working as it should! Tried it with Firefox, Chrome, Safari. Tried also hosting it, doesn’t change anything.
WOULD REALLY APPRECIATE HELP, LOVE THE PAGE STRUCTURE AND WANNA SEE HOW IT TRULY WORKS!
BIG Thanks in advance!!
Charles
Must be blonde… found the solution > THANKS AGAIN BRIAN!
https://github.com/briangonzalez/codrops-medium-style-page-transitions/blob/master/js/app.js#L63
So, in the end it would look like (no slash):
$.getJSON(‘data/post_’+ index +’.json’, function(d){
Yeah, I’m having the same issue too. Can’t get this to work. Any ideas????
Would be cool if we could navigate backwards?
In your next update, can you please add a “previous article/post link” also.
oh and great work by the way.
awesome script, things are working fine in firefox but page don’t show in chrome or IE. anyone knows how to fix it?
file:///C:/Main/post_1.json?_=1386317103426 No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘null’ is therefore not allowed access. jquery.js:6
XMLHttpRequest cannot load file:///C:/Main/post_1.json?_=1386317103426. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘null’ is therefore not allowed access.
Hi !
Have you found the solution for this ? I have the same problem. I solved by placing in server. ( MAMP )
Any ideas how I could modify this work with post numbers that increment by more than 1? For example, if my files were named post_3.json, post_7.json, post_15.json, could I make it ignore the missing posts?
Hi Brian,
… + thaks for this, so cool!
Is it somehow possible to implement some php into this?
I tryed this:
“content”: “”
… but it didn’t seem to work : )
very best,
Tomas
Did you make any Progress on this?
Thank you for this code, it helped me a lot! But what if I want to had a link to another post in a post? The window.location changes well but nothing happened on the page (which seems logical, because we juste change the hash). Do I have to handle those links in JS as well or is their any other solutions ?
And second important question, what about the url rewritting? I don’t think it’s possible with the hash. (But medium doesn’t have URLs with #1 🙂 )
Thank you!
Hi guys! I like this! But I have a problem. I want to write russian texts, but when I change it, it looks like ??????????. HTML works good in Russian, but .json files don’t. How can I change encoding from UTF-8 to chcp-1251?
How to change the encode from UTF-8 to another?
Thank you for this code. It’s a great help for me especially working in my own site. Thank you for sharing this interesting tutorial.
Great article!
How are you doing prototype gif-animation?
article-animation1.gif