CodePen

Loading ..................

Sass parallax example

Description

By locking the perspective on the body element and transforming elements in 3D on top of that, you can easily create parallax scrolling effects that don’t require JavaScript and can be much more performant as a result. Mixins can be found here

How it works?

Parallax is simply the effect of depth because objects in the background move more slowly than objects in the foreground. Because we have 3d transforms and perspective objects in the background are smaller and move more slowly than objects in the foreground. If you lock the perspective to the view that is scrolling and preserve that perspective on child elements, a parallax effect will be visible. While these objects move at different speeds they are also scaled differently so this effect can be inverted using the scale() function of CSS transforms so things still move as if they are on different planes but the perspective no longer has impact on the scale of the element. All of this math sounds complicated, so it is bundled into easy to use mixins that can be applied with a given depth. You can also use this alongside other 3d transforms and the perspective shifts will happen to 3d boxes and things.

Some background:

I have been playing with this technique since late 2012 and have iterated on it a few times. My interest was peaked again with @keithclark’s pen that really polished the experience and added scale() to the transforms bringing objects back out of perspective. I refined this so it was more mathematically repeatable with the help of Brenna O'Brien and created Sass mixins to make the whole process really easy.

Tags

  1. parallax
  2. scroll
  3. sass
  4. mixins

Comments

  1. Freakin awesome, love it! Nice work :)

  2. I really like that this emulates how parallax actually works. Objects further away move slower. Makes the javascript equivalent seem hacky and cumbersome. Great job.

  3. Awesome. I can wait to steal this technique. :)

  4. This is the first implementation of parallax that I've seen work well on iOS. Fantastic work!

  5. Excellent job Scott (again) - thanks for sharing :)

  6. Great find, however it's not always working...

    On Chrome at OSX the parallax effect is not visible; tested with: - Chrome 32.0.1700.107 - Chrome 34.0.1819.0 canary

    Both on OS X 10.8.4 (12E55)

    It does however work on Safari (6.0.5) and Firefox (26.0)

  7. @Grezvany13 This is a bug with Chrome on Retina Macs where preserve-3d doesn’t work properly. It is being tracked: https://code.google.com/p/chromium/issues/detail?id=338980&q=parallax&colspec=ID%20Pri%20M%20Iteration%20ReleaseBlock%20Cr%20Status%20Owner%20Summary%20OS%20Modified

    IE (11 and below tested) don’t play nice with with preserve-3d either. However this technique is progressive enhancement so it should appear flat, not broken.

  8. I have long admired the Parallax effect but hated that it had to be a JS thing as it's a presentation item and should be CSS.

    Now it is.... rockstar.

  9. This is amazing, thank you. The big issue I'm finding with this though is there is no momentum scrolling in iOS... which seems weird, because it works on desktop with a trackpad or a magicmouse.

    EDIT: ...nevermind, all it took was -webkit-overflow-scrolling: touch; applied to the parent perspective element.

  10. this is amazing. unfortunately it's not possible to apply overflow hidden to the parent element. this makes it very hard to use.

  11. superb... and would love to steal this technique... :P HOW dare you to think like this :) this is really awesome.

  12. If you want to trigger any affixing or fixed-position based on the scroll position, Keith's method, won't let you do it. Maybe it's because the layers become absolute positioned that when you want to trigger a bootstrap nav affix via position:fixed; the affixing won't be triggered.

    See the issue in this fiddle

    And if it does, the affixed element goes off screen, rather than being fixed position relative to the viewport. See here

  13. @gwho Correct, the fixed item must be outside of the parallaxed area. In this mixin you can select a parallax area other than body

    EDIT: Note I don’t do things exactly like Keith does. I use % heights instead of VH on the body to avoid issues with iOS. Also, perspective is variable so you can do other 3d transforms to the elements without them looking blown out.

  14. @gwho Here is a fork where the parallax effect is isolated so that you can have a fixed nav: http://codepen.io/scottkellum/pen/xbPLKB

  15. You are the most magnificent awesomes!

    I've spent so much time trying to figure this out, and got to the point of knowing exactly what's wrong with it, but not being able to right it lol. It sure helps to ask around, and learn by reverse engineering. Much faster, And you still learn it in the end.

    Thanks a bunch!

  16. Pure CSS. A mixin so that it's modular like a decorator. Doesn't mess up when using other 3d transforms. Increased browser compatibility. Works with fixed positions. Doesn't creates a new stacking context, thereby preventing you from going crazy wondering why z-indexes are behaving seemingly illogically.

  17. tl:dr I'm trying to figure out how to implement this in multiple sections.

    Details

    Seeing as the "container" element needs to have fixed position, it seems you must have the entire page as with a perspective property set, and elements at the "base level" (i.e. not a "background" layer of parallax) must be positioned absolutely manually to simulate it being "in-flow".

    I've been trying to figure out how to make the "base layer" (i.e. elements not moved forwards or backwards) be out of the parallax-enabling div (i.e. .container in your example case), while only including the background layer in the parallax-enabling div.

    It seems making different background images show at different points in the scroll would need to be accomplished by manually adjusting the "top:" values, or by replacing each image with javascript.

    Another aspect I've been considering is elements in the parallax not triggering scroll() or offset().top events in jquery. In the fork you provided, the navbar was fixed to begin with, but I want to provision for triggering somethign like bootstrap's .affix(), where it becomes fixed after scrolling to a certain point.

  18. If we use the perspective property, it seems unavoidable to make the entire document parallaxed.

    Here's my reasoning: Using the perspective property does create a new "stacking context", as indicated by the presence of an additional scrollbar. In the forked example, you'll notice the scrollbar for the parallax-enabled .contanier div starts after the navbar, rather than at the topmost "viewport" level. If you include elements with total height greater than your topmost "viewport" level's height, the original, real scrollbar will appear, and you'll be looking at two scrollbars.

    And once we make the entire document have a perspective property, scrolling within that div does not trigger .scroll() or .ScrollTop() or offset().top in jquery, as the topmost "viewport" level has not actually scrolled at all, The only scrolling was within the div that has the perspective property.

    You can detect the .scrollTop() position of the parallaxe-enabled element with its own scrollbar by calling `$('.parallax-enabled-element').scrollTop(), but this still doesn't get around the fact that there can only be one page-wide parallax-enabled element... otherwise, you'll end up with multiple scrollbars.

    It seems if you to to preserve the "main" in-flow layer to detect .scroll() positions, and add slower scrolling backgrounds, you can't use the perspective property.

    These are my thoughts thoughts and deductions so far. Please correct if I've made any errors.

  19. @gwho wow, a lot here.

    For one thing, the container element doesn’t need to be fixed position. This technique may not be right for your needs though, and that’s ok. JavaScript techniques are always going to give you more control. Maybe checking out some of Keith Clark’s examples will help you wrap your head around sections as he tends to structure his in sections: http://codepen.io/keithclark/pen/JycFw.

Leave a Comment Markdown supported. Double-click names to add to comment.

You must be logged in to comment.
  • 72727 Views
  • 21 Comments
  • 769 Hearts
Loading...
Loading...