Skip to content

Instantly share code, notes, and snippets.

@derblub
Created October 18, 2016 11:08
Show Gist options
  • Save derblub/8ea55649834c3f22a7a0fbfe15630e7b to your computer and use it in GitHub Desktop.
Save derblub/8ea55649834c3f22a7a0fbfe15630e7b to your computer and use it in GitHub Desktop.
Sass parallax example
<div class="container">
<h1>Parallax</h1>
<h2>faster</h2>
<h2>easier</h2>
<h2>sassier</h2>
<img src="http://placekitten.com/200/200" alt=" " />
<img src="http://placekitten.com/150/200" alt=" " />
<img src="http://placekitten.com/200/150" alt=" " />
<img src="http://placekitten.com/150/250" alt=" " />
<img src="http://placekitten.com/300/400" alt=" " />
<img src="http://placekitten.com/400/300" alt=" " />
</div>

Sass parallax example

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.

A Pen by Scott Kellum on CodePen.

License.

// Magic parallax mixins
$parallax-perspective : 1 !default;
$parallax-element : "body" !default;
$parallax-ios : true !default;
@mixin parallax-init(
$perspective : $parallax-perspective,
$element : $parallax-element,
$parallax-ios : $parallax-ios
) {
@if $element == "body" {
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
}
#{$element} {
overflow: auto;
perspective: $perspective * 1px;
transform-style: preserve-3d;
// Allows for smooth scrolling but disables parallax effects.
@if $parallax-ios == false {
-webkit-overflow-scrolling: touch;
}
// Preserve 3D
&, * {
transform-style: preserve-3d;
}
}
}
@mixin parallax(
$distance : 0,
$perspective : $parallax-perspective
) {
transform:
translateZ($distance * $perspective * 1px)
scale(abs($distance - 1))
;
z-index: $distance * 1000;
}
// End of magic parallax mixins
@import url(http://fonts.googleapis.com/css?family=Roboto:100);
$primary: #1586D1;
@include parallax-init;
.container {
:nth-child(1) {
@include parallax(-.4);
top: 200px;
left: 200px;
}
:nth-child(2) {
@include parallax(.2);
top: 200px;
left: 500px;
}
:nth-child(3) {
@include parallax(.3);
top: 400px;
left: 600px;
}
:nth-child(4) {
@include parallax(.1);
top: 500px;
left: 500px;
}
:nth-child(5) {
@include parallax(-2);
top: 2000px;
left: 2000px;
}
:nth-child(6) {
@include parallax(.4);
top: 600px;
left: 300px;
}
:nth-child(7) {
@include parallax(-1);
top: 400px;
left: 1000px;
}
:nth-child(8) {
@include parallax(-.4);
top: 100px;
left: 1400px;
}
:nth-child(9) {
@include parallax(.4);
top: 900px;
left: 500px;
}
:nth-child(10) {
@include parallax(-1);
top: 1600px;
left: 100px;
}
padding: 10%;
max-width: 40em;
margin: auto;
> * {
position: absolute;
}
}
body {
font-family: Roboto, sans-serif;
font-weight: 100;
background: #EEF1F3;
line-height: 1;
}
h1, h2 {
font-weight: 100;
margin: 0;
}
h1 {
font-size: 5em;
color: $primary;
}
h2 {
font-size: 3em;
@include parallax(.2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment