Happy upcoming Valentine's Day, ya crazy lovebirds!
It's my pleasure, as always, to present the annual Valentine's Day web tutorial. This one is in standard HTML, CSS and JavaScript, and it will be a simple animation complete with graphics and a sappy love poem. We also want this animation to appear differently according to the time of day.
Ready? Here we go...
The images
For this, we will be using two pairs of backgrounds and one background for the love poem.
These are the sky backgrounds. They have been given a color adjustment in Photoshop, but are otherwise identical.
|
topbg_day.jpg |
|
topbg_night.jpg |
These are the earth backgrounds. They are PNG files with transparency.
|
middlebg_day.png |
|
middlebg_night.png |
This is the background image for the letter.
|
letterbg.jpg |
The starting HTML is as follows.
<!DOCTYPE html>
<html>
<head>
<title>Valentine Letter</title>
<style>
</style>
<script>
</script>
</head>
<body>
</body>
</html>
We set divs to have a translucent
red background because there is going to be a fair amount of nesting.
<style>
div {background: rgba(255, 0, 0, 0.2); }
</style>
Here, we define the function
getTimeBg(). Leave it blank, for now.
<script>
function getTimeBg()
{
}
</script>
The body needs to call this function upon loading.
<body onload="getTimeBg()">
Now for the divs! The first div has a CSS class of
container.
<body onload="getTimeBg()">
<div class="container">
</div>
</body>
This is the styling for
container. We want a specific width and height, and it will be set in the middle of the screen via the
margin property. We will also give it a nice
pink outline.
<style>
div {background: rgba(255, 0, 0, 0.2); }
.container
{
width: 800px;
height: 700px;
margin: 0 auto 0 auto;
outline: 1px solid rgba(255, 100, 100, 1);
overflow: hidden;
}
</style>
Looking a little basic, right?
Now, add in two divs, wth CSS classes
top and
middle.
<div class="container">
<div class="top">
</div>
<div class="middle">
</div>
</div>
Here's the styling. They have 100% widths, but different heights. Also,
middle has background properties that will fill the entire div. For now, we will leave the background image itself unspecified.
<style>
div {background: rgba(255, 0, 0, 0.2); }
.container
{
width: 800px;
height: 700px;
margin: 0 auto 0 auto;
outline: 1px solid rgba(255, 100, 100, 1);
}
.top
{
width: 100%;
height: 200px;
}
.middle
{
width: 100%;
height: 850px;
margin-top: -200px;
background-size: cover;
background-position: middle top;
background-repeat: no-repeat;
}
</style>
You can see where they line up.
Within the div styled using CSS class
top, we have a div styled using CSS class
sky.
<div class="top">
<div class="sky" id="sky"></div>
</div>
This is the styling for
sky. It takes up 400% of its parents width. The
background-repeat property is set to
repeat-x, because we want the sky background to stretch on forever horizontally.
.top
{
width: 100%;
height: 200px;
}
.sky
{
width: 400%;
height: 100%;
background-position: left top;
background-repeat: repeat-x;
}
See how this works? Don't worry about the content overflowing for the time being; I want you to have a clear visual of what is going on.
Now within the div styled by
middle, we have another div styled using
letter.
<div class="middle" id="earth">
<div class="letter">
</div>
</div>
Here are the CSS styles.
letter has a specific width and height, and is set to the middle of its parent using the
margin property. Its background is
letterbg.jpg, and we set other properties to ensure it fills up the entire thing.
.sky
{
width: 400%;
height: 100%;
background-position: left top;
background-repeat: repeat-x;
margin-left: 0px;
}
.middle
{
width: 100%;
height: 850px;
margin-top: -200px;
background-size: cover;
background-position: middle top;
background-repeat: no-repeat;
}
.letter
{
width: 400px;
height: 500px;
margin: 0 auto 0 auto;
background: url("letterbg.jpg");
background-size: cover;
background-position: middle top;
background-repeat: no-repeat;
}
So far so good. We may need to make more adjustments later.
Yet aother div!
<div class="middle">
<div class="letter">
<div class="text">
</div>
</div>
</div>
text is for containing the poem, so we will make it even less wide than
letter, set it in the middle using the
margin property, and set font sizes.
.letter
{
width: 400px;
height: 500px;
margin: 0 auto 0 auto;
background: url("letterbg.jpg");
background-size: cover;
background-position: middle top;
background-repeat: no-repeat;
}
.text
{
width: 80%;
margin: 0 auto 0 auto;
font-family: georgia;
font-size: 12px;
font-weight: bold;
line-height: 2.5em;
}
Now we will add two paragraph tags within the div styled using
text. They will be styled using
poem and
author, respectively.
<div class="middle">
<div class="letter">
<div class="text">
<p class="poem">
</p>
<p class="author">
</p>
</div>
</div>
</div>
Fill up the first p tag with the poem, and the second p tag with the author's name.
<div class="middle">
<div class="letter">
<div class="text">
<p class="poem">
<br />
How do I love thee? Let me count the ways.<br />
I love thee to the depth and breadth and height<br />
My soul can reach, when feeling out of sight<br />
For the ends of being and ideal grace.<br />
I love thee to the level of every day's<br />
Most quiet need, by sun and candle-light.<br />
I love thee freely, as men strive for right.<br />
I love thee purely, as they turn from praise.<br />
I love thee with the passion put to use<br />
In my old griefs, and with my childhood's faith.<br />
I love thee with a love I seemed to lose<br />
With my lost saints. I love thee with the breath,<br />
Smiles, tears, of all my life; and, if God choose,<br />
I shall but love thee better after death.<br />
</p>
<p class="author">
- Elizabeth Barret Browning
</p>
</div>
</div>
</div>
Let's style those p tags. This is just for aesthetics.
.text
{
width: 80%;
margin: 0 auto 0 auto;
font-family: georgia;
font-size: 12px;
font-weight: bold;
line-height: 2.5em;
}
.poem
{
font-style: italic;
}
.author
{
text-align: right;
}
Here we go!
The backgrounds
First, we add ids to the divs that we need to set backgrounds for.
<div class="top">
<div class="sky" id="sky"></div>
</div>
<div class="middle" id="earth">
Next, we add in some script. We first get sky and earth using the
getElementById() method. Then we get the date using
new Date() and assign it to the variable
d.
function getTimeBg()
{
var sky = document.getElementById("sky");
var earth = document.getElementById("earth");
var d = new Date();
}
Set an
If block, that examines the output of the
getHours() method. If the time of the day is between 6 AM and 6 PM (i.e,
d.getHours() is between 6 to 18 inclusive), we use the day versions of the backgrounds. If not, we use the night versions.
function getTimeBg()
{
var sky = document.getElementById("sky");
var earth = document.getElementById("earth");
var d = new Date();
if (d.getHours() >= 6 && d.getHours() <= 18) {
sky.style.background = "url(topbg_day.jpg)";
earth.style.background = "url(middlebg_day.png)";
}
else
{
sky.style.background = "url(topbg_night.jpg)";
earth.style.background = "url(middlebg_night.png)";
}
}
It's now 11 PM where I am, so the night versions are on!
At this point, we should be turning off the background color of the divs.
div {background: rgba(255, 0, 0, 0); }
Also, add breaks here to adjust the content. It's a really lazy way, I know.
<div class="middle" id="earth">
<br /><br /><br /><br /><br /><br /><br /><br /><br />
<div class="letter">
Animating the skyFor this, we will use CSS3 animations. This will go right into the CSS class
sky. We use an animation name,
skymove, which we will expand on later, and set a duration. Make this fast, maybe 1 second, so we can check on the smoothness of the animation. The iteration count is set to
infinite so that it will go on forever, and we'll set the timing function to
linear so that there won't be any acceleration or deceleration of the animation. It will be at a constant speed.
.sky
{
width: 400%;
height: 100%;
background-position: left top;
background-repeat: repeat-x;
margin-left: 0px;
animation-name: skymove;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
Now we will define
skymove. At 100%, the
margin-left property is set to minus twice the width of the background, which is minus 1600 pixels.
.sky
{
width: 400%;
height: 100%;
background-position: left top;
background-repeat: repeat-x;
margin-left: 0px;
animation-name: skymove;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes skymove
{
0% {margin-left: 0px;}
100% {margin-left: -1600px;}
}
Now the sky div moves left! You can see that the animation appears infinite due to the
background-repeat property being set to
repeat-x.
Set the
overflow property of these classes to
hidden.
.container
{
width: 800px;
height: 700px;
margin: 0 auto 0 auto;
outline: 1px solid rgba(255, 100, 100, 1);
overflow: hidden;
}
.top
{
width: 100%;
height: 200px;
overflow: hidden;
}
Ah, great stuff! Now that the
overflow property is set to
hidden, it looks like the sky is animated! You may want to make the animation slower, maybe set the duration to 200 seconds or something.
Final loving words
I know I know, this Valentine's day web tutorial is kind of corny. But hey, they can't
all be winners. And let's face it, Valentine's Day
can be pretty corny.
Did the earth sky move for you? Heh heh.
T___T