HTML Guides for style
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The “Stray start tag style“ error occurs when the HTML parser encounters a <style> element somewhere it doesn’t belong according to the HTML specification. The most common causes are:
- A <style> element placed after the closing </body> tag or after the closing </html> tag.
- A <style> element accidentally placed inside an element like <p>, <span>, or <a> that only accepts phrasing content and not <style> in that context.
- A <style> element appearing in the <body> without being a valid child in that context (though the HTML living standard does allow <style> in the <body> in certain conditions).
According to the WHATWG HTML living standard, the <style> element is primarily expected inside the <head> section. While the spec does technically allow <style> in the <body> where metadata content is expected (such as within a <noscript> element that is a child of <head>), placing it in the <head> is the most reliable and universally valid approach.
When a <style> tag appears after </body> or </html>, the browser’s error-recovery behavior kicks in. Browsers will still try to apply the styles, but you’re relying on undefined recovery behavior rather than the specification. This can lead to inconsistent rendering, makes the document harder to maintain, and signals structural problems in your HTML.
This issue commonly arises when content management systems, JavaScript frameworks, or copy-paste mistakes inject styles at the end of a document. It can also happen when template includes or server-side rendering place <style> blocks in unexpected locations.
To fix this issue, move the <style> element into the <head> section. Alternatively, consider moving the CSS into an external stylesheet linked via a <link> element, which is generally the preferred approach for maintainability and caching.
Examples
Incorrect: <style> after the closing </body> tag
This is the most common scenario that triggers the error. The <style> element is “stray” because it appears outside the <body> and <head>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
<style>
p {
color: green;
}
</style>
</html>
Incorrect: <style> after the closing </html> tag
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
<style>
p {
color: green;
}
</style>
Incorrect: <style> nested inside a <p> element
The <p> element only accepts phrasing content, so a <style> element here may trigger the stray tag error:
<p>
<style>
.highlight { color: red; }
</style>
Some highlighted text.
</p>
Correct: <style> inside the <head>
Move all <style> elements into the <head> section:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<style>
p {
color: green;
}
.highlight {
color: red;
}
</style>
</head>
<body>
<p>Hello world</p>
<p class="highlight">Important text.</p>
</body>
</html>
Correct: using an external stylesheet instead
For better separation of concerns, caching, and maintainability, use an external stylesheet:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<p>Hello world</p>
</body>
</html>
If you have multiple <style> blocks scattered throughout your document, consolidate them all into a single <style> element in the <head>, or better yet, move them into an external .css file. This ensures valid HTML, predictable rendering across browsers, and cleaner document structure.
In earlier versions of HTML (HTML 4 and XHTML), the type attribute was required on the <style> element to declare the MIME type of the styling language being used. The value was almost always text/css, as CSS has been the dominant stylesheet language for the web since its inception.
With HTML5, the specification changed. The type attribute on <style> now defaults to text/css, and since no browser supports any other styling language, the attribute serves no practical purpose. The WHATWG HTML Living Standard explicitly notes that the attribute is unnecessary and can be omitted. The W3C validator flags its presence as a warning to encourage cleaner, more modern markup.
Why This Matters
- Cleaner code: Removing unnecessary attributes reduces file size (even if marginally) and improves readability. Every attribute should earn its place in your markup.
- Standards compliance: Modern HTML encourages omitting default values when they add no information. Including type="text/css" signals outdated coding practices.
- Consistency: The same principle applies to <script> elements, where type="text/javascript" is also unnecessary. Keeping your markup consistent by omitting both makes your codebase easier to maintain.
How to Fix It
The fix is straightforward: find every <style> element in your HTML that includes a type attribute and remove it. No other changes are needed — the browser behavior will be identical.
If you’re working on a large codebase, a simple search for <style type= across your files will help you find all instances.
Examples
❌ Incorrect: Redundant type attribute
<style type="text/css">
p {
color: red;
}
</style>
<p>This text will be red.</p>
The type="text/css" attribute is unnecessary and triggers the W3C validator warning.
✅ Correct: type attribute omitted
<style>
p {
color: red;
}
</style>
<p>This text will be red.</p>
Without the type attribute, the browser still interprets the contents as CSS — the behavior is exactly the same.
❌ Incorrect: Other variations that also trigger the warning
The warning is triggered regardless of how the type value is formatted:
<style type="text/css" media="screen">
body {
font-family: sans-serif;
}
</style>
✅ Correct: Other attributes are fine, just remove type
<style media="screen">
body {
font-family: sans-serif;
}
</style>
Note that other valid attributes like media or nonce should be kept — only the type attribute needs to be removed.
Ready to validate your sites?
Start your free trial today.