CodeLair website tutorials, articles & scripts

Deprecated & obsolete elements in HTML 5

Published: 10 January 2014   •   Updated: 1 August 2022   •   Tags: html

Several years ago, I wrote an extensive article on deprecated elements in HTML 4. Now, with HTML 5 as the current standard, there are several more elements, attributes and techniques that are not recommended nor necessary today.

As a reminder, ‘deprecation’ refers to the process of marking elements in the specification as obsolete, which means they will be removed from the spec in the future. Generally, web browsers will continue to support them for some time, but they should not be relied upon.

In most cases, the elements are superseded by CSS usage. Below we list examples of the code you should no longer be using, and the best replacements for it.

Features already deprecated #

The following elements were deprecated in HTML 4:

  • <applet>
  • <basefont>
  • <big>
  • <center>
  • <dir>
  • <font>
  • <isindex>
  • <strike>

Furthermore, various presentational attributes like bgcolor, border and align are deprecated and should be achieved using CSS instead. Appropriate replacements can be found in our previous article.

Elements back from the dead #

As well as deprecating features, some elements have also been repurposed in HTML 5.

  • <b> - bold text - now represents ‘a span of text to which attention is being drawn without conveying any extra importance’. Examples include key words or product names.
  • <cite> - citation - now represents ‘the title of a work’ only and not a person. Examples include a book, poem, film, TV show, game, or song.
  • <i> - italic text - now represents ‘a span of text in an alternate voice or mood’. Examples include a technical term, a thought, or a ship name.
  • <menu> - menu list - now represents ‘a toolbar or popup menu’.
  • <s> - strikethrough text - now represents ‘contents that are no longer accurate or relevant’. This is slightly different from <del> which represents a removal from the document.
  • <small> - small text - now represents ‘side comments such as small print’.
  • <u> - underlined text - now represents ‘a span of text with a non-textual annotation’. Includes labelling text as being misspelt.

Now on to the new deprecated features.

Old monolithic DOCTYPEs #

All web pages should start with a valid ‘doctype’. Prior to HTML5 we had many different doctypes for different levels of standards support:

<!-- HTML 4 strict -->

<!-- HTML 4 loose -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">

<!-- HTML 4 frames -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "">

<!-- XHTML 1 strict -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">

<!-- XHTML 1 loose -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">

Instead, the doctype for all web pages should now be:

<!DOCTYPE html>

This is supported by all browsers, without any issues or quirks. It’s also very easy to remember!

Frames #

Frames were an interesting feature in the early days of HTML. As most websites have a common header or sidebar menu, downloading that on every page you visited could be slow on older connections. For developers, having to update the menu across every page was tedious. Frames allowed you to put your menu in one HTML file and each content page of the website in separate files. When the visitor first came to the site both pages would load, but on further navigation only the frame containing the content page would need to load.

The HTML looked something like this:

<frameset cols="25%,75%">
<frame src="sidebar.html">
<frame src="main.html">

However this came with its own performance problems. It required downloading multiple pages - firstly the index page (the above code), then all the pages referenced. So it could actually end up slower for most people. There were also many usability and accessibility problems.

Before long, server-side includes took off so webmasters could update one menu or template file to apply changes to their entire site. Nowadays there are many server-side and client-side frameworks to ease development. Frames are just not needed today.

The TYPE attribute for scripts and stylesheets #

Ever since stylesheets and scripting were introduced, browsers have only ever supported CSS and JavaScript respectively (although in the case of JS there were many small differences between Internet Explorer and Netscape).

As such, all appropriate elements default to CSS of JavaScript, so there is no need to specify the type attribute. Instead of:

<link rel="stylesheet" type="text/css" href="stylesheet.css">
<style type="text/css">
/* some CSS styles */

<script type="text/javascript" src="library.js"></script>
<script type="text/javascript">
// some JavaScript code

We should now use:

<link rel="stylesheet" href="stylesheet.css">
/* some CSS styles */
<script src="library.js"></script>
// some JavaScript code

Furthermore, the use of comments or CDATA blocks to hide CSS/JS from older browsers is not necessary at all. Don’t do any of these:

{ display: block; }

var JS = 'example';

var JS = 'example';


The ACRONYM element #

In HTML 4 two elements <abbr> and <acronym> were defined, for abbreviations and acronyms respectively. However, the difference between the tags was a little muddled and in fact there isn’t any reason to distinguish between the tags. Since an acronym is a type of abbreviation, from HTML 5 only the <abbr> tag is acceptable. Here’s an example of usage:

<p>The <abbr title="British Broadcasting Corporation">BBC</abbr> is the most-watched network on UK television.</p>

The BGSOUND element #

This was an old element only supported by Internet Explorer, which played an audio file when the web page was loaded:

<bgsound src="music.mid" loop="infinite">

Auto-playing music is heavily discouraged on websites, but HTML 5 defines a new <audio> element that can be used if so desired:

<audio src="music.mp3" controls loop>
Sorry, your web browser does not support the HTML 5 audio element.

