When people first learn web development, the three names HTML, CSS, and JavaScript usually arrive all at once, and it can feel like you’re supposed to master three separate worlds before anything works. The good news is that they were designed to fit together, like three workers on the same small team. The fastest way to see how they cooperate is to stop reading definitions and build something tiny.
So that’s exactly what we’ll do. In this article we build one button. Just one. It will start as plain text on a page, then get a proper look, and finally do something when you click it. By the end you’ll have seen each layer added on top of the last, and you’ll understand which layer is responsible for what.
If you want the big-picture explanation of why the web splits work into three layers in the first place, that’s covered separately in the conceptual companion to this piece. Here we stay practical and keep our hands on the keyboard.
The job each layer does
Before we type anything, it helps to name the roles. Think of building a small web feature the way you’d think about building a piece of furniture in a showroom.
- HTML is the structure: the wood and screws. It says what things are — this is a button, this is a heading, this is a paragraph.
- CSS is the finish: the paint and polish. It says how things look — this color, this size, these rounded corners.
- JavaScript is the behavior: the moving parts. It says what happens when someone interacts — click this and a message appears.
A useful way to remember it: HTML is the noun, CSS is the adjective, JavaScript is the verb.
HTML -> structure -> "what it is"
CSS -> presentation -> "what it looks like"
JS -> behavior -> "what it does"
Each layer is optional in the sense that a page can technically exist with only HTML. But a real, polished feature almost always uses all three, and they layer neatly on top of one another.
Layer one: structure with HTML
Let’s create the most basic version of our feature. Open a new file and call it index.html. Everything below goes inside it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My First Button</title>
</head>
<body>
<h1>Welcome</h1>
<button id="greet-button">Say hello</button>
<p id="message"></p>
</body>
</html>
If you open this file in a browser, you’ll see a heading, a clickable button that says “Say hello”, and… nothing else interesting. The button is there, but it’s plain, and clicking it does absolutely nothing yet. That’s expected. Right now we only have structure.
Notice two small details that will matter soon. The button has id="greet-button", and there’s an empty paragraph with id="message". An id is just a unique label we attach to an element so other layers can find it later. The empty paragraph is a placeholder — a spot where JavaScript will eventually write a greeting.
What an id is for
An id is a name you give one specific element on the page. It has to be unique — only one element should carry a given id. We use ids here so CSS and JavaScript can point to exactly the right element without confusion.
New to this layer? The dedicated explainer What Is HTML? walks through the tags and structure in more depth.
Layer two: looks with CSS
The button works as a thing, but it looks like a leftover from 1998. Let’s give it some style. CSS is written as a list of rules. Each rule picks an element (a “selector”) and then sets some properties on it.
We can put CSS right inside our HTML by adding a <style> block in the <head>:
<head>
<meta charset="utf-8" />
<title>My First Button</title>
<style>
body {
font-family: system-ui, sans-serif;
padding: 40px;
}
#greet-button {
background-color: #00b8e6;
color: #ffffff;
border: none;
padding: 12px 20px;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
}
#greet-button:hover {
background-color: #0098bd;
}
</style>
</head>
Reload the page and the difference is immediate. The button is now blue with white text, rounded corners, comfortable padding, and the mouse cursor turns into a pointer when you hover over it. Hovering even darkens the color slightly, thanks to the :hover rule.
Read that #greet-button selector carefully. The # means “the element whose id is greet-button” — this is how CSS reaches the exact button we labeled in the HTML. We didn’t touch the HTML structure at all; we only described how it should look. That separation is the whole point. Structure stayed put; presentation got added on top.
| You wrote | It controls |
|---|---|
background-color |
the fill color of the button |
border-radius |
how rounded the corners are |
padding |
the breathing room inside the button |
cursor: pointer |
the hand cursor that signals “clickable” |
If you’d like to go deeper on selectors, colors, and spacing, see What Is CSS?.
Layer three: behavior with JavaScript
We have a button that looks like a button. But click it and the page just sits there. Making it do something is JavaScript’s job.
Add a <script> block at the very end of the <body>, just before the closing </body> tag:
<body>
<h1>Welcome</h1>
<button id="greet-button">Say hello</button>
<p id="message"></p>
<script>
const button = document.getElementById('greet-button');
const message = document.getElementById('message');
button.addEventListener('click', function () {
message.textContent = 'Hello there, nice to meet you!';
});
</script>
</body>
Now click the button. The empty paragraph fills with a friendly greeting. Click again — it stays. You just made a page react to a human.
Let’s read those few lines slowly, because they show the connection between all three layers:
document.getElementById('greet-button')tells the browser: go find the element whose id isgreet-button. That’s the very button we built in HTML. JavaScript is reaching into the structure.- We do the same to grab the empty paragraph (
message). addEventListener('click', ...)says: when this button is clicked, run the function inside.- Inside the function,
message.textContent = '...'writes text into the paragraph — changing what the user sees, live, without reloading.
Put scripts at the bottom
Notice the <script> sits at the end of the body. Browsers read a page top to bottom. If the script ran before the button existed in the document, getElementById would find nothing. Placing the script after the elements is a simple, reliable habit for beginners.
That’s the handshake. HTML created the button and gave it an id. JavaScript used that id to find the button, then listened for a click, then changed the page in response. Want a fuller tour of variables, functions, and events? Start with What Is JavaScript?.
Seeing the three layers cooperate
Step back and look at what each layer contributed to one single button:
<button id="greet-button"> <- HTML: it exists, it's a button
background-color, border-radius <- CSS: it looks clickable and friendly
addEventListener('click', ...) <- JS: it responds when clicked
The same id, greet-button, appears in all three places. That shared name is the thread that ties the layers together. HTML defines it, CSS styles it, JavaScript controls it. None of them had to know the internal details of the others — they just agreed on a label and a place on the page.
This is also why developers usually keep the three in separate files on real projects. In our tiny demo we crammed everything into one index.html for convenience, but as a feature grows it’s cleaner to have index.html, styles.css, and script.js as three files. The HTML then links to the other two:
<head>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<!-- your content -->
<script src="script.js"></script>
</body>
Same idea, just tidier. Structure, presentation, and behavior each live in their own file, and the page pulls them together.
Keep responsibilities where they belong
It’s tempting, once you know JavaScript, to do everything with it — even styling and structure. Resist that early on. If something is about looks, reach for CSS. If it’s about what an element is, that’s HTML. Letting each layer keep its own job is what makes a project easy to read and fix later.
A quick mental checklist
When you build any small web feature, you can walk the same three steps every time:
- Structure first. What elements do I need? Write the HTML. Give the important ones an
idor a class. - Then style. How should it look? Write CSS rules that target those elements.
- Then behavior. What should happen on interaction? Write JavaScript that finds the elements and responds to events.
Do them in that order and you rarely get lost. Each step builds on a finished version of the one before it. A page with only HTML still works. Add CSS and it still works, just prettier. Add JavaScript and it gains a pulse.
Wrapping up
We took a single button from plain text to a styled, interactive element, and along the way you saw the division of labor that powers every website you’ve ever used. HTML gave it structure and a name. CSS gave it a look. JavaScript gave it behavior, reaching back to that same name to wire everything up.
That’s the heart of front-end development. Bigger projects add tools, frameworks, and a lot more code, but underneath it’s still these three layers cooperating in the same way you just watched. The next time you meet a complicated interface, you can mentally peel it apart: what is it (HTML), how does it look (CSS), what does it do (JavaScript). Once that lens clicks into place, the whole web starts to make a lot more sense.