Here is a simple 50x50 pixel black box.
The HTML:
<div class="box"></div>
The CSS simply makes the box 50x50 pixels and black.
.box {
background: black;
width: 50px;
height: 50px;
}
We can make a circle by using the same technique, but rounding the corners in CSS.
The HTML:
<div class="circle"></div>
.circle { background: black; width: 50px; height: 50px;
border-radius: 50%;
}
Triangle can even be created with crafty use of the border properties. Each border side has an angled edge.
We can demonstrate this by creating a box with a width and height of 0, but a thick border on each side. Setting a different color for each border side lets us see the edges.
.box {
width: 0;
height: 0;
border-top: 100px solid red;
border-right: 100px solid green;
border-bottom: 100px solid yellow;
border-left: 100px solid blue;
}
To make a triangle, we set the desired color and size on the border we want. We then set the two adjacent borders to a transparent
color.
To make a left-pointing triangle, we could use this code:
.box {
width: 0;
height: 0;
border-top: 100px solid transparent;
border-bottom: 100px solid transparent;
border-left: 100px solid blue;
}
The triangle size and shapes can be further adjusted by manipulating the border widths.
We'll animate these shapes in our examples.
We want the box to start at the left edge of the page and end just past the right edge of the page.
We can use CSS positioning properties (top, bottom, left, right) to move elements around the page (see aside for review).
Animated Object |
CSS Property |
Timeline (represented in vertical pixels scrolled) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100 | 1200 | 1300 | 1400 | 1500 | ||
box | left | 0% | 100% |
To set up the animation, I have to add my data attributes to the element. The numbers indicate the keyframes.
<div class="box" data-0="" data-1000=""></div>
The number value could be as high or low as we wanted.
For the data attribute values, we add the CSS property and value that we want to animate. The CSS property must have a starting keyframe and an ending keyframe in order to be animated.
<div class="box" data-0="left:0%;" data-1000="left:100%;"></div>
Note that we must use the percent symbol even when specifying 0.
If we wanted the box to start at the middle of the page and also move slowly upward, we could add the top property.
Animated Object |
CSS Property |
Timeline (represented in vertical pixels scrolled) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100 | 1200 | 1300 | 1400 | 1500 | ||
box | left | 0% | 100% | ||||||||||||||
top | 50% | 25% |
The HTML:
<div class="box" data-0="left:0%; top:50%;" data-1000="left:100% top:25%;"></div>
We can scale objects by using the CSS transform
property. The transform property can do all kinds of neat things. The scale value will allow us to make objects bigger or smaller. Here are the possible values:
Value | Description |
---|---|
scale(x,y) | Defines a 2D scale transformation, changing the element's width and height |
scaleX(n) | Defines a 2D scale transformation, changing the element's width |
scaleY(n) | Defines a 2D scale transformation, changing the element's height |
The numerical values represents the scaling factor.
scale(1)
: original element sizescale(2)
: 200% of original sizescale(.5)
: 50% of original sizeHere we're making a box 400% larger than it's original size.
Animated Object |
CSS Property |
Timeline (represented in vertical pixels scrolled) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100 | 1200 | 1300 | 1400 | 1500 | ||
box | transform | scale(1) | scale(4) |
The HTML:
<div class="box" data-0="transform:scale(1.0);" data-1000="transform:scale(4);"></div>
We can add another keyframe to make the box smaller again. I've broken the div into several lines to make it easier to ready the data attributes. Remember that the browser doesn't care about spacing in HTML.
Animated Object |
CSS Property |
Timeline (represented in vertical pixels scrolled) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100 | 1200 | 1300 | 1400 | 1500 | ||
box | transform | scale(1) | scale(4) | scale(1) |
<div class="box"
data-0="transform:scale(1.0);"
data-1000="transform:scale(4);"
data-1500="transform:scale(1.0);"
></div>
Notice how the box gets smaller more quickly because of where we've placed the keyframe in the scrolling.
Using the opacity property, we can make objects fade in or out. The opacity can be set between 0 (fully transparent) and 1 (fully opaque).
We'll start with a fully transparent box and then fade it in as we scroll.
Animated Object |
CSS Property |
Timeline (represented in number of pixels scrolled down the page) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100 | 1200 | 1300 | 1400 | 1500 | ||
box | opacity | 0 | 1 |
The HTML:
<div class="box" data-0="opacity: 0;" data-1000="opacity: 1;"></div>
Using the opacity property, we can make a background fade in or out. This is useful as a scene change. Here we'll fade the background to black.
We can create the scene with a div
(or your choice of section
or article
). In order to make the background fit to the whole page, we have set the width and height of the background to 100%.
<div class="scene"></div>
The CSS makes the background fill the page and changes the color to black. Make sure that the margin on the body
is also set to 0 so that the scene stretches all the way to the edge.
body {
margin: 0;
}
.scene {
background: black;
width: 100%;
height: 100%;
}
Here we will fade a box out and then change scenes afterward.
Animated Object |
CSS Property |
Timeline (represented in number of pixels scrolled down the page) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | 1100 | 1200 | 1300 | 1400 | 1500 | ||
box | opacity | 1 | 0 | ||||||||||||||
scene | opacity | 0 | 1 |
The HTML:
<div class="box" data-0="opacity: 1;" data-400="opacity: 0;"></div>
<div class="scene" data-500="opacity: 0;" data-1000="opacity: 1;"></div>
We can have multiple scene changes by using different div
s, section
s, article
s, etc. We can set the properties of each scene by using id
s.
.scene {
width: 100%;
height: 100%;
}
#scene1 {
background: red;
}
#scene2 {
background: blue;
}
#scene3 {
background: green;
}
Animated Object |
CSS Property |
Timeline (represented in number of pixels scrolled down the page) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 500 | 1000 | 1500 | 2000 | 2500 | 3000 | 3500 | 4000 | 4500 | 5000 | 5500 | 6000 | 6500 | 7000 | 7500 | ||
scene 1 | opacity | 0 | 1 | ||||||||||||||
scene 2 | opacity | 0 | 1 | ||||||||||||||
scene 3 | opacity | 0 | 1 |
The HTML:
<div id="scene1" class="scene" data-500="opacity: 0;" data-2500="opacity: 1;"></div>
<div id="scene2" class="scene" data-3000="opacity: 0;" data-5000="opacity: 1;"></div>
<div id="scene3" class="scene" data-5500="opacity: 0;" data-7500="opacity: 1;"></div>
With the transform property, you can scale, skew and rotate.
To combine these effects, you must use one transform property, with multiple values separated by a space.
The HTML:
<div class="box"
data-0000="transform: scale(1.0) skew(20deg)"
data-1000="transform: scale(4) skew(60deg)"
data-1500="transform: scale(1) skew(1deg)"
></div>
Make sure to always specify the transform effects in the same order:
Animations between CSS transforms only work when they use the same functions in same order. From rotate(0deg) scale(1) to rotate(1000deg) scale(5) is fine.
Colors can be animated by using either hsl
or rgb
. Using color keyworks or hex values are not supported.
The HTML:
<div class="box one"
data-0000="background: hsl(0, 50%, 50%)"
data-2500="background: hsl(360, 50%, 50%)"
>HSL</div>
<div class="box two"
data-0000="background: rgb(0, 0, 255)"
data-2500="background: rgb(0, 255, 0)"
>RGB</div>
Note: You cannot animate between rgb and hsl values. Because of the way HSL works, it will typically yield better results than using RGB.
transform:scale(1)
. Just change the scaling factorrotate(0deg)
. Just change the number of degreesskew(0deg)
. Just change the number of degreesTo see an example of an animated story, see Down the Rabbit Hole.
You don't generally know how many pixels a screen will be. Because of this, tend towards using percentages for moving objects rather than other units if possible.
Your animation will work best at a specific size. That's fine for this project. Pick a size and work with that.
All numeric values have to have the same unit, even 0 needs a unit. It's not possible to animate from 5% to 100px. skrollr won't complain, but results are undefined.
Always specify a unit of measurement, even for 0 (this is specific to Skrollr)
Don't mix units of measurement
Don't mix and match CSS shorthand values. Instead consistently use one type.
Animations between values which are composed of multiple numeric values like margin:0 0 0 0; are only possible for the same number of values. margin:0px 0px 0px 0px; to margin:0px 100px 50px 3px; is fine, but not margin:10px; to margin:5px 10px;.
(From the Skrollr documentation):
Imagine the following animation
<div data-100="left: 0%;" data-200="top: 0%;" data-300="left: 50%;" data-400="top: 50%;" ></div>
One could expect left to have a value of 25% at keyframe 200. That is not the case. By design, skrollr only interpolates values between key frames which are direct neighbors. What actually happens is that skrollr internally fills out all holes once from left and then from right. So the above is equivalent to
<div data-100="left: 0%; top: 0%;" data-200="left: 0%; top: 0%;" data-300="left: 50%; top: 0%;" data-400="left: 50%; top: 50%;" ></div>
Because of this, make sure to explicitly add all values for each keyframe:
<div
data-100="left: 0%; top: 0%;"
data-200="left: 25%; top: 0%;"
data-300="left: 50%; top: 25%;"
data-400="left: 50%; top: 50%;"
></div>
z-index
property. A higher value means it moves to the front. Anything that moves with scrollr will have a default value of 100. You'll really only need to use this if you notice something is moving behind another object.