The controls attribute adds standard play/pause controls, while loop makes the audio repeat infinitely. There is also an autoplay attribute but its use is strongly discouraged.

The TT element #

<tt> was used to style text as ‘teletype’ (monospaced). It should be replaced by a more appropriate element:

  • <code> for computer code
  • <kbd> for keyboard input
  • <samp> for sample computer output
  • <var> for variables
  • <pre> for a block of pre-formatted text

The <code>, <kbd>, and <samp> elements are displayed in monospace font by default, while <var> is displayed in the default font, but italic. Here is one possible style for inline <code> elements:

code {
padding: 1px 3px;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 3px;
color: #444;
font-size: inherit;

The NOBR element #

This is another proprietary element, however this one is actually well-supported. It simply prevents any line breaks from occurring inside the tag:

<p>You can contact us by phone on <nobr>08000 123 456.</nobr></p>

The tag should be replaced with the CSS white-space property.

.number { white-space: nowrap; }

<p>You can contact us by phone on <span class="number">08000 123 456.</span></p>

These were never standard elements (they were introduced by Netscape in the 1990s), but are noted in the HTML 5 spec as obsolete. The <blink> tag caused an element’s visibility to toggle on and off repeatedly. The <marquee> tag caused text to scroll across the screen, like an electronic banner.

Both elements have been considered to be bad practice for a long while now since flashing and moving objects can be annoying. However, in the interest of education, here is one way to recreate each element.

For blink:

@-webkit-keyframes blink {
0% {
visibility: hidden;
-webkit-animation-timing-function: step-end;
25%, 100% {
visibility: visible;
@keyframes blink {
0% {
visibility: hidden;
animation-timing-function: step-end;
25%, 100% {
visibility: visible;
.blink {
-webkit-animation: blink 2s infinite;
animation: blink 2s infinite;

<p class="blink">Blinking 'eck!</p>

For marquee:

@-webkit-keyframes marquee {
0% {
-webkit-transform: translateX(200px);
95%, 100% {
-webkit-transform: translateX(-110%);
@keyframes marquee {
0% {
transform: translateX(200px);
95%, 100% {
transform: translateX(-110%);
.mq-container {
width: 200px;
overflow: hidden;
padding: 5px;
background-color: #ddd;
white-space: nowrap;
font: 14px monospace;
.marquee {
display: inline-block;
-webkit-animation: marquee linear 10s infinite;
animation: marquee linear 10s infinite;

<div class="mq-container">
<span class="marquee">
Now playing: Feel Good Hit of the Summer by Queens of the Stone Age

Attributes on the OBJECT element #

This element is not used very much at all now, as mobile browsers do not support Java applets or Flash. But a few attributes should not be used:

  • classid was the location of the main class file for applets. The data attribute should be used instead.
  • code, archive, codebase, and codetype were all similar attributes, also replaced by data.
  • declare was used to allow the object to download but not instantiate, until a later <object> element did so. Instead the full object can be repeated each time it’s needed.
  • standby was a message to be shown while loading. There is nothing specific to replace it, but faster internet connections these days mean it’s not necessary.

The REV attribute #

This was supposed to be a counterpart to the rel attribute to indicate backward links, such as the previous page in a navigation list. However, it seems there was no real need for the distinction. The value of the attribute can sometimes be used to determine this - for example rel="prev" is used for the previous page, alongside rel="next" for the next page.

Adding name to a link allowed for that element to be linked to within a page - i.e. an anchor. For example:

<!-- at the top -->
<a href="#answers">View answers</a>

<!-- at the bottom -->
<a name="answers"></a>
<h2>Answers to the quiz...</h2>

Clicking the “View answers” link would scroll the user to the latter <a> tag. This is now obsolete as the id attribute serves the same purpose, and can be used with any element. We can simplify our example to this:

<!-- at the top -->
<a href="#answers">View answers</a>

<!-- at the bottom -->
<h2 id="answers">Answers to the quiz...</h2>

The LONGDESC attributes #

This attribute, used on images, would contain a URL to a separate page with a longer description of the image. Similar to alt text it isn’t displayed in browsers, but intended for screenreaders, and useful when the image is complex and requires a lot of explanation. Unfortunately screenreaders did not support it for a long time and it fell by the wayside.

One option for screenreaders is to use aria-describedby with the value set to the ID of another element in the document. For example:

<img src="graph.jpg" alt="A graph showing the number of thing sold in some time period" aria-describedby="graph-description">

<p id="graph-description">The longer description of the graph, perhaps listing the exact data for each thing sold.</p>

Or alternatively, a <figure> element with a text description visible for everyone.

The LOWSRC attributes #

Another image attribute, lowsrc was a link to a low resolution version of the image to show while the full image is loading. However in practice this attribute never worked in any browser.

2021 edit: these days there is a new option: loading="lazy". This helps solve the original problem of images increasing page load times. It stops the image from loading entirely until it comes into the viewport. Example:

<img src="photo.jpg" alt="Description" loading="lazy">

And many more… #

The official HTML 5 specification includes a page on obsolete features. There are many more than listed in this article, but most of them were never well-supported or well-known.