If you’re just getting started with HTML and CSS, you may be wondering if you can mix CSS rules and HTML markup in the same document.
The long answer short is yes, you can mix HTML and CSS if you inline your CSS rules or embed them in a <style>
tag in your HTML document’s header.
The real question to ask here, though, is whether you really want to.
There are three ways to add CSS to an HTML document: You can put it in the style=""
attribute of each HTML element, embed it in a <style>
tag in your document’s header, or link to an external CSS file with a <link>
tag.
Each of these ways has its unique pros and cons, and poses various page speed and maintainability challenges. We’ll discuss them in more detail in this article, so read on.
Inline CSS
Suppose you have an HTML document with the following markup:
<!doctype html>
<html>
<head>
<title>My HTML Document</title>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
</body>
</html>
To add inline CSS, declare the CSS properties you want to change insde the style=""
attribute of each and every HTML element, omitting the CSS selector:
<!doctype html>
<html>
<head>
<title>My HTML Document</title>
</head>
<body style="background: #f9f9f9">
<h1 style="font-size: 42px; color: #111">A heading</h1>
<p style="font-size: 16px; color: #353535">A paragraph.</p>
<p style="font-size: 16px; color: #353535">Another paragraph.</p>
</body>
</html>
Inline CSS loads faster because the web browser doesn’t have to make roundtrips to read the rules of an embedded CSS style sheet or extra HTTP requests to download an external CSS file.
However, inline CSS is specific to the HTML element it’s inserted in. So if you want to apply the same style to repeating elements, you must declare that style in each individual element’s style=""
attribute, making your HTML/CSS code repetitive and very difficult to maintain.
Then there’s the question of caching. If you inline all of your CSS in your HTML document, the browser will download them at every HTTP request. If you save them in a .css file and link to them, the browser will cache them heuristically.
Embedded CSS
Like inline CSS, embedded CSS is code that’s inserted directly into your HTML document. Unlike inline CSS, embedded CSS consists of rules in a <style>
tag in the <head>
of your HTML document, and it allows you to target multiple elements with one and the same rule using CSS selectors.
<!doctype html>
<html>
<head>
<title>My HTML Document</title>
<style>
body { background: #f9f9f9 }
h1 { font-size: 42px; color: #111 }
p { font-size: 16px; color: #353535 }
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Another paragraph.</p>
</body>
</html>
Compared to inline CSS, embedded CSS is more versatile and economical. Notice, for example, that we can target both of the paragraphs (that is, the inner text of the <p>
tag) with a single CSS rule on line 8.
At the same time, embedded CSS style sheets have similar drawbacks as inlined CSS properties. They’re read by the web browser at every HTTP request.
They also make change management far from optimal—even if you want to change a single value in your CSS style sheet, you need to edit the entire HTML document and flush the CDN and/or server-side caches.
Linked CSS
To link to an externally hosted CSS style sheet in an HTML document, add the <style rel="stylesheet">
tag to that document’s header:
<!doctype html>
<html>
<head>
<title>My HTML Document</title>
<link rel="stylesheet" href="/css/style.css?ver=1.0">
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Another paragraph.</p>
</body>
</html>
Saving your CSS rules in a .css file and linking to it in the header of your HTML document does result in an additional HTTP request from the web browser when the page loads.
But it also offers numerous advantages:
The browser will cache the CSS file separately from the contents of the HTML file. And, by adding the ?ver=
parameter to the end of your style sheet’s URL, you can invalidate the client-side caches as you deploy new versions of that style sheet.
Change management also becomes easier for you and your team. You’ve practically decoupled the CSS style sheet from the HTML markup. As long as the location and name of the file remain the same, you or somebody else can edit the CSS code without having to touch the HTML document.
Last but not least, it allows you to split your CSS style sheet into multiple files on complex projects. It’s not uncommon, for example, to have one CSS file for each medium:
/* CSS rules for screen and print */
<link rel="stylesheet" href="/css/style.css" media="all">
/* CSS rules for screen only */
<link rel="stylesheet" href="/css/screen.css" media="screen">
/* CSS rules for print */
<link rel="stylesheet" href="/css/print.css" media="print">
Separating your screen and print style sheets like this also brings performance gains. CSS is normally a render-blocking resource. But if the browser sees that a style sheet is intended for an inactive medium, like print, it will load it asynchronously because it’s considered non-critical.
Which One Should You Go For?
Now that you’re familiar with the three ways of adding CSS to an HTML document, the next logical question to ask is, which one should you go for?
It’s an important question. After all, it determines your whole approach to coding the HTML/CSS for the project in question, and everything that you and your teammates will have to do to maintain it once it’s on Production.
90% of the time, the best approach is to save your CSS style sheet in a .css file and link to it using a <link>
tag in the document’s header. It gives you the most control over caching and it makes your project more maintainable.
What about the remaining 10%, you’re probably wondering?
Well, website performance experts recommend inlining the critical CSS code to reduce the First Meaningful Paint (FMP), the time it takes for a web visitor to see a meaningful paint of the above-the-fold content.
So consider if you can do that as part of your project’s implementation. By inlining or embedding the critical CSS into your HTML document, the page will seemingly load faster for the user—and a page that loads faster is a page that doesn’t cause users to drop off and go to your competitors.