To link a CSS file to an HTML page, put <link rel="stylesheet" href="styles.css"> inside the head. The href is a path from the HTML file to the CSS file, so a file in a css folder needs href="css/styles.css". You can also write CSS in a style element, in a style attribute, or pull files in with @import.
| Method | Where it goes | Best for |
|---|---|---|
| <link rel="stylesheet"> | In the head | Almost everything: one file shared by many pages |
| <style> element | In the head | Small pages, critical CSS, demos |
| style="..." attribute | On one element | One-off values set from code |
| @import url(...) | Top of a CSS file | Splitting CSS into layers or files |
Updated
Almost every case of a page with no styling comes down to the link element's path or attributes. This guide shows each way of adding CSS, includes a path checker that works out exactly which URL your href points at, and ends with a checklist for when the styles still do not appear.
https://example.com/css/site.css
<link rel="stylesheet" href="../css/site.css">
The link sits in the head. Its href is relative to this HTML file, so styles.css must sit in a css folder next to it.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My page</title>
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="css/print.css" media="print">
</head>
<body>
<h1>Hello</h1>
</body>
</html>The style element colours every p. The style attribute on the second paragraph wins for that element only.
<style>
p { color: #1d4ed8; font-weight: 600 }
</style>
<p>Styled by the style element.</p>
<p style="color: #b91c1c">Styled by its own style attribute.</p>Imports come first. They can carry a media query, a supports() condition or a cascade layer.
@layer reset, base;
@import url("reset.css") layer(reset);
@import url("print.css") print;
@import url("grid.css") supports(display: grid);
body { font-family: system-ui, sans-serif; }| Symptom | Likely cause | Fix |
|---|---|---|
| 404 for the CSS in the Network tab | Wrong path or folder | Use the path checker above; try a root path on a server |
| No request for the CSS at all | Typo in rel or link outside the HTML | Write rel="stylesheet" exactly; put the link in head |
| Works locally, fails online | File name letter case differs | Servers are often case-sensitive: Styles.css is not styles.css |
| Old styles keep showing | Browser cache | Hard reload, or add a version like styles.css?v=2 |
| Some rules ignored | Overridden by later or more specific rules | Inspect the element; check order and specificity |
| @import does nothing | It comes after other rules | Move every @import to the top of the file |
| Blocked in the console | Served with the wrong content type | The server must send text/css for .css files |
The browser starts from the page's own URL, drops the file name, and applies the href to the folder that remains. ../ moves up one folder, ./ stays in the same one, and a leading slash restarts at the site root.
When you open a page by double-clicking it, the root is your disk, not your project. That is why /css/site.css works on a server but fails from a file:// address, while a relative path works in both.
A style element keeps CSS in the page, which saves a request and is handy for the small block of critical CSS that styles the first screen. It cannot be cached separately and is repeated on every page.
A style attribute applies to one element and beats rules from stylesheets unless they use !important. Use it for values your code calculates, not for regular design, which becomes impossible to change site-wide.
Check the path first: open the browser's developer tools, look at the Network tab and find the CSS request. A 404 means the href points to the wrong place. Also check for rel="stylesheet" spelled correctly, file names in the same letter case, and that you saved the file.
A relative path like css/site.css is resolved from the folder of the current page. A path starting with / is resolved from the site root, and a full URL starting with https:// points to an exact address. Root paths do not work when you open the file straight from disk.
Prefer link. Each @import is only discovered after the file that contains it has downloaded, so chained imports load one after another. @import is useful for layer() ordering or inside a build tool that bundles the files anyway.
Use ../ for each level. A page at /blog/post.html with CSS at /css/site.css uses href="../css/site.css", or the root path href="/css/site.css" when the site runs on a server.
At the very top of the stylesheet, before any other rules. Only @charset and @layer statements may come before it. An @import placed after style rules is ignored.
Related: HTML boilerplate, CSS reset, CSS media queries, CSS specificity calculator, CSS minifier.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.