Fast & Efficient
Light-weight
Pure CSS
3kB
P
A
R
A
L
L
A
X
C
S
S

Getting Started

Installation

npm install parallax.css
or

Usage

<link rel="stylesheet" href="node_modules/parallax.css/parallax.css">
or
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/parallax.css">

Make sure you import this library as first so it can be overwritten by your own styles!

See the repository readme for more info.

TL;DR

<body>
    <div prx >default parallax effect</div>
    <div prx=6 >depth set to 6</div>
    <div class="item1" prx >I am fast</div>
</body>
.item1{
    --p-speed: 3; /*3x faster than scrolling*/
}
Fixed elements don't work that way, here is a quick fix: fixed elements

Use the "prx_fit" class on item to fit in its size when scrolling.

example:

Container

The container defines a space where you can move elements by its z-axis (closer or further from the screen).

The container has a fixed size and the effect applyes only to the content inside when scrolling trough the container.

you make a container by styling an element with one of the classes bellow.

the body is a container by default!

Axis

you can choose between 2 classes:

prx_container_y

prx_container_x

Container size

defines dimension of the scrollable side of the container.

accepts any unit except percentage.

Syntax

.my_container {
    /* value: <dimension> (not %)*/
    --p-container-size: 100vh;
}

Align

controls on which side are items aligned when traveling trough perspective.

Syntax

.my_container {
    /* value: <number> | 0 to 100 | left - right, top - bottom */
    --p-align: 50;
}

Align: 0

left
center
right
left
center
right

Item

An Item is considered any descendant of a container that is translated in perspective.

prx (attribute)

To acctivate the parallax effect you simply need to add the "prx" attribute on any 1st level child element of container. To control the depth assign a number to the attribute.

Syntax

<div prx>default depth</div>
<!-- value: <integer> | -10 to 10 -->
<div prx=4>your optimal depth</div>

Set depth in css

Another way to set the depth is to use --p-depth or --p-speed variable in css.

Syntax

<div class="item1" prx >I am slow</div>
<div class="item2" prx >I am fast</div>
<div class="item3" prx >precise depth</div>
.item1{
    /* value: <number> | 0 - "infinity" */
    --p-speed: 0.5; /* 1/2 is valid as well */
}
.item2{
    --p-speed: 3; /* 3x faster than scrolling */
}
.item3{
    /* value: <number> | -5 to "infinity" */
    --p-depth: 6;
}

example:

speed: 0.5
speed: 0.8
speed: 1
speed: 2
speed: 2.5

Transform functions

To adjust the scale of an item (zoom) use the --p-scale variable in css.
For any other transformation use the --p-transform var instead.

Only the translateZ() and scale() functions are used by the library (which can be overwritten).

Syntax

.item1{
    /* value: <number> | 0 - "infinity" */
    --p-scale: 0.5;
    /* value: <transform-function> | one or more */
    --p-transform: rotate(90deg);
}

prx_fit (class)

Use the prx_fit class to fit any item in its size!
This class is especially useful when working with background/layers.

prx_fit item has its default size set to 100. The value represents size percentage relative to Container (allways, even if the item is inside a wrap).
You can change the size by using the --p-size variable.

Syntax

<body>
    <div class="bg1 prx_fit" prx >my awesome background!</div>
</body>
.bg1{
    /* value: <number> | 0 - "infinity" */
    --p-size: 50;
}

The class uses the "left" property and "width"/"height" property to align the item, so it is recomended not to use these properties unless you want to overwrite the behaviour.

Example:

On the left is basic parallax item and on the right is the prx_fit class enabled.

But how to align?

You can choose to either use the img tag or div tag with background-image set.
But background-image has one advantage.
While img is automatically centered, with background-image you can set the "background-position" to align the image when cropped.

.bg1{
    --p-size: 50;
    background-image: url("my_img.png");
    background-size: cover;
    background-position: 15%;
}

Example:

position: 50%

Advanced

todo;

Examples

todo;

Limitations and issues

This library uses css only to achieve these effects.
That is why it is limited to how browsers calculate to display the content according to the css and what css has to offer.

Here are some of the biggest limitations and issues:

Fixed elements

An element with the prx_container class has perspective property set in order for the effect to work (body is a container by default).

According to the MDN and W3C docs "an element with position:fixed are always relative to the initial containing block".
The initial containing block is usually the <html> (visible portion of viewport).
Surprisingly, an exception is made when one of its ancestors has a transform, perspective, or filter property set to something other than none, in which case that ancestor behaves as the containing block. more info.

Solution

In order to solve this issue you simply need to put every fixed element outside of the prx_container.

Here is an example:

<body>
    <div class="main prx_container_y">
        <!-- scrollable content -->
    </div>
    <div class="fixed_element"></div>
</body>

Solution2

Other more sketchy way to solve this is to create a container with extreme parallax depth (barely moving) and put all fixed elements there. Here is how:
<div class="main prx_container_y">
    <!-- scrollable content -->
    <div class="fixed_container prx_fit" prx>
        <div class="fixed_element"></div>
    </div>
</div>
.fixed_container {
    position: absolute;
    --p-depth: 1000000;
}

Negative depth background

When Item has negative depth or speed set to > 1 it means it is closer to you than (infront of) the usual content. Normally It would be obstructing the content but thanks to its default z-index(-1) it isn't.

This only works when directly under the prx Container. Because for more deeply nested items transform-style: preserve-3d is required for the parallax effect to work at all! More info about transform-style property.