To demonstrate why you shouldn't have errors in your HTML source, here are some examples where browsers differ
in how they display erroneous HTML, while they all look the same if your HTML is error-free.
Note that more and more browsers are being based on the Blink rendering engine; for instance Edge v74 and up are,
which accounts for differences between versions of the same program.
Using the same ID value more than once causes browsers to behave differently.
#one:target {color:#E6E6E0; background:#0F0F0A}
..
<p id="one">This is the one.</p>
<p id="one">This is the one.</p>
<p id="one">This is the one.</p>
Browser | Result |
---|---|
Firefox 3.0 .. 83 SeaMonkey 2.12 .. 2.57 |
Highlights the first paragraph |
Chromium 6 .. 87 Safari 5 .. 14 Microsoft Edge 74 .. 86 Konqueror 4 |
Highlights the first paragraph |
Internet Explorer 9 .. 11 Microsoft Edge 15 .. 18 |
Highlights all paragraphs |
Opera 11 .. 12 | Highlights the first paragraph |
If you use tag names that are not officially defined HTML, there are browsers that feel free to treat them the way they want.
<style> two:nth-of-type(2) {text-decoration:underline} </style>
..
<one>one</one>
<two>two</two>
<one>one</one>
<two>two</two>
Browser | Result |
---|---|
Firefox 3.6 .. 83 SeaMonkey 2.1 .. 2.57 |
underlines the second <two> |
Chrome 6 .. 87 Safari 5 .. 14 Konqueror 4 |
underlines the second <two> |
Internet Explorer 9 .. 11 Microsoft Edge 14 .. 15 |
underlines the first <two> |
Microsoft Edge 16 .. 86 | underlines the second <two> |
Opera 11 .. 12 | underlines the second <two> |
Reaction to mismatched tags varies greatly and depends on what the tags are.
Normal text
<address>address with h5 end tag</h5>
Normal text
Normal text
<address>address with p end tag</p>
Normal text
Normal text
<h4>h4 with h5 end tag</h5>
Normal text
Browser | Result 1 | Result 2 | Result 3 |
---|---|---|---|
Firefox 3.0 .. 3.6 SeaMonkey 2.0 |
Ignores end tag | Ignores end tag | Ends h4 as if end tag was ok |
Firefox 4 .. 83 SeaMonkey 2.1 .. 2.57 |
Ignores end tag | Inserts p in address | Ends h4 as if end tag was ok |
Chromium 5 .. 6 | Ignores end tag | Inserts p in address | Ignores end tag |
Chromium 10 .. 87 Safari 5 .. 14 Konqueror 4(W) |
Ignores end tag | Inserts p in address | Ends h4 as if end tag was ok |
Internet Explorer 7 .. 8 | Inserts h5 in address | Inserts p in address | Ends h4 as if end tag was ok |
Internet Explorer 9 .. 11 Microsoft Edge 14 .. 86 |
Ignores end tag | Inserts p in address | Ends h4 as if end tag was ok |
Opera 9 .. 12 | Ignores end tag | Inserts p in address | Ends h4 as if end tag was ok |
Konqueror 3 | Ignores end tag | Ignores end tag | Ignores end tag |
Konqueror 4(K) | Ignores end tag | Ends address; adds p | Ignores end tag |
<p id="test">You should see only this line (with end tag).</p>
<script type="text/javascript"> <!--
var text = document.createTextNode('</script>');
document.getElementById('test').appendChild(text);
//-->
</script>
Browser | Result |
---|---|
Firefox 3.0 .. 83 SeaMonkey 2.0 .. 2.57 |
Script ends halfway, rest of script is displayed in the window |
Chromium 5 .. 6 Konqueror 3 .. 4(K) |
Script runs in its entirety¹ |
Chromium 10 .. 87 Safari 5 .. 14 Konqueror 4(W) |
Script ends halfway, rest of script is displayed in the window |
Internet Explorer 7 .. 9 | Script runs in its entirety¹ |
Internet Explorer 10 .. 11 Microsoft Edge 14 .. 86 |
Script ends halfway, rest of script is displayed in the window |
Opera 9 .. 11 | Script runs in its entirety¹ |
Opera 12 | Script ends halfway, rest of script is displayed in the window |
</script>
too.<div> Before <li> a list item </li> and after </div>
<div> Before <optgroup> an opt group </optgroup> and after </div>
<div> Before <rt> a ruby text </rt> and after </div>
Browser | With li | With optgroup | With rt |
---|---|---|---|
Firefox 3.0 SeaMonkey 2.0 |
Block; bullet left of left edge | Text put in parent | (not recognised) |
Firefox 10 .. 83 SeaMonkey 2.7 .. 2.57 |
Block; bullet left of left edge | Collapsed block content not visible |
(not recognised until v36) Superscripted |
Chromium 5 .. 87 Safari 5 Microsoft Edge 15 .. 86 |
Block. Has padding | Block content not visible | Inline |
Safari 9 .. 14 Konqueror 4(W) |
Block. Has padding | Invisible | Inline |
Internet Explorer 7 | Block (but IE7 ignores the </li> end tag)Has padding |
Text put in parent | Text put in parent |
Internet Explorer 8 .. 9 | Block; bullet left of left edge | Text put in parent | Text put in parent |
Internet Explorer 10 .. 11 Microsoft Edge 18 |
Block; bullet left of left edge | Block content not visible | Inline |
Microsoft Edge 14 | Block; bullet left of left edge | Inline, with a bold font | Inline |
Opera 9 .. 11 | Block. Has padding. | Text put in parent | (not recognised) |
Opera 12 | Block. Has padding. | Inline | (not recognised) |
Konqueror 4(K) | Text put in parent | Text put in parent | Inline |
When an element's attribute values differ from the CSS styles for the element, the CSS styles
usually take preference over the attribute.
Usually, but not always.
<hr color="red" style="color:blue">
Browser | Result |
---|---|
Firefox 3.0 .. 83 SeaMonkey 2.0 .. 2.57 |
blue |
Chromium 5 .. 87 Safari 5 .. 14 Konqueror 3 .. 4 |
red |
Internet Explorer 7 | blue |
Internet Explorer 8 .. 11 Microsoft Edge 14 .. 86 |
red |
Opera 9 .. 12 | red |
<link rel="stylesheet" href="error-19a-css.css" type="text/html">
Browser | Result |
---|---|
Firefox 3.0 .. 83 SeaMonkey 2.0 .. 2.57 |
Doesn't use stylesheet |
Chromium 6 .. 20 Safari 5 .. 9 Konqueror 3 .. 4 |
Ignores type, shows style normally |
Chromium 57 .. 87 Safari 14 |
Doesn't use stylesheet |
Internet Explorer 7 .. 11 Microsoft Edge 14 .. 86 |
Doesn't use stylesheet |
Opera 9 .. 12 | Doesn't use stylesheet |
In Quirks mode, browsers are supposed to ignore the file type of the stylesheet, and to load it anyway. Some browsers are not playing though.
<link rel="stylesheet" href="quirks-19c-css.txt">
Browser | Result |
---|---|
Firefox 3.0 .. 83 SeaMonkey 2.33 .. 2.53 |
Loads stylesheet |
Chromium 15 .. 20 Safari 5 .. 14 Konqueror 4 |
Loads stylesheet |
Chromium 73 | Doesn't load stylesheet |
Chrome 81 .. 87 | Loads stylesheet |
Internet Explorer 7 .. 8 | Loads stylesheet |
Internet Explorer 9 | Doesn't load stylesheet |
Internet Explorer 11 Microsoft Edge 15 .. 86 |
Loads stylesheet |
Opera 10 .. 12 Vivaldi 1.3 |
Loads stylesheet |
Trying to show an img without a src attribute
<img style="width:30px; height:30px; background:lime"><br>
<img style="width:30px; height:30px; background:lime" alt="square">
Browser | Without alt | With alt |
---|---|---|
Firefox 3.0 .. 60 SeaMonkey 2.0 .. 2.57 |
Nothing | Keeps background, alt text |
Firefox 68 .. 83 | Keeps size, background. Has border | Keeps background, alt text |
Chromium 5 .. 35 Safari 5 .. 14 Konqueror 4(W) |
Keeps size, background. Has border | Keeps size, background. Has border |
Chromium 55 .. 59 | Keeps size, background. Has border | Keeps size, background; shows partial alt text. Has border |
Chromium 63 .. 64 | Keeps size, background. Has border | Keeps background, alt text |
Chromium 65 .. 87 Microsoft Edge 74 .. 86 |
Keeps size, background. Has border | Keeps background, alt text; shows broken image icon |
Internet Explorer 7 .. 10 | Keeps size, background. Has border and a broken image icon | Keeps size, background. Has a broken image icon |
Internet Explorer 11 Microsoft Edge 14 .. 18 |
Keeps size, background | Keeps size, background; shows partial alt text. |
Konqueror 3 .. 4(K) | Keeps size, background. Has border and a broken image icon | Keeps size, background. Has border and a broken image icon |
Opera 9 .. 12 | Keeps size, background | Keeps size, background, alt text. Has border |
If you have a font name which happens to be a CSS keyword, or which contains characters that are not letters, you get inconsistencies when you omit the quotes around the name.
<div style="font:1.5em Caption">This is 1.5em Caption</div>
<div style="font:1.5em Default">This is 1.5em Default</div>
<div style="font:1.5em Inherit">This is 1.5em Inherit</div>
<div style="font:1.5em Initial">This is 1.5em Initial</div>
<div style="font:1.5em Courier 10 Pitch">This is 1.5em Courier 10 Pitch</div>
Which style rules are used and which are not, is evident by the larger text size: when the style is considered OK,
the "1.5em" part is applied, even if a font with that name can't be found.
"Courier 10 Pitch" is a real font, by the way, and if you're wondering, no, it's not the spaces in the name that cause the problems.
Browser | with Caption |
with Default |
with Inherit |
with Initial |
with Courier 10 Pitch |
---|---|---|---|---|---|
Firefox 3.0 .. 17 SeaMonkey 2.0 .. 2.14 |
Used | Used | Not used | Used | Not used |
Firefox 20 SeaMonkey 2.17 |
Used | Used | Not used | Not used | Not used |
Firefox 25 .. 83 SeaMonkey 2.22 .. 2.57 |
Used | Not used | Not used | Not used | Not used |
Chromium 6 .. 15 Safari 5 Konqueror 3 .. 4(K) |
Used | Used | Not used | Used | Not used |
Chromium 20 | Used | Used | Not used | Not used | Not used |
Chromium 25 .. 87 Safari 9 .. 14 Microsoft Edge 74 .. 86 Konqueror 4(W) |
Used | Not used | Not used | Not used | Not used |
Internet Explorer 7 | Used | Used | Used | Used | Used |
Internet Explorer 8 | Used | Used | Used | Used | Used |
Internet Explorer 9 .. 11 | Not used | Not used | Not used | Not used | Used |
Microsoft Edge 14 .. 18 | Not used | Used | Used | Used | Not used |
Opera 9 | Used | Used | Used | Used | Used |
Opera 10 | Used | Used | Not used | Used | Used |
Opera 11 .. 12 | Used | Used | Not used | Used | Not used |
Other font names that consist of CSS keywords, such as Unset
, are problematic too.
So the bottom line is it's best to always use quotes.
For a more in depth article on font names and quotes, you can read my blog post here.
There is a border around <span style="border:1em outset#777">this span</span>.
If you forget the space in the shorthand property, the results vary.
Browser | Result |
---|---|
Internet Explorer 9 .. 11 | Does not show border |
All other browsers tested, including Edge | Shows border |
If you forget the closing parenthesis in a css function such as rgb(...)
, the results vary.
<p style="background-image:url(pic.png">
Missing parenthesis in url
</p>
<p style="background:linear-gradient(#EC2, #E60">
Missing parenthesis in linear-gradient
</p>
Browser | Result with url | With linear-gradient |
---|---|---|
Firefox 10 .. 83 SeaMonkey 2.7 .. 2.57 |
Pretends all is fine | Pretends all is fine |
Chromium 15 .. 20 Safari 5 Konqueror 4 |
Ignored | Ignored |
Chromium 55 .. 87 Safari 14 Microsoft Edge 86 |
Pretends all is fine | Pretends all is fine |
Internet Explorer 11 Microsoft Edge 14 |
Pretends all is fine | Ignored |
Microsoft Edge 15 .. 18 | Pretends all is fine | Pretends all is fine |
Opera 10 .. 12 | Ignored | Pretends all is fine |
Note that this is one area where the rules are clear: if there's an error like that, the style should be ignored. In other words, some browsers used to handle this correctly in the past, but don't any more!
The Symbol font is meant for displaying several Greek and mathematical symbols. However, there are right ways and wrong ways to use it. Long ago, the right way was to set this as your display font and write ASCII letters. So if you wanted "Η γρηγορη καφε αλεπου πηδαει πανω απο ενα τεμπελης σκυλι.", you wrote something like
<div style="font-family:'Symbol'">
H grhgorh kafe alepou phdaei panw apo ena tempelhV skuli.
</div>
These days, if you try that, it will come out as
Browser | Result |
---|---|
Firefox 3.0 .. 83 SeaMonkey 2.0 .. 2.57 |
Shows ASCII text |
Chromium 6 .. 73 (Linux) Safari 9 .. 14 (iOS) Konqueror 3 |
Shows ASCII text |
Chrome 5 .. 87 (Windows) Safari 5 Microsoft Edge 74 .. 86 Konqueror 4 |
Shows Greek |
Internet Explorer 7 .. 11 | Shows Greek |
Microsoft Edge 14 | Shows ASCII text |
Microsoft Edge 17 .. 18 | Shows Greek |
Opera 9 (Linux) | Shows ASCII text |
Opera 11 .. 12 (Linux) | blank |
Opera 10 .. 12 (Windows) | Shows ASCII text |
Note that this is one of the few instances where I found differences between operating systems. Maybe we shouldn't be using Symbol at all any more.
The title of the page is supposed to be plain text, that is, it can't contain markup.
<title>Error test 32: <i>Markup</i> in the title</title>
The results are remarkably similar across browsers, however they differ between operating systems: in Windows, all browsers display "<i>Markup</i> in the title". Some versions of Linux do interpret the markup and display "Markup in the title" in the title bar, while other versions have "<i>Markup</i> in the title" like in Windows. They all have "<i>Markup</i> in the title" in the tab.
Note that the definition of how comments are parsed is different for HTML5 than it was for SGML-based HTML, in the
old days. So be careful with them: what is an error today, like <!-- comment -- >
, was perfectly
acceptable in SGML. And reversely, <!-- comment-- -->
is OK to modern browsers now, but was
treated as an incomplete comment before. To play it safe, play by the rules: don't use two dashes in a row
and don't have spaces before the closing >
.
However, the browsers don't all play by the rules; both the modern ones that are HTML5-aware and the old ones that only know about SGML differ in what they consider correct or not.
<ol>
<li>too few dashes: before <!--> and after <br title=--> </li>
<li>too many dashes: before <!-- -- --> and after <br title=--> </li>
<li>too many spaces: before <!-- -- > and after <br title=--> </li>
<li>nested comments: before <!-- <!-- --> --> and after <br title=--> </li>
</ol>
The browser will display "before and after" if it sees a complete comment. If it doesn't, it only displays
"before", because the text "and after" will be part of the comment.
Note that the <br title=-->
is an error recovery device in case the comment was incomplete: this
will end it. Otherwise it's just a line break with a title.
The fourth example is supposed to end at the first -->
according to the rules, displaying the
following -->
on the screen.
Browser | Result 1 | Result 2 | Result 3 | Result 4 |
---|---|---|---|---|
Firefox 3.0 .. 3.6 SeaMonkey 2.0 |
not complete | not complete | complete | Ends too late¹ |
Firefox 10 .. 83 SeaMonkey 2.7 .. 2.57 |
complete | complete | not complete | Ends properly |
Chromium 6 Konqueror 4(L) |
not complete | complete | not complete | Ends properly |
Chromium 15 .. 87 Safari 5 .. 14 Konqueror 4(W) |
complete | complete | not complete | Ends properly |
Internet Explorer 7 .. 11 Microsoft Edge 14 .. 86 |
complete | complete | not complete | Ends properly |
Opera 9 | not complete | complete | not complete | Ends properly |
Opera 10 .. 11 | not complete | complete | complete | Ends properly |
Opera 12 | complete | complete | not complete | Ends properly |
¹ Only in Standards mode though; in Quirks mode; acts just like the other browsers.
The parameters in the font
style are supposed to be in this order: font-style font-variant
font-weight font-size/line-height font-family. See the W3C Fonts page. Most of them are optional,
so you can leave them out if you want, but you cannot put them out of order. A font
style
with parameters in the wrong places is an error and will be ignored.
That is, in theory. In practice, browsers differ in what they consider errors and what they don't.
<ol style="font-size:13px; font-style:normal; font-family:serif>
<li style="font:18px normal monospace">18px normal monospace</li>
<li style="font:18px normal 'Arial'">18px normal 'Arial'</li>
<li style="font:italic 18px 700 'Arial'">italic 18px 700 'Arial'</li>
<li style="font:18px italic 'Arial'">18px italic 'Arial'</li>
</ol>
Browser | Result 1 | Result 2 | Result 3 | Result 4 |
---|---|---|---|---|
Firefox 3.0 | uses size | ignored | ignored | uses size, family |
Firefox 3.5 .. 60 SeaMonkey 2.0 .. 2.57 |
uses size; default family | ignored | ignored | ignored |
Chromium 6 .. 31 Safari 5 .. 9 Vivaldi TP3 |
uses size; default family | uses size, family | ignored | uses size, family |
Chromium 55 .. 87 | uses size; default family | ignored | ignored | ignored |
Internet Explorer 7 | uses size | uses size | uses size | uses size |
Internet Explorer 8 | uses size | uses size | ignored | uses size |
Internet Explorer 9 .. 11 | uses size; default family | uses size; default family | ignored | uses size; default family |
Microsoft Edge 14 .. 86 | uses size; default family | ignored | ignored | ignored |
Opera 9 | ignored | ignored | uses size, weight, family | ignored |
Opera 10 .. 12 | uses size | ignored | uses size, weight, family | ignored |
Konqueror 4 | uses size | uses size, family | ignored | uses size, family |
<div style="color:Copper"> Copper </div>
<div style="color:LightSlateBlue"> LightSlateBlue </div>
Browser | Result 1 | Result 2 |
---|---|---|
Firefox 3.0 .. 83 SeaMonkey 2.0 .. 2.57 |
- | - |
Chromium 6 .. 36 Safari 5 .. 9 Konqueror 4(W) |
- | √ |
Chromium 55 .. 87 Safari 14 Vivaldi 1.12 |
- | - |
Internet Explorer 8 .. 11 Microsoft Edge 14 .. 86 |
- | - |
Opera 9 .. 12 | √ | √ |
Konqueror 4(K) | - | - |
If a table has a number of columns defined with <col>, but there are fewer columns in the body of the table, there is a mismatch.
<table>
<col span="6" width="70">
<tr><td>one</td><td>two</td><td>three</td></tr>
</table>
Browser | Result |
---|---|
Firefox 3.6 .. 60 SeaMonkey 2.0 .. 2.57 |
table is six columns wide |
All other browsers tested so far | table is three columns wide |
Column definitions in tables should always go before the first table row. If you forget that...
<table>
<tr><td>one</td><td>two</td><td>three</td></tr>
<col span="3" width="100">
</table>
Browser | Result |
---|---|
Firefox 3.6 .. 60 SeaMonkey 2.1 .. 2.57 |
Columns are the specified 100px wide |
Chromium 6 .. 20 Safari 5 .. 14 Konqueror 4 |
Columns have their default widths, ignoring the col definition |
Chromium 37 .. 87 Vivaldi TP3 |
Columns are the specified 100px wide |
Internet Explorer 7 | Columns have their default widths, ignoring the col definition |
Internet Explorer 8 .. 11 Microsoft Edge 14 .. 86 |
Columns are the specified 100px wide |
Opera 9 .. 12 | Columns have their default widths, ignoring the col definition |
Browsers usually ignore bad attribute values altogether. But apparently not always!
<table border="1">
<tr>
<td valign="botto" height="60">This is a bad td</td>
</tr>
</table>
Browser | Result |
---|---|
Firefox 10 .. 83 SeaMonkey 2.7 .. 2.57 |
Ignored; aligned to middle as normal |
Chromium 6 .. 87 Safari 5 .. 14 Microsoft Edge 74 .. 86 Konqueror 4 |
Ignored; aligned to middle as normal |
Internet Explorer 8 .. 11 Microsoft Edge 14 .. 18 |
td is now aligned to top |
Opera 9 .. 11 | td is now aligned to top |
Opera 12 | Ignored; aligned to middle as normal |
You shouldn't assign a border
property to a tr
. It won't have any effect.
That is, if you're lucky.
In some circumstances, some browsers will protest by throwing the table out of alignment.
<table style="border:1px solid red" dir="rtl">
<tr style="border:5px solid blue">
<td style="border:1px solid green">Test</td>
</tr>
</table>
Browser | Result |
---|---|
Firefox 3.0 .. 40, 71 and up SeaMonkey 1.9 .. 2.35 |
Ignored; no effect |
Firefox 41 .. 69 SeaMonkey 2.38 .. 2.57 |
The td is drawn 10 pixels to the right (2× the width of the tr border) |
All other browsers tested so far | Ignored; no effect |
Basically the same as above. Table rows don't have backgrounds of themselves, so if you assign a background to a
row, it's up to the browsers to decide what to do with it.
Naturally, this may result in some differences.
<table style="width:200px; height:100px">
<tr style="background:url(bkgnd.png)">
<td>One</td><td>Two</td>
</tr>
</table>
Browser | Result |
---|---|
Firefox 3.0 .. 60 SeaMonkey 2.0 .. 2.57 |
Cells are windows on the tr, showing different parts of the background image |
Chromium 15 .. 57 Safari 5 .. 14 Konqueror 4(W) |
Acts as if cells inherit the style, all showing the same part of the background image |
Chromium 58 .. 87 | Cells are windows on the tr, showing different parts of the background image |
Internet Explorer 7 | Acts as if cells inherit the style, all showing the same part of the background image |
Internet Explorer 8 .. 11 Microsoft Edge 14 .. 86 |
Cells are windows on the tr, showing different parts of the background image |
Opera 10 .. 12 | Cells are windows on the tr, showing different parts of the background image |
Konqueror 4(K) | Cells are windows on the tr |
The legend should be the first thing in a fieldset. If you forget that, you get differences in how the browsers display it.
<form action="#">
<fieldset>
Text before legend
<legend>The legend</legend>
Contents of fieldset: <input name="contents"> <input type="submit">
</fieldset>
</form>
Browser | Result |
---|---|
Firefox 52 .. 83 SeaMonkey 2.49 .. 2.57 |
Looks normal; Text is inside the fieldset |
Chrome 63 .. 87 Safari 9 .. 14 Microsoft Edge 74 .. 86 |
Text is inside the fieldset; behaves as a block |
Internet Explorer 5 .. 11 Microsoft Edge 15 .. 18 |
Text appears above the fieldset |
Opera 12 | Text is inside the fieldset, followed by text "The legend" (which does not behave as a legend) |
calc()
Certain values are illegal in CSS, for instance negative padding values.
In some circumstances, not all browsers play by the rules.
<div style="border: 1px solid; padding-left: calc(0px - 2em);">
This is a div with a negative left padding
</div>
Browser | Result |
---|---|
Internet Explorer 9 .. 11 | Applies the negative padding, resulting in content partially out of the confines of the div. |
All other browsers tested, including Edge | Ignore the error |
href=""
Links with href attributes should lead somewhere. And they usually do, but the empty href href=""
is an exception.
<a href="">Go nowhere</a>
Browser | Result |
---|---|
Internet Explorer 8 .. 11 | Goes to the current directory, i.e. loads the default index.html |
All other browsers tested, including Edge | Reloads the current file |
::after
pseudo-element on void elementsVoid elements do not have content by definition, so they can't have pseudo-content either. If you ignore that, the browsers don't all react the same.
<style> area::after {content:'This is the area'; display:inline;} </style>
..
<map name="map1"> <area href="#" coords="0,0,150,75" alt="click here"> </map>
<img usemap="#map1" src="//dummyimage.com/150x75" alt="click here">
Browser | Result |
---|---|
Firefox 3.0 .. 83 | Does not show the content |
Internet Explorer 8 | Does not show the content |
Internet Explorer 9 .. 11 Microsoft Edge 15 .. 18 |
Shows the content |
Safari 5 .. 14 Chromium 15 .. 20 Konqueror 4 |
Does not show the content |
Chromium 56 .. 87 Microsoft Edge 86 |
Shows the content |
Opera 10 .. 12 | Does not show the content |
Sources: various. Some is the result of my own research, some I found all over the web.