High-performance parallax animation "translation"

Source: Internet
Author: User

High-performance Parallax http://www.php.cn/code/9595.html "target=" _blank "> Animation

Love or hate, parallax effect has spread over the web. When you use it skillfully, it can add depth and metaphor to your application. But the problem is that achieving a high-performance parallax effect is a challenging task. In this article, we will discuss how to construct a high-performance parallax effect, and of course it is also important to cross-browser.

Parallax effect


    • Do not use scrolling events (scroll events) or background positioning (background-position) to create parallax animations.

    • Use the CSS 3D transform to create a more accurate parallax effect.

    • For iOS mobile devices, the Safari browser is used position: sticky to ensure that parallax can take effect.

If you want an out-of-the-box solution, please visit Parallax Helper JS, which also has a demo demo.

Analysis of Parallax problem

Before we begin, let's take a look at two common ways to implement parallax and explore why they are not suitable for the goal we are pursuing.

Bad scenario: using a scrolling event

The key requirement for Parallax is that it should be a rolling coupling: the location of parallax elements should be updated for each position of page scrolling. This looks easy, and one of the important mechanisms of modern browsers is that they can work asynchronously. However, in most browsers, scrolling events are handled as "best effort", which means that the browser does not ensure that scrolling animations are delivered for every frame!

This important message tells us why we should avoid using JavaScript to move elements based on scrolling events:JavaScript does not ensure that Parallax is kept at the same pace as page scrolling. . On some older versions of mobile Safari, scrolling events are triggered even after scrolling is complete, which makes JavaScript-based scrolling ineffective. In newer mobile safari versions, scrolling events can be triggered during animation, but like Chrome, it is based on the "best possible" principle. So when the main thread is busy with other work, the scrolling event does not trigger immediately, which means that the parallax effect is lost.

Bad scenario: Update the background location

Another scenario that we want to avoid is drawing at every frame. Many scenarios attempt to use changes background-position to provide parallax, but this will allow the browser to redraw the affected parts while scrolling, which can be quite resource-intensive, and this effect will cause the animation to stutter.

If we want to provide a high-quality parallax animation, we want a property that can be used as an acceleration (here we mean transform and opacity ), and this is not dependent on scrolling events.


Both Scott Kellum and Keith Clark have done important work in the area of using CSS 3D to achieve parallax effects. The very effective technologies they employ are:

    1. Creates a container element that is set overflow-y: scroll so that it can be scrolled (and possibly required overflow-x: hidden ).

    2. For the above element, we will apply a perspective value and set it perspective-origin to top left , or 0 0 .

    3. Apply a transform on the Z-axis to the child elements of the above element, and then restore them back to achieve the parallax effect without affecting their size on the screen.

The CSS for this scenario looks like the following:

. container {  width:100%;  height:100%;  Overflow-x: Hidden;  OVERFLOW-Y: scroll;  perspective:1px;  perspective-origin:0 0;}. Parallax-child {  transform-origin:0 0;  Transform:translatez ( -2px) scale (3);}

Of course, let's assume that your HTML looks like this:

<p class= "Container" >  <p class= "Parallax-child" ></p></p>

Adjust the ratio of perspective

Squeezing the elements back will require it to set a smaller relative perspective ratio. You can calculate the desired zoom ratio by using the following equation: (perspective-distance)/perspective. Since we want the parallax element to look as large as the one we set at the beginning, it should be indented rather than unchanged based on this equation.

With the above example, perspective Yes, and in the direction of the 1px Z- parallax-child axis -2px , this means that the element needs to be magnified 3 times times, and you can see that we have scale written 3 this value in.

For any content that is not applied, translateZ you can replace it with 0, which is the scaling ratio (perspective - 0) / perspective and the result is 1, which means neither zooming in nor shrinking. really is very convenient.

Why is this scheme useful?

It is important to find out why this scheme works well, because we will soon be using this knowledge. Scrolling is essentially a transformation, which is why it can be accelerated. Scrolling largely uses the GPU to participate in the transformation of the layer. A common scroll (without applying any perspective ) is this: scrolling in this case is done in a 1:1 way that treats the scrolling element and its child elements. In other words, if you scroll down an element 300px , then its child elements are shifted upward by the same number: 300px .

However, applying a value to the scrolling element perspective will "confuse" the process: This value changes the ideal path for the scrolling transformation. Now if one 300px of the scrolls may be moving the handle element 150px , of course it depends on perspective what value you give and translateZ set. If a translateZ child element is set to 0, it scrolls all the same as usual ( 1:1 ), but a child element pushed to the Z-axis ( translateZ not 0) will scroll at a different scale! Therefore, the parallax effect occurs. It is also important to note that the process itself is part of the scrolling mechanism inside the browser, so there is no need to listen for scrolling events or change the background position.

In the ointment: Mobile Safari

