(except from this menu) — build your own homepage, a la carte — click any item for the code
I based this mini project on something I built for myself that has been helpful.
Build a personal homepage Something to prepare yourself to go online.
Instead of writing code from scratch, order from the menu.
Copy what you like, paste it in, change it, break it, fix it. The goal is to learn what each piece does by moving it around.
<iframe>) of something live: calendar, video, doc, map, song (see embeds)lastname_firstname.html and open it in your browser.Prices below = difficulty. 1.00 is easy. 5.00 is hard. Anything with an image costs 5.00 (folders, file names, zipping), and so does anything you have to wrap around your text.
Some lines in the menu code aren't code at all! The browser skips them and they never show on your page.
<!-- an HTML note: goes in the body -->
/* a CSS note: goes in the style */
<!-- --> in the body and /* */ in the style. Every page has two rooms. Paste each snippet into the right one.
<!DOCTYPE html>
<html>
<head>
<title>My Homepage</title>
<style>
/* ROOM 1: CSS goes here. */
/* Anything with { } curly braces */
</style>
</head>
<body>
<!-- ROOM 2: HTML goes here. -->
<!-- Anything with < > angle brackets -->
</body>
</html>
{ } = CSS. Paste between <style> and </style>.< > = HTML. Paste between <body> and </body>. A <script> counts as HTML.<!DOCTYPE html>
<html>
<head>
<title>My Homepage</title> <!-- CHANGE -->
<style>
body {
background-color: #0000cc; /* CHANGE */
color: white; /* CHANGE */
font-family: "Times New Roman", Times, serif;
margin: 0;
padding: 20px;
}
a {
color: white;
font-size: 24px;
}
/* PASTE CSS ITEMS BELOW THIS LINE */
</style>
</head>
<body>
<h1>Your Name</h1> <!-- CHANGE -->
<a href="https://example.com">First link</a>
<br>
<a href="https://example.com">Second link</a>
<a href="https://example.com">Third link</a>
<br>
<a href="https://example.com">Fourth link</a>
<!-- PASTE HTML ITEMS BELOW THIS LINE -->
</body>
</html>
Everything else on this menu goes either in the <style> (CSS) or in the <body> (HTML). Each item tells you which. Not sure? See the box called where things go.
goes in <style>, inside body { }
background-color: #0000cc;
color: white;
background-color: PapayaWhip;
color: DarkSlateGray;
background: linear-gradient(to bottom, #ff00cc, #3333ff);
background-image: url("images/tile.png");
background-repeat: repeat;
Image files go in a folder next to your .html file.
Want to look up web-friendly color names? W3Schools: HTML color names
Colors lifted from the diner menu that inspired this page. Steal them by copying the hex code, like background-color: #eca56c;
goes in <style>, inside body { }
font-family: "Times New Roman", Times, serif;
font-family: Arial, Helvetica, sans-serif;
font-family: "Courier New", Courier, monospace;
font-family: Georgia, serif;
font-family: "Comic Sans MS", cursive;
/* very top of your <style> */
@import url("https://fonts.googleapis.com/css2?family=Space+Mono&display=swap");
body {
font-family: "Space Mono", monospace;
}
Browse at fonts.google.com, pick one, swap the name in both places.
/* CSS */
body {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.links {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
<!-- HTML -->
<div class="links">
<a href="https://example.com">One</a>
<a href="https://example.com">Two</a>
<a href="https://example.com">Three</a>
</div>
.links {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 30px;
justify-content: center;
}
/* CSS */
.scatter {
position: absolute;
top: 120px; /* CHANGE */
left: 300px; /* CHANGE */
}
<!-- HTML -->
<a class="scatter" href="https://example.com">Here</a>
Give each scattered link its own class and its own top/left.
a {
color: white;
text-decoration: none;
font-size: 24px;
font-weight: bold;
}
a:hover {
text-decoration: underline;
}
a:hover {
background-color: white;
color: #0000cc;
}
a {
text-transform: uppercase;
letter-spacing: 4px;
}
a::before {
content: "→ ";
}
a:visited {
color: pink;
}
/* CSS */
.spinner {
display: inline-block;
font-size: 24px;
margin: 5px 0;
animation: spin 4s linear infinite; /* CHANGE 4s */
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
<!-- HTML: drop anywhere -->
<div class="spinner">✜</div>
.pulse {
display: inline-block;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.6); }
}
<span class="pulse">♫</span>
.blink {
animation: blink 1s steps(1) infinite;
}
@keyframes blink {
50% { opacity: 0; }
}
<span class="blink">NEW!</span>
<marquee>Welcome to my page ★ Welcome to my page ★</marquee>
<marquee direction="right" scrollamount="3">slow and backwards</marquee>
<marquee behavior="alternate">back and forth</marquee>
Try other ornaments: ✦ ❀ ☼ ✺ ♫ ✿ ☻ or any emoji.
/* CSS → goes in <style> */
/* 16px is normal. 2em = twice normal. */
body {
font-size: 18px; /* CHANGE */
}
h1 {
font-size: 64px; /* CHANGE */
}
/* CSS → goes in <style> */
/* 1 = tight. 1.5 = comfortable. 2 = airy. */
body {
line-height: 1.5; /* CHANGE */
}
p {
line-height: 1.8; /* CHANGE: just paragraphs */
}
/* CSS → goes in <style> */
.big {
font-size: 48px; /* CHANGE */
}
<!-- HTML → wrap around your text, in <body> -->
Welcome to <span class="big">my page</span>
<!-- HTML → wrap around your text, in <body> -->
<h1>Biggest</h1>
<h2>Big</h2>
<h3>Medium</h3>
<h4>Smaller</h4>
<h5>Small</h5>
<h6>Smallest</h6>
<!-- HTML → wrap around your text, in <body> -->
<strong>bold</strong>
<em>italic</em>
<u>underlined</u>
<strong><em>both at once</em></strong>
<!-- HTML → wrap around your text, in <body> -->
<mark>highlighted</mark>
<s>crossed out</s>
/* CSS → goes in <style> (optional) */
mark {
background-color: yellow; /* CHANGE */
}
Wrap = put a tag before the words and its closing tag after, like <strong>this</strong>. Anything you wrap around your text costs 5.00.
<img src="images/myimage.png" alt="Describe the image" width="500">
img {
transform: rotate(-5deg);
border: 4px solid white;
}
Images are optional. If you use one, keep it in a folder (here called images) next to your .html file. The folder name and file name in your code must match exactly. Fill in the alt: it's the description for screen readers.
all of these go in the <body>
In Google Calendar:
Settings → your calendar →
"Integrate calendar" → copy the
"Embed code". Paste into your body.
(Calendar must be public for other
people to see it.)
<iframe width="560" height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
frameborder="0" allowfullscreen></iframe>
On a video: Share → Embed → copy.
On a song, album or playlist:
⋯ → Share → Embed → copy.
Paste into your body.
In the doc:
File → Share → Publish to web →
Embed → copy the code.
<iframe src="https://example.com"
width="800" height="600"></iframe>
iframe {
margin-top: 20px;
border: solid 1px #777;
}
Heads up: many sites refuse to be embedded and show a blank box. That's their choice, not your mistake. Use a plain link instead, and look for the site's own "Embed" or "Share" option first.
each item says where it goes: <style> (CSS) or <body> (HTML)
<!-- HTML → goes in <body> -->
<hr>
/* CSS → goes in <style> */
hr {
width: 50%;
border: 1px dashed white;
}
/* CSS → goes in <style> */
.links {
margin-bottom: 40px;
padding: 20px;
}
/* CSS → goes in <style> */
html {
cursor: crosshair;
/* try: pointer, wait, help, text, not-allowed */
}
a {
cursor: crosshair; /* links normally force the little hand */
}
<!-- HTML → goes in <body> -->
<div id="clock"></div>
<script>
function tick() {
document.getElementById("clock").textContent =
new Date().toLocaleTimeString();
}
tick();
setInterval(tick, 1000);
</script>
<!-- HTML → goes in <body> -->
<p><em>Currently:</em> reading,
avoiding email, listening to ___.</p>
extras for when the meal is done. Some need both a <style> part and a <body> part.
/* CSS → goes in <style> */
.sparkle {
position: fixed;
pointer-events: none;
font-size: 20px;
animation: fade 0.8s ease-out forwards;
}
@keyframes fade {
to { opacity: 0; transform: translateY(-30px) scale(0.3); }
}
<!-- HTML → goes at the bottom of <body> -->
<script>
document.addEventListener("click", function (e) {
for (var i = 0; i < 6; i++) {
var s = document.createElement("span");
s.className = "sparkle";
s.textContent = "✦"; /* CHANGE */
s.style.left = (e.clientX + Math.random() * 40 - 20) + "px";
s.style.top = (e.clientY + Math.random() * 40 - 20) + "px";
document.body.appendChild(s);
setTimeout(s.remove.bind(s), 800);
}
});
</script>
/* CSS → goes in <style> */
.rotate {
display: inline-block;
animation: turn 6s linear infinite; /* CHANGE 6s */
}
@keyframes turn {
to { transform: rotate(360deg); }
}
<!-- HTML → wrap around your text, in <body> -->
<span class="rotate">round and round</span>
/* CSS → goes in <style> */
.framed {
border: 4px dashed hotpink; /* CHANGE */
border-radius: 12px;
padding: 16px;
margin: 20px auto;
max-width: 500px;
}
<!-- HTML → wrap around anything, in <body> -->
<div class="framed">
your links, your words, anything
</div>
/* CSS → goes in <style> */
.rainbow {
background: linear-gradient(to right, red, orange, gold, green, blue, violet);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
<!-- HTML → wrap around your text, in <body> -->
<span class="rainbow">over the rainbow</span>
/* CSS → goes in <style> */
h1 {
text-shadow: 3px 3px 0 hotpink; /* hard shadow */
text-shadow: 0 0 12px white; /* soft glow */
}
/* CSS → goes in <style> */
/* the color when someone selects text */
::selection {
background: hotpink; /* CHANGE */
color: white;
}
/* CSS → goes in <style> */
a {
display: inline-block;
transition: transform 0.2s;
}
a:hover {
transform: scale(1.2); /* CHANGE */
}
<!-- HTML → goes in <head>, under <title> -->
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>✜</text></svg>">
Swap the ✦ ✜ for any character or emoji. Add one cherry at a time and refresh.
music to code to:
Drew inspiration from somewhere else (a website, an artist, a book, a poster)? Say that too. Leave this at the bottom of your page and fill it in:
<!--
CREDITS
Stolen from someone else's site?
Inspired by: [a website, artist, book, poster...]
-->
</div>, }, or </style>. Undo your last paste.lastname_firstname.html, like bird_raegan.html. Pay attention to capitals and lowercase! Match the pattern exactly: all lowercase, an underscore between the names, no spaces.images/myimage.png.Set your page as the first thing you see in your browser.
First, get your file's address: drag your lastname_firstname.html file onto an open browser window, then copy the address from the address bar. It starts with file:///
chrome://extensions → Custom New Tab → Details and turn on "Allow access to file URLs."No extension? Chrome Settings → Appearance → turn on "Show home button" and enter your address. That sets the Home button, not new tabs.
Firefox keeps a copy of the .html file for new tabs. If you edit your page, pick the file again. Images in a folder may not show on new tabs; the Homepage route shows everything.
Quick way back to it any time: History → Home.
Everything on the house rules is there: 5+ links, 1 embed, 3 changes of your own, your name, and credits in a comment. File named lastname_firstname.html, and the .html plus zipped images are uploaded to the Drive folder.
Turned in but missing a piece: fewer than 5 links, no embed, fewer than 3 changes, no credits, or the file name or upload isn't right.
Nothing turned in, or the page is menu code pasted in with nothing changed.