Each effect has some constraints, and for Transformations ( transform ), the 3D effect of the child element is maintained. If perspective there are other elements in the structure of the applied element and its "parallax" sub-element, then the effect of 3D will be "flattened", that is, the effect will no longer exist.

<p class= "Container" >  <p class= "Parallax-container" >    <p class= "Parallax-child" ></p >  </p></p>

In the above HTML .parallax-container is a newly added element, and it will "erase", resulting in perspective loss of effect. Typically, the solution is more intuitive: Add this element transform-style: preserve-3d so that it can apply 3D effects to deeper nodes.

. parallax-container {  transform-style:preserve-3d;}

For Mobile Safari, things have become a bit of a hassle. Apply to container elements overflow-y : Technically this is fine, but this will make the scrolling elements move too fiercely. The solution is to add one -webkit-overflow-scrolling: touch , but this setting will result in the perspective flattening, so we will not get any parallax effect.

From a development point of view, this may not be a problem (because only in the older version of Mobile Safari), even if we can not show the parallax in every browser, but the functionality of an application is good, but we'd better find a solution.

position:stickyTo save

In fact, we can position: sticky get some help from the, this setting allows the element to be fixed at viewport the top or fixed in a scrolling element of the parent element. The document for this property, like any other document, stinks and grows, but can still find some useful information:

A fixed "box" is very much like a relatively positioned box, but the displacement is calculated by referencing the nearest scrollable ancestor, or by viewport calculation, if no such ancestor is found-CSS positioned Layout Module level 3

The first glance seems to help little, but a key point in the sentence is how to calculate the part of the element's fixed position: "The displacement is calculated by referencing the nearest scrollable ancestor ." In other words, moving the distance of a fixed element (in order for it to appear to be fixed on an element or viewport on) is calculated before any other transformations are applied, not later. This means that, as we just said, the scrolling example is quite similar, if the result of the displacement calculation is 300px , then we have a new opportunity to use perspective (or any other transformation) to 300px change it before applying it to a fixed element.

By setting the Parallax element position: -webkit-sticky , we can effectively "flip" the -webkit-overflow-scrolling: touch resulting "erase" effect. This ensures that the Parallax element refers to the nearest scrollable ancestor element, which is .container . Then, like above, .parallax-container set a perspective value, which changes the calculated scrolling displacement and creates a parallax effect.

<p class= "Container" >  <p class= "Parallax-container" >    <p class= "Parallax-child" ></p >  </p></p>.container {  overflow-y: scroll;  -webkit-overflow-scrolling:touch;}. Parallax-container {  perspective:1px;}. Parallax-child {  position:-webkit-sticky;  top:0px;  Transform:translate ( -2px) scale (3);}

This restores the parallax effect to Mobile Safari, which is a good result.

Fixed positioning problems

And the previous scheme does have a clear difference, position: sticky changing the mechanism of parallax. Fixed positioning attempts to fix an element at the top of the scroll container, rather than a fixed element. This means that the parallax generated by the fixed positioning and the non-stationary chromatic aberration are reversed:

    • use position: sticky : The closer z=0 the element is, the less it moves

    • not used position: sticky : The closer the element is z=0 , the more it moves

If you still feel some abstraction, take a look at Robert Flack's demo, which shows how elements behave differently under fixed and non-fixed positioning conditions. To see this effect, you need Chrome Canary (writing this article is, version 56) or Safari.

position: stickyThe effect of visual aberration

Fancy Bugs and coping

As with anything, there are plenty of pits to fill.

    • Fixed positioning support is inconsistent: currently in Chrome for this feature is still in development, Edge is completely missing, Firefox has drawn bugs. In this case, we should add a bit of code that will be added when needed (this is Mobile Safari)position: sticky

    • The effect is completely ineffective in the Edge. Edge tries to handle scrolling at the OS level, which is usually a good thing. But in this case, this mechanism will make it impossible for us to apply when scrolling perspective . To fix this problem, we can set ' Translatez (0px) ' for the parent element.

    • The page content is too large: many browsers are responsible for shrinking when deciding how big the page content is, but unfortunately Chrome and Safari are not responsible. So if you have a 3 times-fold transformation applied to an element, you may see the scrollbar appear, and once it appears, the 1:1 scrollbar will not disappear even after you restore the proportions. There is one way to avoid this: to indent () from the lower-right corner transform-origin: bottom right . The rationale behind this scenario is that it causes the "negative" (usually upper left) of an oversized element to enter the scrolling area, and the scrolling area never lets you see the "negative" area.


Parallax animations can be a very interesting effect if they are considered in a thoughtful design. And now you should be able to see that we can implement a high-performance, rolling-coupled, cross-browser scenario. Since this requires a little bit of math and some templating, we encapsulate a tool class and an example.

Welcome to the trial, and put forward your valuable comments.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.