Alert! Your web browser does not fully support Cascading Style Sheets! Our website works best using using one of the following modern web browsers: Chrome, Firefox, Edge.
Welcome! I built this HTML 5 Tutorial Page to help new web developers and designers around the world learn how to code web pages the right way! After seeing so many developers struggling with basic HTML and CSS over the years, I decided to create this comprehensive HTML 5 tutorial to help everyone. I hope you will use it to learn HTML or improve upon your own HTML coding skills.
This HTML 5 Tutorial has all the code needed to start building your web pages quickly. It is based on 20+ years of direct experience writing HTML web pages and has all the goodies needed for your HTML to work in web browsers and devices today (2022) as well as browsers going back to the early days of the World Wide Web (1990's)!
As such, this tutorial is less of an introduction to markup languages and web development, and more of a "crib sheet" or quick reference page for HTML 5. In that sense, you will find this page is a very powerful tool for cutting-and-pasting markup directly into your own pages without having to cobble code together. You can therefore skip to various sections in this page and copy the code directly into your own without having to read through the complete tutorial. I designed it to work this way so developers could skip all the other incomplete tutorials online and use mine as a complete codebase for all your web projects.
This web tutorial consists of two main sections: An HTML 5 listing of all the elements with my recommended attributes, and a special "Best Practices" section which lists lots of tricks and traps I have discovered in HTML 5 and CSS that will help you become a better coder. Both sections have code you can copy directly into your web projects. They are complete with all the right markup, attributes, and code based on over 20+ years of working with HTML.
Why did I build this HTML5 tutorial, when there is so much material online about HTML5 and how to get started building web pages? Sadly, most of the training and tutorials you will find on the World Wide Web for HTML and CSS are not complete and missing most of the required tricks and techniques needed to code in those languages. To account for that lack of learning, many young developers then turn to 3rd party scripted products that they hope will solve all their web development problems. But nearly all these web development products fail because they do not adequately address all the various issues in web browsers, past and present. In implementing these modern software solutions, many development groups are then dependent on outside technology to solve problems instead of learning to code in HTML and CSS. I have seen this problem first hand at many corporations I have worked for. They then rely on developers who know the tools but not the code! They are not experienced enough in markup or style sheet languages to know how to address all the bugs and issues in browsers of the past, much less those built today specifically for HTML5.
The fact is, there is so much knowledge and expertise needed in building solid HTML/CSS web applications today that relying on these 3rd party products, then failing to even learn basic HTML and CSS, means you are "half a web developer". For that reason, I decided it was critical I preserve for posterity this wealth of HTML5 coding information for the web development community so that they will not have to rely on products or JavaScripted solutions to build web pages ever again. The fact is, you should always learn coding from experienced web developers. Failing to learn from the past and from older developers means most new developers today will stumble and have to "rediscover" the same solutions after years of coding. The fact is, you MUST learn how to code HTML and CSS yourself before you can rely on these poorly written products. And you can only do that learning from others. Anything written by Mankind will always have flaws. The web browsers written by people today, and in the past, are FULL of bugs. Web browsers will always be "buggy". You just need to know the tricks to fix the bugs in your HTML so your web pages are parsed correctly and look great across many user agents. You just need to have the right code to bypass and fix blunders and errors built into modern web browsers today.
Over the years, using old and new web browsers, I have found solutions to nearly all the bugs found online. I have written CSS "hacks", and I have perfected my HTML markup so it looks and runs fast in nearly every web browser ever made. I felt it was time to gather all this knowledge here in one tutorial and share it with the world. Learning from the past, as well as building on the future, will make you a master at just about anything. With experience combined with cutting-edge technology, you can challenge the future with confidence. But learning anything takes mentoring and learning from others. It is like working on a car. You have to know the tricks, first, from a master mechanic, right? Technology is no different. Without knowledge of the tricks and tools, you are never going to be a master web developer. Having total knowledge of the latest and greatest web technologies means you have mastered only one layer of the technology. You also must learn the "old" practices, too. Too often new coders skip over lessons learned in the past and so are doomed to repeat them. In the end, learning old and new HTML techniques in parallel means you will come away from this lesson as an "all-knowing", experienced expert in HTML and CSS with solutions most of your peers will have completely missed. You can then climb into greatness, building from what others already mastered for you.
You can use the experienced advice in this one page to help "jumpstart" your career towards being a "great web coder" by simply learning what works in modern HTML5 browsers used today, but also learning what worked in the past. Combined, the two perfect the art of great HTML5 markup. But first you must learn from those who have passed through the gauntlet of web development and who have come out the other side with battle scars and wisdom to show for it. I am here to guide you on that journey.
This web page is about learning HTML5, right? But HTML often is not complete without CSS (Cascading Style Sheets). The two work closely together in delivering many types of Human-readable web pages and online documents. The CSS style sheet system that runs this page is itself a powerful and complete Universal CSS Framework that stands behind the design of most of the HTML elements you will see in this tutorial. My CSS system is unique because it not only "resets" all the elements so they look great across all known browsers, but is designed to support styling and markup used by web browsers the past 20+ years! As such, my CSS system is far superior to say, Bootstrap and its "reboot" sheet, which fails to address even a tiny percentage of past browser issues, or Modernizr which relies on thick-client JavaScript, or SASS which is yet another heavy pre-processing dependency. My simple cut-and-paste system solves all your cross-browser problems without any scripts whatsoever, and is designed to fix all the issues needed to support many types of browsers going back to 1995. Besides, I have been perfecting my CSS system for the past 20 years, long before any of these third party products were even built. My latest version of my Universal CSS package was recently updated for 2021 to not just support older user agents, but support the newest HTML5 web browsers used today. If you would like to use my CSS framework, there is a download section under "Best Practices" for both my HTML5 template and my CSS framework.
I hope you will use my HTML5 Tutorial, as well as my CSS knowledge, to improve your own skills so you can move forward, building on the past, towards greatness as a web developer. Happy coding!
- Mitchell Stokely, 2021
HTML 5 Element List
HTML 5 is almost identical to the much older standards - HTML 3.2 / HTML 4.1 / XHTML 1.0 / XHTML 1.1 - all of which we implemented in websites from the 1990's up until 2008, when the first HTML 5 recommendations were released for review. Now here in 2021, we have fully embraced HTML 5, CSS3, and all the newer changes coming on the horizon that advance better website technologies. However, the basic design of HTML 5 is the same as old HTML. There really is nothing truly cutting edge. The same goes for ECMAScript 6 and later. Its the same basic server-client model, same basic HTML and JavaScript parsers, same DOM, same single threaded browsers, and the same basic client-server model of information delivery. In addition, the past 20+ years have left a trail of older web technology and web pages that still run perfectly well and makes companies billions of dollars every year! But many older browsers remain behind that do not support HTML 5, or which only partially support it. Without careful HTML design, you risk locking out millions of viewers from your website. As the HTML 5's new "Living Standard" slowly evolves, it will continue to leave a trail of partial support in modern browsers used today.
Most of the elements in HTML 5 look and work the same as those in say old HTML 4.1 and XHTML, with a few exceptions that are important. That fact has allowed experienced web developers to build on best practices gained from the past in the infancy of the World Wide Web when browser support for HTML and CSS was spotty. Without going into too much detail here, I will simply list below the core HTML 5 elements supported that are universal to most past and present HTML recommendations, and talk about items unique to HTML 5 you should be aware of. I will also list a few HTML5 elements that I do not recommend, either because few modern browsers support them, they rely on heavy JavaScripting to function, or the technology behind them fails.
Along with examples of solid HTML that works in old and new browsers, I have also added a full list of important attributes I recommend for those elements that allow your HTML markup to work at its peak and give browsers, search engines, and screen readers the necessary information they need get the most out of your website and its markup or scripting code. After this HTML 5 elements list, I have added a "Best Practices" section with advice and code examples you should consider that build on 20 years of my personal web development experience. I will always include code in both sections which you can cut-and-paste into your web projects.
Keep in mind, this tutorial is quite a comprehensive list, but not totally exhaustive. It is likely there are details left out on some things you use I do not that are helpful in projects. They may not be that valuable in designing good cross-browser HTML, however. I have added all the newest elements and attributes, even some cutting edge stuff not yet talked about online. So this tutorial is cutting-edge. But the basic idea behind good HTML markup practices is first committing to using a "core" set of HTML and CSS code that works in old and new browsers, as well as solid design principles that are reliable across all web projects and which will stand the test of time. The "test of time" concept is what makes them great. Using the latest and greatest HTML and CSS technologies does not always benefit your projects simply because you leave so many other user's behind when you do. Anything added AFTER good HTML is icing on a cake you should have already carefully baked. JavaScript API's, for example, should always be layered over good HTML practices. They should ONLY be the icing. They can never be the cake or replace good HTML coding practices. Good HTML and CSS code is what works reliably in many browsers with few changes over years and years, as scripts and API's come and go. When JavaScript API's and frameworks are stripped away, or die from disuse over time (which nearly all will do), remember that after the smoke clears, good content written in good 'ol reliable HTML will always remain behind as it has been for almost 30 years on the Internet, now. Remember that fact, Luke, and the "HTML Force" will be with you!
The 'a' element defines a hypertext link or hyperlink, which contains a URI/URL location on the Internet you go to when the anchor element is clicked.
The 'id' attribute value must be unique for each element id in the current web page. It identifies the element for faster script access and allows you to apply a CSS style with high selectivity than most elements and classes. Many people do not use "id", but I recommend you use it on links as it is quite important in uniquely identifying those elements in a page and makes manipulating them in JavaScript very easy. I generally use "id" on structural elements, as well as forms, menu items, and important elements I manipulate in the page.
The 'href' attribute can be a hyperlink URI (http://example.com/), an internal page anchor/bookmark ("#"), blank, or an email address in the format of : "mailto:webmaster@domain.com?subject=mysubject&body=mybody". The latter will then attempt to trigger the users default email "client", if one is installed, and create an email with any attached "subject" or "body" text found in a query string within the link.
Always add a 'title' attributes or "tooltip" to anchor elements so users on rollover know where the link goes or what it does before they click it. A 'title' attribute should always contain a text "description" of the element, not a "label" or alternative text like you see in images. When a user rolls over the element, the title usually describes what the link does. In addition, on rollover, most modern browsers display where the link goes ("href" value) at the lower left corner of the browser so the user knows where they are going before they click it. This is also a good security feature.
The 'target' attribute allows the user to open the page in the same window or a different one when the link is clicked. "_blank" is commonly used to open a new browser window for the link so the user does not use their current page reference. In the old HTML4 days '_self' and names of frameset windows might use various values for 'target', but those are rarely used now.
The 'rel' Attribute: The 'rel' attribute describes the relationship between the current document and a linked document. It really is only used on anchor links, forms, and the 'link' element where it often defines the link type associated with external files. Because its rarely needed in forms, the anchor tag is the only other element where you might find it useful. The "ref" attribute can be a variety of values, but most of the values associated with "rel" attributes are not supported in browsers, are experimental, deprecated, or rarely used. I will not cover the values for "rel" here when using 'link' elements. See that section for more info. Some values like "author", "bookmark", etc. might seem helpful on anchor tags, but are not widely used. Only a few "rel" values are truly helpful, which includes the ones in my code sample above.
"noreferrer", "nofollow", or "noopener": This special set of attribute values is important, especially when linking to external websites via 'target=_blank', as shown in the sample code above. Adding all three attributes does NOT stop the link from working but adds additional hyperlink features. All are optional and can be mixed and matched. Add 'noreferrer' attribute on outgoing links when you don’t want other sites to know that you are linking to them. Adding the noreferrer tag to your links does not directly impact SEO but does have an indirect effect in your link building and promotion efforts by hiding your site from web domains that might be open to giving you traffic back. When you add 'nofollow' to an external link, you basically instruct search engines not to pass any Page Rank from one page to the other. In other words, you tell them to ignore that link for SEO purposes. It informs search engines that the link is commercial in nature, or that it’s a link you don’t endorse. 'noopener' prevents the opening page gaining any kind of access to the original page via a JavaScript function. Your link page and the new page have a parent-child relationships. The new page will have an access to your parent window object via 'window.opener' and it can navigate the linking page to a different URL using window.opener.location so can be security risk. This stops that risk. In all cases above, the links still function, they just don't pass any information beyond a plain hyperlink function. Note: The "rel" attribute is not supported by any Internet Explorer browser.
The 'accesskey' attribute allows users to avoid using their mouse when clicking a link and instead use a special keyboard hot key combination (alt+a, or alt+shift+a, or apple key+a, etc.) to select the link on the page and then hit 'return' to open it. In the past, this was safe to do because all our users were on desktops. With mobile and other devices, you risk triggering unknown features on the device using the "accesskey" attribute, or they simply do not work. Because this feature could trigger other events on various devices or mobile phones, or may have limited browser support, I do not recommend you assign your links an access key.
The 'tabindex' attribute is optional and allows users to tab through and select ordered lists of anchors or form controls with tabindex index values in specific orders. It is mostly an accessibility standard. If you leave this out, the browser establishes its own tab index, naturally, on interactive elements in your web page. Add "tabindex=0" to include the link in the browsers natural tab order, add "tabindex=-1" to exclude it, or add "tabindex=5" to make it a specific focus in a specific order in the list.
The 'alt' attribute is not supported in anchors in XHTML and rarely in HTML 5. So avoid using it in anchor elements. In some browsers it can work as a placeholder for a link when non-anchors are used as hyperlinks. An example would be a click-able div with an 'href' that has some content that is still downloading. Years ago we did use this attribute on links to provide alternate content for links. But today, avoid it.
ARIA Attributes on Hyperlinks: We do not add ARIA role="link" as an attribute to anchors to assist screen readers in identifying it as a hyperlink as it is self-describing. The anchor 'a' element tells most screen readers it is a hyperlink by default. Only add the link role to a non-anchor used as a link. It's ok to add a 'aria-label' here to tell screen readers what the link does, but in most cases a 'title' tooltip attribute will assist in that function.
There is a rich set of "pseudo-class" CSS styles you can now use to change the color and features of links based on user interactions like hover, focus, and other states. The colors you see applied here are defaults I set for anchor elements in my Universal CSS Framework that resets all HTML elements to a common style.
Styling Links with CSS: CSS can be applied to links to color their text, add underlines, rollover colors, and more. By default, you can apply lots of styles and rollover events to links using CSS. But events connected to the rollover or click events is controlled by CSS and "pseudo-classes". An unvisited or new link is underlined and most often blue by default. A visited link is underlined and purple by default, in most browsers. An active link is underlined and red on click. Most often you apply pseudo-classes to control these colors. They should be added in your style sheet in a specific order in CSS so that the various combinations of color changes cascade over previous ones as users interact with your hyperlinks. The order is: ":link", ":visited", ":hover", ":focus", ":active". If you placed ":visited" after ":hover" you could never change the ":hover" color on ":visited" links. There are newer pseudo-classes, but support in newer HTML 5 browsers is spotty and inconsistent. Most of these new ones affect links but also form inputs and other elements: ":disabled", ":checked", ":required", ":valid", ":invalid", ":optional", and ":readonly". Roll over the text example above to see how I have applied these colors. Note: New "privacy" concerns in modern search engines and in HTML 5 now limit the properties web authors are allowed to change on "visited" anchors. So most of these properties and styles are removed and cannot be changed by web authors. Color in text is one you can still safely change. For that reason, the browsers now controls many of the style properties applied to text links for privacy reasons. If you see limitations on how your CSS is applied to HTML 5 anchors, now you know why!
Styling Image Links: If you choose to make an image a link (example: <a href="..."><img src="image.png" /></a>), the most common way to do this is to wrap a link tag around an image. This is superior to adding an "href" attribute to an 'img' tag, or adding CSS background images to elements then making them links. The reason is search engines like to associate the image with the link. Also, pure image links help the blind or people that need to know some visual image carries additional information (see my 'img' section below on how best to decorate images for ARIA and screen readers). If you use backgrounds, you destroy or hide all this valuable information.
In CSS and web pages, when using image links, some strange design bugs can occur in older browsers. But there are simple fixes for them in CSS. One weird bug that haunted developers for years after 2000 was the weird issues that would occur when you wrapped anchor tags around images to create links. Often, browsers would add a strange "blue border" around the image when wrapped by an 'a' element. We got around this by simply adding a "border:0" in our CSS style sheets for anchor images like so: "a img {border:0;}". This usually occurred in IE 1-9, so this bug hung around for a long time. Sometimes image link would "flicker" or move when rolled over. To fix this one, make sure you always set a width and height on your image, or even the anchor wrapper itself. With locked down dimensions and zero borders, the browsers can do any monkey business on image links.
* Additional attributes are available with various levels of browser support. Items without wide historical browser support are not listed here nor recommended unless you are targeting a special subset of browsers or using special JavaScript API that requires it.
<abbr>
abbreviation
Abbreviation
<abbr title="World Health Organization">WHO</abbr>
The WHO was founded in 1948.
My Recommendations:
The 'abbr' element defines an inline abbreviation or acronym and shows a full text translation on rollover.
An abbreviation is text marked with an 'abbr' tag with a title giving the full text translation. Marking abbreviations can give useful information to browsers, translation systems, and search-engines. Note that this 'abbr' tag puts a nice dotted line under the abbreviation in some browsers you can customize in CSS.
<acronym>
acronym
Acronym
<acronym title="World Health Organization">WHO</acronym>
The WHO was founded in 1948.
My Recommendations:
The 'acronym' or inline abbreviation element is deprecated now and was a member of old HTML4. Old IE 4-5 and Mozilla 5 were the main supporting browsers of 'acronym'. Use 'abbr' instead.
<address>
address
Address
<address>
Visit us at:<br />
My Business, Inc.<br />
Box 123<br />
Some City, CA<br />
USA
</address>
Visit us at:
My Business, Inc.
Box 123
Some City, CA
USA
My Recommendations:
The 'address' element defines a piece of block-level text representing the contact information for the author of a web page or online document. But it can be used for any address display in HTML.
The 'address' element is usually displayed in italics and laid out in lines with break elements added for line breaks. You can customize its look-and-feel further with additional elements inside its tag. Address is a block-level element so performs like a 'div'.
Use the 'address' element to list a address online. Search engines and special parsers may read the address data directly and use it in special ways that index location, as well.
<applet>
applet, Java applet
Applet
also see <audio>, <video>, <object>, and <embed>
<applet controls="controls" code="rain.mp3" width="300" height="200">
Your browser does not support the applet tag.
</applet>
My Recommendations:
The 'applet' element was used to display a multimedia file (primarily Java applets) in a web page. This element has been deprecated. Use the 'video', 'audio', 'object', or 'embed' elements instead.
As usual, always include an 'id' and a 'title' on these click-able multimedia objects.
The 'applet' element became a popular alternative to Microsoft's 'object' element for ActiveX and the 'embed' element built by Netscape. It has been around since the 1990's, so was once a very popular element used to support Java objects in web pages. The browser will interpret the media player required based on the file extension and the 'type' attribute in the 'source' element and attempt to load a player to display it. However, because Java applets are rarely used and remain a security risk in browsers, there really is no reason to use 'applet'. Most of the "other" media once supported by 'applet' were driven by deprecated players that have been discontinued. However, you may find older websites that still use 'applet'. If you are targeting still using Java applets in older browsers, it might be useful to still use 'applet' in special limited cases.
History: Prior to 2010 and the advent of HTML 5, the 'applet', 'embed', and 'object' elements were used to display a wide range of multimedia objects in HTML including: JavaScript Applets, Adobe Flash, plug-ins, ActiveX objects (in Internet Explorer only), images, video, audio, Windows documents, and older 3rd party applications in the browser. Keep in mind that for over a decade, web browsers viewed millions of multimedia objects this way. Many of these media types are now discontinued, no longer supported, or are security risks in the browser. For those reasons and more, these multimedia elements are generally not supported in HTML 5. With the newer smart phone technology that came online after 2007, having limited CPU capacity and security concerns, it was decided that most of this new media would not be supported on mobile devices. And so tags like the 'applet' and 'embed' elements quickly died, even on desktop. Legacy websites today that still contain unique custom multimedia objects like this now must be removed or replaced with alternatives, as so many of the "players" that once supported rich media like this are no longer around to play them (post-2010). Flash for example, was recently discontinued just a few years ago, but was once hugely popular as a choice for highly interactive solution in thousands of websites. (I actually used to write Adobe Flash animations and applications in old Actionscipt.) This change has not stopped video, audio, or other applications from being embedded in web pages, however. HTML 5 has simply come up with alternative elements. Keep that in mind. So, if you see these old elements and are deciding to remove them or update them, use the newer HTML 5 elements available ('video' and 'audio', for example).
As mentioned, do NOT use the 'applet' element as it is fully deprecated now and replaced by the <audio>, <video>, <object>, and <embed> elements.
<area>
area, map area
Area
see <map>
My Recommendations:
The 'area' element defines an area inside an image map element. See the <map> element for a full description.
<article>
article
Article
See also <header>, <nav>, <main>, <footer>, <section>, and <aside>
<article id="article1" aria-label="Article1">Article 1</article>
<article id="article2" aria-label="Article2">Article 2</article>
Header
Main
Section Article 1Article 2
Footer
* A typical web page structure is shown above.
My Recommendations:
The 'article' element is new in HTML 5 and defines an independent, self-contained piece of page content. Typically, this is a structural element and is nested inside a 'main' and 'section' element. It is used for defining a larger block-level area of content in a web page. Unlike its twin, 'section' which can contain anything, 'article' usually contains text content. In HTML 5, the 'article' is part of a set of new structural page elements that define the overall layout of most HTML 5 website pages designed today (<header>, <main>, and <footer>, etc.).
The New HTML 5 Structural Elements include: header, nav, main, footer, section, article, and aside.
ARIA: The 'article' element is a top-level, "self-describing" structure recognized by most modern screen readers without additional assistance. However, in the case of 'article' it is recommended you add an optional 'aria-label' of "Article {some label}" for each one added.
Structure: Use article for wrapping around large textual blocks, blog posts, or smaller independent content areas within other parts of a page. 'article' can also be a parent for one or more 'section' elements. Articles can also be nested inside each other. Because 'article' is a universal structural element of modern HTML 5 pages now, you will see 'article' appear in grids, flex boxes, and other CSS design and formatting structures. Nested articles can be floated side-by-side, hidden, or shown in many different configurations. Like sections, they can have headings and other page structures that a blog post or a content 'div' might have. Typically, articles are contained with a single 'section' element. But, some designers like to use one 'article' element per page and stack multiple sections inside them. I rarely use 'article' elements unless I am designing a news website or a corporate blog. I prefer the use of the 'section' element as a replacement for 'article' as it feels more semantic and generic for the majority of web pages built today. Note: Like all the other structural HTML 5 elements, placement of multiple articles inside 'main' or 'section' will add important semantic structure to your pages in HTML. Know that 'article' does NOT come with a specific style. You must add that feature using CSS.
See the <main> element section for more details about this new HTML 5 element.
<aside>
aside
Aside
See also <header>, <nav>, <main>, <footer>, <section>, and <article>
<aside id="complementary" role="complementary" aria-label="Aside">Aside</aside>
Header
Main
Section
Footer
* A typical web page structure is shown above.
My Recommendations:
The 'aside' element is new in HTML 5 and defines an independent, self-contained piece of page content. Typically, this is a structural element and is nested inside a 'main' element, as well as alongside a 'section' element. It is used for defining a larger block-level area of content in a web page. In HTML 5, the 'aside' is part of a set of new structural page elements that define the overall layout of most HTML 5 website pages designed today (<header>, <main>, and <footer>, etc.).
The New HTML 5 Structural Elements include: header, nav, main, footer, section, article, and aside.
ARIA: The 'aside' element is a top-level, "self-describing" structure recognized by most modern screen readers without additional assistance. However, in the case of 'aside' it is recommended you add an ARIA role of "complementary" and an optional 'aria-label' of "Aside".
Structure: Use 'aside' for a small side banner, image, content, or navigational structure in your page. Because 'aside' is a universal structural element of modern HTML 5 pages now, you will see 'aside' appear in grids, flex boxes, and other CSS design and formatting structures. Like sections, they can have headings and other page structures that a blog post or a content 'div' might have. Typically, 'aside' floats beside a 'section' element. I rarely use 'aside' elements unless I am designing a website with advertising or sites that need important supplemental info on the side walls. Note: Like all the other structural HTML 5 elements, placement of multiple 'aside' elements inside 'main' will add important semantic structure to your pages in HTML. But know that 'aside' does NOT float to the left or right of any element naturally. You must add that feature using CSS.
See the <main> element section for more details about this new HTML 5 element.
<audio>
audio
Audio
<figure aria-labelledby="myaudio">
<audio id="audio1" alt="audio: Rain Sounds" controls="controls" preload="metadata" title="An Audio File of Rain Falling" aria-label="Rain Sounds">
<source src="rain.ogg" type="audio/ogg" />
<source src="rain.mp3" type="audio/mpeg" />
<p><strong>Sorry, this audio file will not play. Your browser does not support the audio element or the file formats available.</strong></p>
</audio>
<figcaption id="myaudio">"Rain Sounds" [<a href="http://creativecommons.org/licenses/by-sa/3.0" target="_blank" rel="noreferrer nofollow noopener">CC BY-SA 3.0</a>] , via <a href="https://commons.wikimedia.org/wiki/" target="_blank" rel="noreferrer nofollow noopener">Wikimedia Commons</a></figcaption>
</figure>
(If your browser supports the audio element above you should see an audio control and hear a rain sound when playing.)
My Recommendations:
The 'audio' element is a new HTML 5 tag used to embed sound content in web pages, including music, streams, or sound files. (It replaces the old 'object', 'applet', and 'embed' elements in HTML4).
The audio tag works like the <picture> element with multiple fallback child <source> tags representing alternative audio file sources inside it. The browser will pick the first source file format it can play successfully from a list, or report a text message indicating no file format or audio element support.
As always give your element an 'id' for script control and a 'title' attribute to tell users what the audio control will do.
The 'src' attribute in 'source' elements must point to a valid audio file or the audio controls will not play a file when pressed.
The 'alt' attribute in 'audio' elements helps screen readers and the blind identify the meaning of audio elements, just like images provide. For that reason, always add the "alt" attribute.
The 'width' and 'height' attributes can be set on the element, as well as in CSS. I recommend you avoid the attribute versions and set dimensions in CSS so you have more flexibility and can use 'em' text units or percentages which allow the audio to fit various dimensions. Note: The audio element is a "replaced" inline element controlled by the operating system. I recommend you give it a "display:block" CSS value so you can at least control its borders, margins, and background features.
The controls="controls" attribute specifies that audio controls should be displayed. By default it generally includes play, pause, volume, time, and playtime position controls. Note: There is a "controlless" version of the audio element, but I do not recommend you play audio without giving a user controls.
The 'preload' attribute specifies a hint to the browser as to when the audio file should be loaded. "auto" generally means to load the complete file as the page loads, but some browsers may ignore this feature. "none" would mean to not load the audio file as the page loads and would load the file only when the play button is clicked. "metadata" would only load the metadata for the audio file as the page loads. The default value is different for each browser. The spec advises it to be set to "metadata", so I recommend that value be set so you don't slow down the display of your web page with large audio file downloads in the background. Note: These types of files are not true streams and are likely "on-demand" download streams buffered and negotiated with the server over HTTP, unlike a true audio streaming service and audio player would negotiate over a streaming protocol like udp/rdp, etc. So, keep that in mind if your page has lots of audio files on your server!
There are other 'audio' attributes you can apply, like 'loop', 'muted', 'crossorigin', and 'autoplay' you can use for more control of your audio, though I do not recommend them.
There are numerous scripted methods and events you can apply to your audio element along with scripts to fully control and customize your audio player.
Beneath the audio control sample above I have added some small text with more info about the audio file as well as licensing information. This is generally good practice so users understand the source of the file and have access to more textual information about its licensing. Notice I wrapped a Figure with Figcaption around the audio element, so its text description becomes its caption. This allows it to work with captions as a 'picture' or 'img' element would do.
CSS styling of the audio control is difficult if not impossible, so realize there is limited support for designing audio controls.
Many modern mobile phone browsers as well as Internet Explorer 8 and earlier browsers on the desktop do not support the 'audio' element! These older agents prefer the 'embed' (non-IE) or 'object'(IE only) elements, instead. So, keep in mind the limited support many modern browsers may have for the audio control and its many features.
I recommend use of the new HTML 5 'audio' element, but with the understanding many older browsers will not support it. Be prepared to offer 'embed' and 'object' alternatives for wider support in older agents. (see my "best practices" section for how to do this). If you need more universal support for audio controls across devices and browsers consider building a JavaScript-based audio control.
<b>
bold, bolder
Bold
This is some <b>bold</b> text.
This is some bold text.
My Recommendations:
The 'b' element defines a piece of "bold" text.
In my style sheets I always re-define the 'b' element as "bolder", not "bold", in font-weight value as you might have bold text that now must stand out and be bolder from the other text. So its a relative value.
Do not use the 'b' element, but use 'strong' instead! Because 'b' is a purely visual element, use of its semantically important brother, <strong>, is recommended instead of 'b'. You can also use CSS styling and 'font-weight:bolder' on spans of text segments if you just want a design change, but its not as search engine friendly as 'strong'.
<base>
base url
Base URL
<base href="/" target="_self" />
My Recommendations:
The 'base' element specifies the "base URL" to use for all relative URL's or paths in your web page. The 'base' element always appears in the 'head' of your HTML page. It has been a part of the early HTML recommendations, though rarely used.
Why Use the 'base' Element? The 'base' element resides in the <head> section of your HTML page and has no design function. It mainly affects links inside your web page but affects any element with a relative web path, as well. It tells the browser what the starting web root is under your website domain for all such "relative" URL's. If your HTML page has no 'base' element (which most do not), the browser defaults to the "base" URL or website domain itself. That means by default, all relative URL's resolve relative to the web root, or "https://yourwebsite.com/". You could set it to "/" if you have a site that might include an unknown number of domains pointing to the same website and web root. If you use 'base', also know it must come after your meta tags in the 'head' of your web page, but BEFORE all 'link', 'style', 'script', or other elements that reference relative URL paths.
Most of the time you do not need the 'base' element, as relative URL's in your website (like paths to images, video, CSS files, or links) always use the path starting from the web domain and "web root" and resolve paths to files ok without any help. The browser will fill in the rest, which is usually done by adding the website's fully qualified domain plus "/" in the file path. Example: A relative URL in a web page to an internal page in a subfolder under it, like "myfolder/mypage.html", would work ok as is without any help. If that same page was off the web root it would also work the same as "/myfolder/mypage.html" (absolute URL) or "http://mywebsite.com/myfolder/mypage.html" (fully-qualified URL). The browser and server resolve it just fine. You could also let the server dynamically send you the right folder path with the image, link, etc. Most servers do that quite easily. Finally, you could simply ignore the domain part of the URL and use pure relative paths, like this "../myfolder/mypage.html", which says that a page in a folder next to "mypage" goes up to its parent folder then down into "myfolder" to find the page, ignoring the domain path. Browsers all do this naturally and have for over 20 years. In all of these cases above, you do not need the 'base' element.
Where 'base' elements might help is specialized cases where you have multiple web applications housed under separate folders, but using the same website and domain, like so:
"http://mywebsite.com/application1" - Your "base" URL for pages under this path would become "/application1/".
"http://mywebsite.com/application2" - Your "base" URL for pages under this path would become "/application2/".
Each of the "applications" above could be a folder path or a "virtual" path inside a common website but which need to use separate applications and application paths underneath "http://mywebsite.com/". By setting the base path to "/application1/" for all HTML pages inside the first path, you can then let all your relative URL's and links continue to use the same paths they always use, but let the browser inject the new application "base" path or root path into them. Example: The relative URL "myfolder/mypage.html" with the new 'base' path above added to the page would now resolve to "/application1/myfolder/mypage.html" (same as "http://mywebsite.com/application1/myfolder/mypage.html"). The idea here is to allow complex web applications with multiple subsections continue to use relative paths that do not change, but where only the top application path changes. Otherwise, you would have to include the new application path in every single URL in every application and page. It saves a developer the hassle of keeping some URL's inside different applications. However, in these rare cases, we still never needed "base", as we simply controlled paths on the server. It is MUCH easier to do this server side. For example, if every "user" or "product" or "administrator" needed their own path or web page based on an "id" in the path, we simply injected that path dynamically on the server in every web page and element for thousands of items or users like so: "/{server generated path goes here}/myfolder/mypage.html". That is much easier to do using server-side logic and more manageable that a hard-coded "base" value. So 'base' is again redundant.
One "weird" use for 'base' URL's has been recent JavaScript API's like Google's Angular. These developers felt they needed this antiquated 'base' URL system to help their own pathing systems resolve. That is because they use an artificial "routing" system in JavaScript that builds off static URL's in the 'base' element, not the default web root of most website. Instead of building static folders to support testing or other configurations, or managing those paths in variables inside JavaScript, they like to use the artificial "base" paths that have no basis in real paths like most websites use. They also could have processed custom URL's in memory like a server does for paths, but rejected that idea, too, apparently. They also want to segregate their single page application this way from 3rd party applications that might conflict with theirs, or have the power to stick their pathing system into others without knowing the conflicts involved. They rely heavily on the static "base URL trick", which is yet another dependency. They also build a product that is heavily dependent on an internal, open source, UNIX-based "relative" pathing system using a "." syntax that is not web-friendly and does not always fit with how relative web paths work or resolve in websites. By relying on artificial paths and the 'base' path like this means they must rely on a static HTML path dependency that yet must fit into their own dynamic one. It is just bad design!
'base' Element Attributes: The only two attributes needed for 'base' are the "href" or URL static path and/or a "target" window. By default, you should set "href" set to "/" then customize it from there. his at least allows your paths to avoid static URL domain paths and so remain domain agnostic. If you do use 'base', make sure all your images, CSS files, JavaScript files, links, and other relative paths all resolve to that one web root path! The "target" attribute in 'base' is rarely used and is by default "_self", or posts the page into the existing one. You can use "_blank" to force all links with relative URL's to pop up into a new window or tab. The other values for "target" were mainly for frames, which are no longer used.
Do Not Use the 'base' Element!: I cannot recommend use of this element as it adds too many dependencies to what should be a simple relative path system that works fine as is by default in all browsers and web server systems. Using the natural URL system means you have the freedom to use absolute paths from your web root or relative paths from within any folder in your website to any other file independent of the root. No extra work needed. If you find you do use multiple applications, try using the server to inject those application root paths dynamically (as described above). Most virtual web applications on web server under a given domain do this pathing for you, naturally. Otherwise, if you feel you need to use multiple applications in your website, try creating a subdomain for each major application under your domain instead of manipulating paths using 'base'. Example: "http://mysubdomain.mywebsite.com/". There are so many better solutions to solving pathing problems than using the 'base' element.
The 'basefont' element was used to specify font styles for all elements under the 'body' element in a web page. It would be placed in the <head> section of a web page. 'basefont' has been around since the 1990's and early days of HTML and was still a part of HTML4. However, this element has been deprecated in HTML 5, as it was a design element only.
Do not use the 'basefont' element! Instead, use CSS style sheets to set default font styles on the 'body' element of your web pages. Those font styles then cascade down from 'body' to all other elements, just like 'basefont' used to do. Font styles are thus inherited by all your inline and text style inheriting elements.
<bdi>
bidirectional isolate
Bidirectional Isolate
The user's score - <bdi>إيان</bdi> : 46
The user's score - إيان : 46
My Recommendations:
The 'bdi' element isolates a part of "directional text" (right-to-left or left-to-right) that might be formatted in a different direction from other text outside it. Unlike its HTML4 cousin <bdo>, this element is new in HTML 5, but sadly has no support in any Internet Explorer or in a few others. So, I do not recommend its use. Use <bdo> instead.
If you did not wrap the Arabic above, when you start typing certain text after it, the text might be flipped to the opposite side of the text. If such text is injected into an element without the 'bdi' element, the browser's algorithm to set direction could flip text around the Arabic section above.
The sibling element 'bdo' works the same but reverses the text direction.
Avoid using 'bdi', as it has no support in IE 1-11. Use its cousin, <bdo> instead.
<bdo>
bidirectional override
Bidirectional Override Text
Left-to-right - One type of text: <bdo dir="ltr">إيان</bdo>
Left-to-right - One type of text: <bdo dir="ltr">John Smith</bdo>
Right-to-left - One type of text: <bdo dir="rtl">إيان</bdo>
Right-to-left - One type of text: <bdo dir="rtl">John Smith</bdo>
Left-to-right - Mixed types of text: <bdo dir="ltr">John Smith and إيان</bdo>
Right-to-left - Mixed types of text: <bdo dir="rtl">John Smith and إيان</bdo>
Left-to-right - One type of text: إيان
Left-to-right - One type of text: John Smith
Right-to-left - One type of text: إيان
Right-to-left - One type of text: John Smith
Left-to-right - Mixed types of text: John Smith and إيان
Right-to-left - Mixed types of text: John Smith and إيان
My Recommendations:
The 'bdo' element isolates a part of "directional text" (right-to-left or left-to-right) that might be formatted in a different direction from other text outside it and reverses its direction. This element has been in older HTML recommendations for years, so is supported widely across old and new browsers (unlike its cousin, <bdi>).
The 'dir' attribute sets the new direction of the text. If 'dir=rtl', English text would change direction. Arabic or Hebrew text would not change as they are right-to-left in direction by default.
The CSS property 'unicode-bidi' determines how text and Unicode languages change direction. Review those settings in more detail to combine mixed Unicode languages and text in this element and others.
The sibling element 'bdi' works the same as 'bdo' but isolates the text direction without changing its current text direction.
WARNING: Do not change a native Unicode language's native text direction unless you have a specific purpose in doing so.
<big>
big, bigger
Big
This is some <big>big</big> text.
This is some big text.
My Recommendations:
The 'big' element was used to show larger text in an inline block of text.
Do not use the 'big' element as it is deprecated now and was a member of old HTML4. Use CSS and 'font-size:larger' on spans of text instead, like this (you would move the inline style below to a CSS class):
This is some <span style="font-size:larger;">larger</span> text.
This is some larger text.
<blink>
blink
Blink
<blink style="color:green;">This is some text that should flash on and off, if supported</blink>
My Recommendations:
The 'blink' element is deprecated now and was a non-standard member of old HTML4. 'blink' used to create a section of inline text which flashed, on and off, in the browser.
<blockquote>
blockquote, long quotation
Blockquote
I have decided to leave a quote below:
<blockquote cite="https://www.fi.edu/benjamin-franklin/famous-quotes">Well done is better than well said.<br />— Benjamin Franklin</blockquote>
I have decided to leave a quote below:
Well done is better than well said. — Benjamin Franklin
My Recommendations:
The 'blockquote' element defines a piece of block-level text representing a piece of quoted text from another source. It is usually indented as a block-level element. Note that it does not add quotations like 'q' does.
The 'cite' attribute is used to define an online source for the quoted text and its web page.
Always use 'blockquote' for larger separate blocks of text and 'q' for smaller inline quoted text.
<br>
break, line-break
Break
This is an example of a line-break...<br /> ...I am now on a new line!
This is an example of a line-break... ...I am now on a new line!
My Recommendations:
The 'br' element defines a short line-break between two piece of content. The break element can be used to break inline or block-level elements, even add extra lines as space between two items.
The right way to type a 'br' element is <br /> which has a space then forward slash to end the element correctly. This version is XML-compliant and ends the tag correctly. Do NOT use these forms: <br>, <br/> or <br></br>. The form, <br />, is 100% HTML 5/XML/XHTML/XHTML 5 compatible, while the other forms are not.
<button>
button
Button
see <form> for more details using <button> in forms
The 'button' element defines a click-able button in the web page. The button element can be used to submit form data, reset form data, or be a plain, click-able button that does nothing until you attach a custom scripted event to it. The three types of buttons using the 'type' attribute are: "submit", "reset", and "button".
The 'button' element by default works as a "submit" button in a form. If you leave off the "type" attribute, it remains a "submit" type by default. So, always explicitly set its type to avoid problems. When pressed it will post all of the form field's data as "name:value" pairs back to a server for processing, as well as the "name:value" pair of the button. This is important so you know "who" or "what" submitted your data! 'button' as "submit" types work just like an 'input' submit button "type". Data is posted to the server in a GET URL query string by default, or via a POST HTTP Host Header if the button or parent form have applied a POST type of form 'method'. The "reset" button type clears all form fields in the form associated with the button. The plain "button" type button can be used for processing many types of pressed button events using JavaScript methods (like "onClick="). But the "button" type button does nothing by default. Its just an empty button. It will not submit form data to the server or process any page events until you add JavaScript events to it.
The 'type' attribute on buttons decides what type of button it is. As mentioned, the three types are "submit", "reset", and "button". If the 'type' is left off, it defaults to the "submit" button type and on click will submit all form field data. So be careful and always explicitly define a 'type' attribute on your button.
The button 'id' is optional and must have a unique value. It is helpful when accessing and manipulating a unique button in your web page using JavaScript. I often match change both 'id' and 'name' attributes to use the same matching values on all my buttons so I can keep track of which button was clicked using a single identifiable button in both my client-side scripts and on the web server (see 'name' below). As a best practice ALWAYS use both 'id' and 'name' attributes just in case you need them.
As mentioned above, the 'name' attribute is as important as the 'id' on buttons and is part of the "name-value" set for the "submit" button that is sent to the server on click. It helps you know what button was pressed when processing server-side data. If you use cryptic names, other developers do not know what the button does and have to dig around for it. Use simple names like "loginbutton" or something like that for the button name. It should also always be used with a unique name, like the 'id', unless part of a collection of buttons with the same shared name, with each button having unique values. The 'name' attribute is often used to associate the button with a form field of data it submits or identify which button was pressed among many fieldsets on more complex forms. The button 'name' attribute value along with its 'value' attribute value will be submitted to the server as a "name-value" pair along with all other name-value pairs of input controls within a parent form element when the button 'type' is "submit". Note: Some older browsers send just the text inside the button for the value (IE8, for example), so beware! As mentioned, it is critical if you have complex multi-form element pages with lots of buttons where you need to identify on the server which form data was submitted. I often match the 'id' and 'name' with the 'name' value so I can keep track of a single identifiable button in both my client-side scripts and on the web server.
Always wrap a <form> element around your buttons and form fields! This tells the browser your button is associated with that form and will only submit its child input elements to the server if you have multiple forms of input fields to submit in a web page. You can still place the 'button' element outside a form if you give it a 'form' attribute to associate it with a specific form. In that case, it will still submit all input fields inside that specific form when pressed. However, I do not recommend you move any form controls or buttons outside of a parent form, as some older browsers may fail to submit data.
Along with the 'form' element wrapper, always add the 'form' attribute to buttons with the 'name' attribute's value of the parent 'form' element, as mentioned above (example form="myform1"). This associates your button with a specific form of inputs they will submit to the server. Buttons without this 'form' attribute will not know which form to submit, and if you have several in a web page, could submit ALL forms and all form data to the server by mistake.
As mentioned, the "button" type of button does not do anything. It will NOT submit input form fields to the server. As such use it for custom JavaScript events or triggers in your web page. The ideas of how to use "button" type 'buttons' is endless!
formtarget, formaction, formmethod, formnovalidate, and formenctype are only needed if you plan to override the attributes on the parent 'form' element. However, these only work for the default or "submit" button types (see <input> "submit type element, as well). 'formtarget' specifies a keyword that indicates where to display the response that is received after submitting the form, like a new window. 'formaction' is used to add a server URL, and tells the browser where to send the form data. It is an override of the parent form's "action" attribute value, which is the same URL of the current web page if missing on the form. If different buttons need to submit data to different locations on the server for processing use this attribute. 'formmethod' is used to set either GET or POST method types for all form fields it submits. GET is the default. 'formnovalidate' forces no validation on all form field inputs on submit, again overriding the 'form' elements settings for the inputs. 'formenctype' applies only when you are using the POST method, submitting files using the 'input' element "file" type, and wanting to override the default form settings. Always use the XML-friendly version of these attributes. Example: "formnovalidate=formnovalidate". In most cases you do not need to set these attributes unless you have multiple submit buttons and need to override the parent form values for each one using buttons inside the form.
As with all my interactive HTML elements, I encourage you to ALWAYS add a 'title' attribute to your buttons and an ARIA label. You do not need ARIA roles on buttons as they are self-describing. Adding titles and label attributes on buttons allows a user to know its function, its properties, and the type of data it submits. If its a button that is not a "submit" type, its important to have a title telling a user what it does before they press it. Otherwise, they have no idea beyond vague visual queues on the web page.
Adding an accesskey attribute to a button with a letter representing the keyboard text to trigger it is optional and for accessibility. 'accesskey' values often do not work, so a better solution is to add "tabindex=0" to force the button into indexed list of tabbed form field items. Often buttons are added by the browser by default. A "tabindex=0" value forces it into the tab list then allows the browser to sort all "0" tabbed items naturally. Most browsers now support ENTER/RETURN key submissions. This means that when a user presses ENTER on their keyboard, the browser will locate the FIRST "submit" button type in the web page and press it, submitting the form data associated with it and its parent form wit all its associated form fields.
How to Enable Enter/Return Key Submission: Often by default in modern browsers pressing the "RETURN" or "ENTER" key on a keyboard presses the form's "submit" button on a web page and submits the data. It is a fast way to have users submit data quickly. This natural "ENTER" keyboard button submission feature has been a feature of web browsers for decades! Many kids today design elaborate JavaScript rules to achieve this, but it's not necessary as its built into all form fields if you follow a few simple rules. To make sure this feature works, an input field or button inside the 'form' element must have focus, be set with the "autofocus" attribute, or be the first button of many listed in the form and be a part of the tabindex list created by the browser. In most cases all this is true and "ENTER" keypresses work fine. To verify this, the user should be able to "tab" into the form and be the first button reaching focus after all prior inputs have been tabbed through. You can also force them there by adding "autofocus=autofocus" but only if the web page does NOT require previous input of data first. Finally, as a last resort, you can add JavaScript to capture keyboard events. But using this simple HTML trick above that is not needed. WARNING: In rare cases where a web page has heavy user access, this ENTER key submission feature makes using your submission button faster and easier, but allow users to press "ENTER" before the page and its data is fulling loaded! If your web page or form field page isn't loaded by the time they press "enter", bad data or no data can be sent to the server (this has happened to me with time clock stamp web pages where impatient users press the key without waiting for the page to load....causing missing time stamp data on the server). In those rare cases, be careful and add "required" to a form field to make sure its manually filled out prior to submission, or consider capturing the "ENTER" key press event with scripts until the web page is fully loaded! That is one rare case where JavaScript does help.
As mentioned above, add "tabindex=0" to all your buttons to make sure they are included in the browser's default tabindex listing. I recommend you always add "tabindex=0" to a 'button' element as it adds it to the global tab index list created by the browser for the web page. Add "tabindex=-1" to "disabled" buttons so users do not tab into them (Note: You can remove buttons and all other non-interactive elements in the page using "tabindex=-1"). You can also set specific tabindex values and create your own custom tab order. This is frequently done in form fields a user fills out in a specific order. If you have a specific need to include your button in a custom order of form fields and other buttons, again, add a specific unique tab order number to control what users fill out prior to submission. Setting "tabindex=1", for example, would start a user at a specific control and works like 'autofocus', for example. It controls where a user goes to in a page, initially. But realize, the "ENTER" key will still trigger the submission. Adding "required" or "validation" attributes and scripts to stop submission until fields have valid data is also important.
You can also add "autofocus=autofocus" to enable a users browser to focus and select the button control after the page loads. The 'autofocus" attribute takes the user immediately to a specific item regardless of tabindex.
"disabled=disabled" turns off the ability for a button to submit data or function. All button types would be affected. Note: In CSS I generally gray out disabled buttons and change the cursor rollover type back to the default (non-pointer or hand type).
Can I Create Image Buttons? Yes! Because 'button' types unlike 'input' buttons can have HTML and image elements between their tags, you can actually style buttons to hold all kinds of images. You can also add a CSS image background to buttons to simulate an image button.
ARIA: Notice in the examples above I have added ARIA and 'aria-label' attributes. In most cases screen readers will identify your buttons without assistance so the ARIA 'role' attribute is optional. Many screen readers will know its a generic button, but not know what it does or represents. For 'button' elements without a "type" added, I recommend you do add ARIA "role=button" to tell screen readers it is an active "submit" button. But, the 'aria-label' is also important in helping identify the element's purpose and should always be used, regardless.
Styling a Button with CSS: Styling the 'button' element, cross-browser, is incredibly challenging in terms of designing buttons that look exactly the same between browsers, old and new. This is because buttons are "replaced" elements whose design and features are often controlled by the computer's OS. In addition, most browsers "default" to a specific button design that is often raised or gray in color, matching say a Windows or Mac dialog button. Below is CSS style for a simple, white, raised button style that works well in many types of browsers and which has been thoroughly tested. Just paste this CSS style code below in your web page's style sheet and watch all your button elements magically change design!
Should I use 'button' or 'input' type submit buttons? Every form field should have a "submit" type of input or button, whether its a button of type "submit" or an input of type "submit". This is a general rule to follow when deciding whether to add the 'button' element to your page or not. Because many legacy browsers, like IE, are not consistent in how 'button' types submit "name-value" pairs versus the text inside, some people avoid 'button' elements and use 'input' types for form submission. Use buttons if you need to pass "name-value" pairs, otherwise use 'input' buttons. 'input' "submit" types seem to be more common. If you do use the 'button' element, I would make sure all my buttons have the above attribute values in case an older browser is targeted.
Any Browser Issues? There are no really huge cross-browser issues, other that the minor data-submission Internet Explorer issues described above. Those are minor. 'button' has been around as an HTML element since the birth of most browsers, and has really not changed in HTML 5, so is totally safe to use.
The 'caption' element is used inside a table only, and appears as a "title" at the top of your table grid. By default, a table caption will be center-aligned above a table. The purpose of the caption is to semantically label your tables and tell users and screen readers the subject or meaning of the tabular data.
The 'caption-side' CSS style property is used to control where the caption should appear on the table and can be "top" (default) or "bottom". Note: IE 7 and older do not support this style property.
<center>
center
Center
<center>My Text Is Centered</center>
My Text Is Centered
My Recommendations:
The 'center' element was an old way to center text in HTML4 (pre-2001) but is deprecated now. It still may work in newer browsers, but DO NOT USE IT! Use CSS instead to control centering of text by placing the style on the block-level element holding the text. Example:
<div style="text-align:center;width:100%;">Center My Text Using CSS</div>
My Text is Centered Using CSS
<canvas>
canvas
Canvas
also see <svg>
<canvas id="canvas1" style="background-color:#ccc;border:1px solid #666;" width="100" height="100">
Sorry, your browser does not support the new HTML 5 canvas object.
</canvas>
<script type="text/javascript">
var myCanvas = document.getElementById('canvas1');
var myContext = myCanvas.getContext('2d');
// draw colored boxes
myContext.fillStyle = 'green';
myContext.fillRect(10, 10, 20, 20);// x-y coordinates, x-y art dimensions
myContext.fillStyle = 'red';
myContext.fillRect(70, 10, 20, 20);
myContext.fillStyle = 'blue';
myContext.fillRect(10, 70, 20, 20);
myContext.fillStyle = 'yellow';
myContext.fillRect(70, 70, 20, 20);
// draw a colored circle
myContext.beginPath();
myContext.globalAlpha = 0.6;// allows the circle to be semi-transparent
myContext.arc(50, 50, 40, 0, 2 * Math.PI);// x-y coordinates, radius, start angle , end angle
myContext.fillStyle = '#fff';
myContext.fill();
myContext.strokeStyle = '#aaa';
myContext.stroke();
</script>
(The JavaScript used above in rendering this image is from the standard "Canvas Scripting API")
My Recommendations:
The 'canvas' element is new to HTML 5 and allows for dynamic, scriptable rendering of 2D shapes and bitmap images. The 'canvas' element has no drawing abilities of its own and is only a container for graphics (requires JavaScript using either the Canvas Scripting API or the WebGL API).
The 'width' and 'height' attributes control the basic canvas element dimensions as well as the drawing surface. You can use CSS to control the element's size but NOT its drawing surface. Using the canvas attributes, you control both. So my recommendation is to use the 'width' and 'height' canvas attributes. Note: The default dimensions of the element and drawing surface is 300 pixels wide by 150 pixels high.
SVG uses vectors to draw art in the browser window, while canvas uses rasters (bitmaps). This means that once a canvas is drawn it is forgotten by the graphics card and cannot be re-rendered, unlike SVG which has vectors that can change and be regenerated by the browser. Once a canvas is drawn and the bitmap is rendered, if it changes, it must be redrawn again with a new graphics object instance. It is not as efficient. So canvas is not recommended for dynamic screen rendering of artwork in HTML 5.
WARNING: The canvas object is heavily dependent on scripting, so is not a fully independent HTML feature. If scripting is turned off or unavailable in the user agent, the element is not rendered! Note: Internet Explorer 8 and older do not support the 'canvas' element. In addition, WebGL for high performance canvas rendering is NOT supported in IE 10 or below, Chrome 8 and below, and many other older user agents. There is also limited mobile browser support. For these reasons and more, use caution when supporting canvas imagery in the browser.
<cite>
citation
Citation
<p>The <cite>Pieta</cite> is my favorite work by Michelangelo.</p>
The Pieta is my favorite work by Michelangelo.
My Recommendations:
The 'cite' element defines an inline citation or title of a creative work, book, etc. It is not for citing an author's name, just their work or its title. 'cite' has been around since early HTML in the 1990's and fully supported.
Cited text is usually in italics.
<code>
code, computer code
Code
<code>
<p>Here is my sample paragraph using HTML with the 'code' element</p>
</code>
<p>Here is my sample paragraph using HTML with the 'code' element</p>
My Recommendations:
The 'code' element defines an inline piece of user input text or computer code. It is commonly used with the 'pre' element, to wrap around HTML, CSS, and JavaScript code that is shared online by developers. This element is similar to <var>, <kbd>, and <samp> in that 'code' formats text to represent abstract computer programs, keys, equations, or ideas.
Facts about the 'code' Element: 'code' text is usually in a monospace font by default to differentiate its purpose to the viewer. Also, text spacing and HTML formatting is NOT preserved when using the 'code' element. And all sample HTML must be escaped in order to display markup examples inside the 'code' element. If you do not escape your HTML it will be rendered in the browser instead of showing the markup code. In the example above, the HTML angle brackets (chevrons) are now escaped with special "ampersand-prefixed" escape characters ("<" brackets in HTML replaced with code, like "<") to show you how that is done.
Below, you can see that this element is only used for grouping columns for styling purposes, when CSS can do this much better without this element but using classes.
My Table 'col' Example
header 1
header 2
header 3
body 1
body 2
body 3
footer 1
footer 2
footer 3
My Recommendations:
The 'col' element defines groups of columns within a table and is a child of a 'colgroup' parent element. It has no display or meaning beyond its use in tables in defining groups of columns. The 'col' element typically controls how CSS classes and styles will affect a span of columns throughout the table and is helpful if you need to design CSS styles on specific groups of columns. It is also used to help assistive devices understand how columns of meaningful data are grouped in tables.
The 'span' attribute on each 'col' element determines how many columns in a table horizontally the grouping will hold and the group of columns the CSS styles will affect.
Note: CSS and pseudo-classes (example: td:nth-child(3){...}) on table cells can be used more effectively in setting styles than 'col' and 'colgroup' elements.
Column grouping, meaning, and styling is usually inferred by the table design itself, so 'col' is usually not needed. Example: Using well-named header cells can define what columns mean, and CSS can control designs on multiple columns now. Because CSS can be used to style any type of column grouping, use of 'colgroup' and 'col' is redundant, unless it is needed in more complex tables to confer some special column group meaning to screen readers or other assistive devices. So, 'colgroup' and 'col' is rarely needed. For these reasons, I rarely use 'col' and 'colgroup' elements. But if you have a complex table with lots of subtle data and are concerned about accessibility, these elements may have additional value. (See 'table' element recommendations for adding additional table cell and row designs.)
Below, you can see that this element is only used for grouping columns for styling purposes, when CSS can do this much better without this element but using classes.
My Table 'col' Example
header 1
header 2
header 3
body 1
body 2
body 3
footer 1
footer 2
footer 3
My Recommendations:
The 'colgroup' element specifies a group of one or more columns and is a child of a 'table' parent element. It has no display or meaning beyond its use in tables. The 'colgroup' element wraps around one or more 'col' elements which define groups of table columns. See 'col'.
If there are no child 'col' elements inside a 'colgroup' tag, then it may have a 'span' attribute with a value equal to the total number of columns in the table (example, <colgroup span="4" />). But this column grouping is inferred by the table headers and cells, so is redundant and rarely used.
Note: The 'colgroup' element should not be confused with the 'colspan' attribute on 'td' cells which controls how many cells a single cell should stretch across.
Column grouping, meaning, and styling is usually inferred by the table design itself, so 'col' is usually not needed. Example: Using well-named header cells can define what columns mean, and CSS can control designs on multiple columns now. Because CSS can be used to style any type of column grouping, use of 'colgroup' and 'col' is redundant, unless it is needed in more complex tables to confer some special column group meaning to screen readers or other assistive devices. So, 'colgroup' and 'col' is rarely needed. For these reasons, I rarely use 'col' and 'colgroup' elements. But if you have a complex table with lots of subtle data and are concerned about accessibility, these elements may have additional value. (See 'table' element recommendations for adding additional table cell and row designs.)
<data>
data
Data
<h4>Products List</h4>
<ol>
<li>This is <data value="7345">Product #1</data></li>
<li>This is <data value="1847">Product #2</data></li>
<li>This is <data value="3890">Product #3</data></li>
</ol>
Products List
This is Product #1
This is Product #2
This is Product #3
My Recommendations:
The 'data' element links a piece of text or content with a value attribute inside the tag that is machine-readable. This element is typically used if there is direct web page processing of data by a script in which your web pages need to be in a certain format to serve both a human readable purpose and a computer processing purpose at the same time. As such this element relies on scripts to have any real use. This element does not have any design features.
The 'value' attribute is required and used to assign a numeric or other value to the text wrapped by the 'data' element. In the example above, the 'data' element contains hidden product numbers inside its 'value' attribute associated with each product name.
When might I need this element? One reason to use it would be to manage "name-value" pairs or for sorting of data. Your scripts might have thousands of pieces of HTML data like this they need to sort. Of course, modern JavaScript API's now allow you to download whole data sets and do sorting like this on the fly using more than one extra piece of data.
Use the 'time' element instead if the data is time-based.
Note: Using your web pages for storing data or data processing like this via the 'data' element and a scripted parser is rarely used. Today, there are much better ways to store data (JSON, XML, etc.) and distribute it (using modern JavaScript API's like Angular and React, for example). So if the 'data' element does serve a purpose it would have to be highly specialized. (See the use of the "data-" attribute elsewhere in this page for additional ways of storing data within elements.)
Note: Internet Explorer does not support this element so in most cases it would be ignored. Because it degrades gracefully, however, this is not a block to using the 'data' element.
The 'datalist' element is new in HTML 5 and allows you to assign a select dropdown list to a input "text" box and narrow a user's choice of values. Currently in 2021, few of the new web browsers (and none of the old) consistently support 'datalist'. Therefore, its use is not recommended.
Double-clicking the 'input' text box shows the datalist dropdown. The "suggested" choices provided by the 'datalist' are optional. A user can still override the list provided and type in their own text value into the input box. Note: The 'datalist' also works with other 'input' types, like the "number", "date", "email", and others. If the user has typed text in the box the datalist dropdown will not appear. The datalist is just an additional list of choices, or rather "suggested" values, and is helpful if you need to give users a limited selection of preferred options but also the freedom to add their own. Note: After users submit a choice from the datalist, on future datalists some browsers will show past choices listed before the default list of options. The 'datalist' works best with an 'input' box to receive the value from the 'datalist' when clicked. A "for" attribute is set on the 'input' that matches the datalist's 'id' attribute value. This associates it with the 'datalist'. As mentioned below, because 'datalist has poor browser support, this could fail and leave the user with no way to choose a value or know what options are available. So, its better to just stay with a traditional 'select' dropdown.
The 'list' attribute of the 'input' element must match the 'id' of the 'datalist' element for the two to be connected and the input text box receive the datalist's 'value' attribute text when selected. 'name' is not supported.
The datalist works with number, date, email and other input types.
ARIA: You should always set an "aria-label" to tell screen readers what action to take on this new HTML 5 element. Also, I recommend you add role="listbox", as its not clear that this new feature provides a list. This assists screen readers.
Warning: There is limited browser support for the datalist! Internet Explorer 9 and earlier does not support the 'datalist, nor does the iPhone OS Safari browser released in 2018 or earlier. In addition, in the newest Chrome and Webkit browsers the list floats away from the input element when scrolling. For that reason, I do not recommend use of this new HTML 5 element at this time! Because many browsers do not fully support this element and would not be able to choose any items, it does not degrade gracefully. A better option is to avoid the 'datalist' and just implement a plain 'select' dropdown HTML element with scripts that updates an 'input' element the minute the dropdown choice is selected.
<dd>
description detail
Description Detail
see <dl>
My Recommendations:
The 'dd' element is a piece of block-level text representing a description detail for a matching description term in a description list. The description list is often used to show a page's glossary, lexicon, or description of terms in key-value pairs. See the 'dl' element.
<del>
deleted, strike
Delete
see also <in>
<p>Did you know my favorite color is <del>green</del> <ins>aqua</ins>.</p>
Did you know my favorite color is green aqua?
My Recommendations:
The 'del' element represents a piece of inline text that has been recently deleted. The 'del' tag will draw a line through (strike) any text it wraps around.
The 'del' element is often used to tell a reader of changes to text that are critical in representing the history of an edited document. An inserted text (<ins>) will often follow the deleted one (<del>) to indicate a replacement of new text for the deleted one and to emphasize the change.
<details>
details
Details
also see <summary>
The "details" example is show below. It includes a 'summary' element with a click-able title which reveals additional 'details' element text below.
All content and graphics on this web site are the property of Company ABC.
My Recommendations:
The 'details' element is new interactive element in HTML 5 which shows a text summary and additional hidden text details that the user can see by clicking the summary text. This is usually created by the browser as a piece of title text with a dropdown toggle arrow that reveals hidden content when clicked. This element is typically used as a JavaScript-free toggle widget to disclose additional information if the user chooses to view it.
The details element is comprised of a single click-able <summary> element or title, followed by multiple HTML content elements which will be hidden until the summary text is clicked. The supporting browser controls the hiding and click-able arrow interactive elements. Because the 'details' element is a "list", setting its CSS display to anything other than "display: list-item" will remove the dropdown toggle arrow. You can add your own custom toggle arrow but that is beyond the scope here as browser support would be very sketchy.
The details hidden element is closed by default until clicked. But you can add the open="open" attribute to the 'details' element to show the hidden content by default.
Always add a unique 'id' to the 'details' hidden element so it can be manipulated by scripts.
IE "Fallback" CSS Design: Because IE1-11 doesn't understand the 'details' element or 'summary', its summary and content will both be shown opened, as if they were "clicked". When those elements have been given CSS background colors, all content is then displayed for those older browsers versus being hidden until clicked for more modern browsers. When that happens, the background colors I've applied above are partially shown as a strip of color above the text in the 'summary' element. That is why in my CSS I added the colors shown above. I've added a fallback CSS style of "background-color:#ccccccff" with alpha values at the end to force them to not show any background color in IE. The last two values of "#ccccccff" are CSS3 supported in newer browsers and define transparency alpha values of opaque (ff), which IE 1-7 versions do not understand so default to white when the full content of the details element is shown in these older browsers. WARNING: Changing the 'details' or 'summary' element's "display" or "list-item" properties destroys the ability of newer HTML 5 browsers to render this interactive element correctly! So, avoid most structural style changes and try and just stick with font, borders, and background color changes.
This Element is NOT an ARIA Button: Avoid adding the ARIA "role=button" attribute on this element or its children as it is not designed to be recognized by screen readers as a button. This will only confused screen readers believing they are either submitting data or launching off to some URL, or worse, triggering some unknown page event. Besides, the detail element should be known by modern screen readers that know HTML 5, They also should see the 'summary' and 'details' element text quite easily without any added interactions.
Because this element's interactive design is controlled by the web browser, there is limited CSS styling available for the details element. There are some specialized Chrome features but no wide support for customizing this element. But, I have added some additional styles in the example above to demonstrate what is possible.
The details feature is not supported by Internet Explorer 1-11, and may have limited browser support in some older mobile phone browsers. However, if the feature is not supported, it simply shows the summary and all hidden content beneath it. Because this new HTML5 element degrades gracefully in older browsers, I support its use.
<dfn>
definition
Definition
A Definition as Referenced By a Page Link
<p>Learn more about the <a href="#sun">Sun</a></p>
<p>The <dfn id="sun" title="Our Shining Celestial Body">Sun</dfn> is the name of the local star in our solar system.</p>
The Sun is the name of the local star in our solar system.
A Definition as Abbreviation
<p><dfn><abbr title="HyperText Markup Language - Version 5">HTML 5</abbr></dfn> is the fifth version of the standard markup language used in creating web pages.</p>
HTML 5 is the fifth version of the standard markup language used in creating web pages.
My Recommendations:
The 'dfn' element represents a piece of inline definition text when its term is defined in a paragraph. It represents a piece of text that is going to be defined within a sentence. Use this element if you are explaining a term like in a dictionary definition directly in your text. The definition item is usually styled in plain italics.
The 'title' element can be added to a 'dfn' tag to provide an additional definition text on rollover. See example above.
Add an 'id' attribute so an anchor tag with a "#" and name of your id can be clicked and accessed in a larger page if referencing the definition. See example above.
The 'abbr' element can wrap around a term inside the 'dfn' tag if the text is an abbreviation that needs to be listed in full. See example above.
You can even wrap a 'dfn' tag around a term ('dt') in a "description list" ('dl') if the term is actually represented by a description that is a formal one, like from a dictionary. Example: <dt><dfn>HTML</dfn></dt>. See 'dl'.
<dialog>
dialog, dialog box, modal, pop-up
Dialog
My Custom "Cross-browser Dialog Box"
(Paste the HTML and JavaScript block below into your web page to recreate my new and improved "cross-browser" HTML 5 dialog box)
The 'dialog' element represents a dialog box/modal/window/popup/interactive box that is new in HTML 5 and only appears when an event outside of HTML fires to open it. It is supposed to display a window or box on top of a web page, like a desktop Windows program might do. It is a very simple concept but fails in many browsers. Its is a simple element to implement until you realize it does not work without a lot of styled and scripted scaffolding. Unfortunately, the HTML 5 'dialog' element is JavaScript-dependent, is not supported in many modern HTML 5 browsers, and doesn't work in most of the other browsers but a few of the most recent. That is why I designed a cross-browser version above you can cut-and-paste easily and move on. The code above includes lots of additional styles and attributes, too many to list. But below I will just describe the core features of the main 'dialog' element, not the dependencies. But read below for all the dirty details.
Add the 'id' attribute to this element so it can be accessed by scripts and styled.
The open="open" attribute can be added to the 'dialog' element if you want the dialog popup to appear when the page loads. It is off by default, so the dialog remains hidden until shown. You must add scripts to a button with "onclick=showModal()" to open it. Note: This only works in 'dialog' supporting browsers.
You can add a 'form' element with fields and buttons to a dialog so that when it appears it requires user to give focus to entering data apart from the rest of the page. If you do add a form inside 'dialog', setting the form's method="dialog" attribute will allow the form to automatically close when "submitted". Note: Again, this only works in 'dialog' supporting browsers. I ran this attribute value through the W3C validator and it rejected this value so it must be proprietary to a few user agents and not yet approved or widely adopted into the HTML 5 "living" standards.
Dialog Boxes and their History of Confusion: The idea of the "dialog box" and the fun of stopping a page view and having an interactive box appear is a promise as old as the Web. But it is a history of many failures and half-attempted proprietary technology by people that failed to come together to define the "dialog" concept properly. That is why dialog boxes still FAIL to work today in many browsers! Trust me, I know as I have used all the JavaScripted versions for years and years. The dialog has been around since the birth of the Web! In the old days (c. 2000), the "dialog box" was often confused with many types of scripts and names. For starters, the term "dialog" was often used with the word "modal", which was a reference to the tendency of Windows desktop computers to display software confirmation or login boxes on top of other windows in the monitor. "modal" windows always implied a window that was a child of another. In the browser world, this often made no sense. This just added to the problem of understanding the "language" used to describe each type. All of the various window "types" had been called "dialogs" at one time or another. Example: A "pop-up" was really a call to an "opener" that actually created a true browser window that was a child of the parent browser window. Many people later called this a "modal" or "dialog". But it was not! Neither was the "confirm" or scripted window. The term "dialog" was then more commonly used for all of them over time, though confused with a variety of scripted versions, including the JavaScript "Pop-up" window, the JavaScript "alert" window, the JavaScript "confirm" window, Windows PC dialog windows created by the OS, and finally DHTML windows (which often were just versions of various JavaScripted windows). A last type of window used was the plain HTML "div" that floated over text, but which again was more of a sub-type of newer DHTML "dialogs" that over time tried to abandon popups and other proprietary scripted modal windows. All these were called "dialog", "popup", or "modal" windows at one time or another in the web world. Eventually a few companies popped up bragging about their powerful "modal window" systems when really it was more gobs of JavaScript or plugins we really didn't need. What is bizarre is that nobody could ever give you an accurate explanation of the differences, and still cannot today! Now that you are totally confused, how do you think we felt as developers when we found out that in order to create all these types of windows, each of the older browsers needed different versions or types of JavaScript calls, and that Internet Explorer had its own type of special Windows the others did not have, including proprietary login pop-ups only Windows supported! What made this idea worse, was the fact that custom browser "plugins/players" like Flash and Java had their own version of "dialogs", which we learned later came with security risks! To simply the idea of windows and pop-ups, and knowing some history of "dialogs", my list below should clarify everything so you understand that a "dialog" as used today using the new 'dialog' element uses plain HTML, yet remains JavaScript-dependent. All the others are various types of JavaScripted alerts, windows, and console views that in modern HTML are no longer considered "dialogs" but called something else, thank goodness. But in web developer groups online, the same confusing language will occasionally "popup". You have been warned! Keep in mind this information below is not a definitive list of all the "dialog" types, just the main ones I remember. Many of the later proprietary Mac OS, browser, or ECMAScripted version "modal" calls are not all covered here. But below you can begin to see why I still feel JavaScript is Evil, simply because it has allowed so many kooky events and calls to trigger things in browsers that still irritate users and developers alike.
Types of Things People called "Dialogs"
"Popup" - This really was the only true "popup" window in the Web World, though some called it a "dialog" window in their websites. At least they tried to design it to look like one. It is just an old JavaScript call to open a child window (window.opener) of the parent window. As such, it floated outside the browser itself and appeared more as a true browser tab or page detached from the main user agent. It even came with its own "href" location. The old advertisers online started to use "popups" to trigger adds starting in the late 1990's which led over time to spam and even security concerns. Ad blockers have long ago blocked these. Because of security concerns I believe the old popup model is blocked by default in all the modern browsers, even old IE.
JavaScripted "ShowModalDialog" Box - If you ask me, this is the only thing that was ever a true "Modal" window in the Web World. This was a rarely used but strange little modal box, often used only in IE browsers to create a true modal window that was not a child of a browser window. Its now dead. Unlike "popup", it had poor support and even poorer styling options way back when. At one time is had a very slick looking interface that felt like a true modal window. Like all the others, it was a security risk at worst, a cross-browser headache at best as only Internet Explorer and a few Safari versions supported it.
JavaScripted "alert()" box - We still use these scripted alert boxes for tested API's and for simple browser messages to the user. Some call these popups, modals, or dialogs but they are not. They are simply small scripted "alert boxes" that show a message and a button to close them. They pause all scripts and displays and are great when forcing users to take an action as they completely layer over the whole page. What is even better is they have wide cross-browser support going back to browsers created prior to 2000. But these are not dialogs, though you can make them large enough with text to look like a dialog.
JavaScripted "confirm()" Box - This "confirm box" works the same as the scripted "alert()" box above, except it offers the user two interactive choices using an "Ok" or "Cancel" button option set. Depending on this choice, this allows the scripter to trigger different events based on the user's decision. It is still a great tool few young developers know about. But it is still not a dialog!
DHTML "Modal Windows" - YES!! These were a true "dialog box", though most older Windows Desktop programmers thought these were just repeats of their old Windows modal windows. But they were wrong! There is too much to list here about DHTML dialog boxes, especially since its a dead technology. But in honesty, most of the JavaScript boxes kids use today is just building on top of older DHTML dialog scripts already built 20 years ago that JQuery and others hijacked. DHTML basically tried to redesign scripts to instead layer HTML boxes over other HTML, which is a true dialog box and gets us to where we are today. These HTML scripted boxes included all of the above circus tricks, with just more JavaScript manipulation of HTML and CSS for a richer display. This included custom "Microsoft Extensions for CSS" that allowed IE 6-9 to use CSS "behavior" properties to load scripts and DHTML. Few use this trick anymore as it is a dead technology. This is what our "dialog" element tries to replace today, but sadly still does not, simply because it still relies on scripting. It would be nice if the HTML 5 guys had designed a dialog "button/box" combo you could customize instead. Then we would not need all of the above!
Warning: 'dialog' has minimal browser support today! Internet Explorer 1-11, Safari version 12 or earlier (desktop and iPhone), and Firefox version 63 or earlier, Chrome version 36 or earlier, Edge 18 and earlier, and Opera 23 or earlier do not support use of the 'dialog' element. Because of lack of wider browser support I generally do not recommend use of the 'dialog' element. You can now create much simpler modal boxes with a 'div', absolute positioning, and z-index layers in CSS.
CUSTOM DIALOG SOLUTION: Because I do not like Modernizr or "polyfills", I created a much simpler 'dialog' box above you can use that supports most browsers with either the 'dialog' element or a simpler scripted 'div' window for non-supporting browsers. The custom script and dialog solution I am posting above will solve most of your cross-browser issues using the new dialog modal window! It even works in Internet Explorer 5-11. The following features are listed below:
Features of My Custom Dialog Box:
My Dialog Box design allows you to support HTML 5 dialogs and modern modal windows in your website, while displaying simpler solutions for older browsers.
Dialog Box comes with a white, centered, rounded popup design you can customize.
Dialog Box has a sample form field with required dropdown and submit button that posts to the server and closes the dialog on submission.
Dialog Box has a cross-browser dark background CSS design in most older browsers
Dialog Box has an extra "close" button for improved assistive support
Dialog Box is fully compatible with many older browsers, including IE5-11
Dialog Box is one block of HTML and one block of legacy JavaScript designed for support in older browsers
Superior functionality in older browsers compared to JQuery Dialog, Modernizr, and more!
Heavy JavaScript API's, polyfills, Modernizr, JQuery, or other JS frameworks are NOT required!
* Internet Explorer Browser Support:
IE 10-11 : Performs normally with background
IE 9: Performs normally but without a background
IE 7-8: Performs normally but without a background and no rounded borders
IE 4-6: Dialog appears inside its parent block, but is fully functional. Also, "position:fixed" is not supported in these browsers, so the box returns as part of the scrollable page.
The 'dir' element defines a directory list. It was designed to create multicolumn directory lists in old HTML4, but has been deprecated.
Do Not Use as it has been deprecated in HTML 5. Use 'ul', 'ol', and 'dl' instead.
<div>
division, container
Division
<div style="padding: 1em;border:1px solid black;">
<p>This text is inside a "div" container</p>
</div>
This text is inside a "div" container
My Recommendations:
The 'div' element is a block-level container that defines a logical division of content in a web page. The 'div' element was a part of the original HTML specifications in the early 1990's. It has changed very little in over 20 years. It has also been the "work horse" element for most HTML web pages built today and in the past, and often used for holding large sections of content or for layout designs.
The 'div' element is by default a "block-level" element or container in web pages. It holds space, creates a new line, has margins, has dimensions, expands to take up available page width, and is part of the page flow. As such, it is considered one of the chief "flow content" element types. You can use CSS to change the structure and design of the 'div'. This makes this element a good choice for both custom layout designs and empty wrappers for holding content in your web pages.
'div' Attributes: Other than setting a unique 'id' on 'div' elements you wish to hide or manipulate with scripts, there are no real attributes beyond ARIA "roles" and "aria-labels" you should need on the 'div' element. 'div' is considered to have an ARIA "generic" role by default (not "none"'). Use these attributes when your 'div' element serves a purpose beyond a generic one, or contains content with semantic meaning in the page screen readers need to understand. An example might be "role=alert" added on 'div' that is used as an alert box. There are some unique attributes that add additional value without scripts, including "contenteditable=true" which allows text inside your 'div' to be edited by a user. Of course this change is not permanent, but might be helpful for educational web sites or demonstrations.
The 'div' Element, Structural HTML Powerhouse! Since the birth of HTML in the 1990's, the 'div' element has been used to structure the layouts of millions of websites. We still use the 'div' element to design our page layouts. But in HTML 5 that has been replaced by newer more semantic elements like 'main', 'header', 'footer', etc. But if you need a generic container for content or other structures, use our old friend the 'div' element.
<dl>
description list
Description List
A Description List can have Multiple Description Terms
<dl>
<dt id="dog1">Dog</dt>
<dt>Puppy</dt>
<dt>Mutt</dt>
<dd aria-labelledby="dog1">Man's best friend</dd>
A Description List can Include Definition and Abbreviation Tags
<dl>
<dt id="html1"><dfn><abbr title="Hypertext Markup Language">HTML</abbr></dfn></dt>
<dd aria-labelledby="html1">The standard markup language for creating web pages.</dd>
</dl>
HTML
The standard markup language for creating web pages.
My Recommendations:
The 'dl' element is a block-level container representing a description list. This list contains groups of description terms ('dt') and descriptions details ('dd'). The description list is often used to show a page's glossary, lexicon, or a dictionary of terms in key-value pairs. The 'dl' element has been around since the HTML4 days, and so is a reliable tool, though rarely used. HTML 5 now supports it.
The child elements, 'dt' and 'dd', are contained inside the 'dd' tag and used to list "terms" and their matching "descriptions". As such, the 'dd' element is just a list container like 'ul' and 'ol' list parents and has no visual design. Each 'dl' element should wrap around only one associated "term"/"description" set. Note: You can have many terms per description in a set, or many descriptions per term in a set (see my code examples above).
Even though a description list is just that, "descriptions" of terms used in a document, it is NOT the same as a "definition" or formal approved dictionary definition. If your list performs as a dictionary or actual definition list, you can wrap a 'dfn' tag around a term ('dt'). Example: <dt><dfn>HTML</dfn></dt>. When you wrap a 'dfn' tag around a term, you are officially "defining" a term and your list is now acting like a true dictionary or lexicon. See 'dfn'.
You can wrap a 'abbr' tag around a term ('dt') if the term is an abbreviation. Example: <dt><abbr title="Hypertext Markup Language">HTML</abbr></dt>. See 'abbr'.
The 'nowrap' attribute on the 'dd' child element used to be used to determine if the description detail text should not wrap. But this is now deprecated in HTML 5 and I do not recommend its use. Use CSS styles instead.
In the above example, I show how definition lists can be grouped in key-value pairs. In the last example, I show how you can wrap description pairs in 'div' elements for styling purposes.
I have also added ARIA accessibility tags in the examples above to enhance screen reader understanding of your description list.
<dt>
description term
Description Term
see <dl>
My Recommendations:
The 'dt' element is a block-level container representing a description term for a matching description detail within a description list. The description list is often used to show a page's glossary, lexicon, or description of terms in key-value pairs. See the 'dl' element.
<em>
emphasis
Emphasis
<p>This text has <em>emphasis</em>.</p>
This text has emphasis.
My Recommendations:
The 'em' element is used to represent a piece of inline text that is emphasized or carries a shift in tone in a sentence. It is usually represented visually by italic text.
Note: Use 'em', not 'i' in your HTML. The text these two tags wrap around looks the same but does not carry the same meaning. In old HTML4, tags like 'i' were used to only format or style text, not stress its importance. And so the meaning of the text was lost using 'i'. Today in HTML 5, importance has shifted to semantic tags that carry meaning as well as style, like 'em', which tells search engines and readers this piece of content has emphasis and should stand out. When you have text in a paragraph that needs emphasis use the 'em' element rather than the 'i' element.
What is the difference between 'em' and 'strong'? Use 'em' for a shift in tone or voice that represents emphasis. Use 'strong' for VERY important text that carries more weight than 'em'. 'strong' might also be seen as "stronger emphasis". (see 'strong' for its sibling type)
<embed>
embed
Embed
<embed id="embed1" alt="embed: Electronic Sheep Video" style="width:324px;height:240px;border:1px solid #000;" src="video1.mp4" type="video/mp4" title="Electronic Sheep Video" aria-label='Embedded File: Electronic Sheep Video'>
<noembed>Your browser does not support this media object or the embed element.</noembed>
</embed>
(Above is an example using the embed tag. Depending on your browser and the plug-in supported, you should see an "MP4" (MPEG4) video file. If you do not it is because this video format or codec is not supported by your browser.)
My Recommendations:
The 'embed' element is used to display a multimedia file in a web page, including an image, iframe, Adobe Flash, Java applets, online documents, audio, or video files. This element is supported in HTML 5 but slowly being deprecated by other elements when displaying multimedia in the browser. Use the 'img', 'picture', 'iframe', 'video', or 'audio' elements instead for those types, and 'embed' for specialized multimedia types only. Keep in mind 'embed' relies on plug-ins and players to play its media unlike the other HTML 5 media types. More details below.
The 'embed' element supports a number of attributes, including 'width', 'height', 'src', and media 'type'. The 'width' and 'height' are used to set the dimensions of your file. The 'src' attribute is a path to your multimedia object. The 'type' should have the generic MIME type of your media object and is a hint to the browser of how to interpret it.
As usual, always include an 'id' and a 'title' on these click-able multimedia objects.
The 'alt' attribute in 'embed' elements helps screen readers and the blind identify the meaning of embedded elements, just like images provide. For that reason, always add the "alt" attribute.
In older pages you may see a strange attribute (not used in HTML 5) called pluginspage, which is a URL that indicates to the browser where the required plug-in is to be found to play the media if it is not installed in the browser. Plug-in vendors typically made available a URL to download and install such plug-ins. Flash and the Adobe Flash plug-in download was a common use for this attribute. When a user displayed the page and did not have the player a popup would fire up asking them to install it. This is less common today.
Add autoplay="false" to stop videos from automatically playing when the browser loads.Warning: Videos automatically play in some modern browsers using 'embed' regardless of setting autoplay="false"! I tried changing many attributes to stop this and it still played! It turns out your users will have to go into their browser settings and under "privacy" change the "autoplay" feature to block autoplay for both audio and video. (This must have something to do with kids wanting Youtube videos to autoplay in web pages now.)
Use of the 'noembed' element: Today, in HTML 5, the 'embed' element is generally an empty element, meaning it has no start and end tag with no additional content inside it. It just displays a media element. But in the old days of the Internet, 'embed' was often part of a block of elements designed with fallback tags if a browser did not support object, embed, etc. The "noembed" is still supported but rarely used. However, in the example above, you will see how I have added the 'noembed' back in as a nice fall back element if a browser or screen reader does not understand the other 'embed' parent element.
The 'embed' element was never a part of the HTML4 spec's but was built by Netscape as a popular alternative to Microsoft's 'object' element for ActiveX and the 'applet' element for Java players. It has been around since the birth of HTML and the 1990's, so was once a very popular element used to support multimedia objects in web pages (everything but Internet Explorer which did not support 'embed'). Because 'embed' became a universal element for non-IE browsers and players, while 'object' became a Microsoft Internet Explorer ActiveX element, 'embed' was often contained inside 'object' elements and used as a fallback to Microsoft's ActiveX 'object' version. 'embed' is now strangely a part of HTML 5. You can still play many types of media using the 'embed' element, including: Images, Video, Audio, Flash, iframes, and more. The browser will interpret the media player required based on the file extension and the 'type' attribute and attempt to load a player to display it. Remember, Internet Explorer 5-10 has limited support of the 'embed' element as it needs the ActiveX 'object' element, instead.) Because of these crazy cross-browser issues, deprecated ActiveX support, and the fact images, video, and audio can now be displayed in newer HTML 5-friendly elements, there really is no reason to use 'embed' except to support older browsers or specialized media. Most of the "other" media 'embed' once supported have gone anyway and were driven by deprecated multimedia players that have been discontinued years ago. However, you may find older websites that still use 'embed'. If you are targeting older browsers it might be useful to still use 'embed' in special limited cases so you support those older user agents.
History: Prior to 2010 and the advent of HTML 5, the 'applet', 'embed', and 'object' elements were used to display a wide range of multimedia objects in HTML including: JavaScript Applets, Adobe Flash, plug-ins, ActiveX objects (in Internet Explorer only), images, video, audio, Windows documents, and older 3rd party applications in the browser. Nearly all embedded media was played back via a "player" or "plug-in" separate from the browsers. 'embed' and 'object' use this plug-in model, while the newer HTML 5 'video' and 'audio' have native playback support built into the browser and element. Keep in mind that for over a decade, web browsers viewed millions of multimedia objects this way using plug-ins and players of many types. Many of these media types are now discontinued, no longer supported, or are security risks in the browser. Smart phones also decided these players and plug-ins were a security risk as well as a CPU hog. For those reasons and more, these multimedia elements are generally not used in HTML 5, though they are still supported in various forms. With the newer smart phone technology that came online after 2007, it was decided that most of this new media would not be supported on mobile devices going forward. And so the plug-in model is dying fast. Tags like the 'applet', 'object', and 'embed' elements are dying too, even on desktop. Legacy websites today that still contain unique custom multimedia objects like this must now be removed or replaced with alternative media types as so many of the "players" that once supported rich media like this are no longer around to play them (post-2010). Adobe Flash, for example, was discontinued just a few years ago, though it was once hugely popular as a choice for highly interactive solutions in thousands of desktop websites. (I actually used to write Adobe Flash animations and applications in old Actionscipt.) This change has not stopped video, audio, or other applications from being embedded in web pages, however. HTML 5 has simply come up with alternate elements where the players are built into the browsers that parse them. Keep that in mind. So, if you see these old elements, 'object' or 'embed', and are deciding to remove them or update them with HTML 5, use the newer HTML 5 elements and media types available ('img', 'picture, 'iframe', 'video', and 'audio' using MPEG4, WebM, etc.).
Warning: Most versions of Internet Explorer 1-11 have never supported 'embed' and prefer the 'object' element instead, as it supports ActiveX. IE9-11 have adopted support of HTML 5's 'video' and 'audio' elements instead of 'object'. This is another reason to avoid this element and move to the 'video' or 'audio' element instead when supporting newer browsers. If you support video in these older browsers, however, you may find you need all three elements. Note: For a powerful new cross-browser video solution that works in old and new browsers and combines 'video', 'object', and 'embed' elements, see my section in "best practices" below called: "How to Create a Cross-Browser Video in HTML 5".
Warning: The sample video above may not play in Internet Explorer using Windows Media Player. If the video above does not play in IE or your browser could be because the media player used by the browser does not support the codec capable of decoding the video information. Your OS may recommend the installation of an additional codec to make up for this deficiency so that you can play the movie in your media player.
Warning: Use CSS to set custom 'width' and 'height' using 'embed' in supporting newer HTML 5 browsers, as the attribute version may not honor the dimensions you set. (see my example above)
As mentioned, I recommend you NOT use 'embed' for playing audio and video in web pages, but use the 'img', 'picture', 'video', or 'audio' elements instead. Even though HTML 5 still supports 'embed', because it is an element that is more reliant on the older "plug-in" player model, its better to avoid its use going forward. Again, if you must support IE or older browsers with multimedia, you may need to add a scripted fallback to use 'embed' and 'object' along with say the 'video' element when supporting these older browsers with video.
See my article below called "How to Create a Cross-Browser Video in HTML 5" for a newer, more modern example of how to combine 'video', 'object', and 'embed' elements together to enable wide video playback support across many old and new browsers.
* Note: The box around the form fields is the 'fieldset'. The "login" text is the fieldset's 'legend'.
My Recommendations:
The 'fieldset' element is used to group related form elements together, including the input, select, textarea, and button elements. It is often used to wrap a bordered, gray box around elements, simulating a PC dialog box when styled. It is a block-level element prized for its ability to group larger sections of complex forms into subgroups which would otherwise become difficult to manage. Note: It is recommended you use 'fieldset' with 'legends' (see below) if you plan to have multiple 'submit' buttons or subsections inside your forms.
The 'fieldset' element supports a number of attributes, including 'form' to connect the fieldset with its parent form element's 'id'.
Adding the 'id' and 'name' to your 'fieldset' is useful for showing and hiding large blocks of form elements using scripts. The 'title' attribute is optional here as the 'legend' provides a title.
A 'fieldset' usually sits inside a parent form, which wraps about it, or can be located outside the form but with a 'form' attribute associating it with the form elsewhere in the page (not recommended). It is recommended you always insert 'fieldset' directly under and inside every form, if you use it to group controls. Always use 'fieldset' if you plan to have multiple 'submit' buttons or subsections of forms. Also, the 'fieldset' element can be nested inside other fieldsets!
The 'disabled' attribute can be used to quickly disable all child form fields inside a 'fieldset'. But, I do not recommend you use the 'disabled' attribute in 'fieldset' as it might not be reliable in some browsers (Some Edge/IE browsers have issues with this attribute.), enabling buttons and forms to be active and submitted to the server, which you might not want. You should control them individually.
The 'fieldset' originally had a "Windows dialog box" look to it when using the browser's default style. It often came with a nice light gray background, grouping form fields with this neutral color. It then used raised buttons that pushed into the 'fieldset' color, much like old desktop application dialog panels used. This default gray look in older browsers was really nice and easy to use. We often used this look to dissolve the disconnect the modern user had online with web form displays, showing instead the old 1980's data entry forms they were used to. (I recommend you try that look-and-feel in your own web forms!)
CSS Issues With 'fieldset': In older browsers, like IE 4-7 and Netscape 4 series, you may see some design issues with this element. Fieldset originally had a Windows dialog box feel to it with a lite gray background when grouping form fields. This looked really nice with input controls inside it. So many designers tend to apply their own background colors and borders. But some older browsers bleed the gray color over the legend at the top, which looks ugly. To solve this you could just set "background-color: transparent". But then Netscape 4 series set background to black if a border was applied and background was set to transparent. So, to fix all this I created my own style fix below, which sets background to white for Netscape only and everyone else to transparent. I then apply this code below just for IE 1-7 series, and in my modern sheets add new designs for more modern browsers. Note: The "/*/*//*/background-color: white;/*end*/" code is a hack only for Netscape 4.
* I have created a very simple 'figure' example below using a plain image. But, you can wrap figures around many types of objects to create more complex captions (see my examples in "Best Practices" below).
This is the World Wide Web!
My Recommendations:
The 'figure' element defines a an image or visual element as a "figure" complete with a title or caption under it. The 'figure' element is new in HTML 5 and is now used by modern browsers to add textual information to images and other visual objects. The child 'figcaption' tag is part of the parent 'figure' element and allows many visual elements to have descriptive text associated with them. Before 'figure' was invented, captions on images and videos was often problematic in HTML design.
Figures: Most photographs or article images should carry more visual information with the element. The 'figure' element solves that by wrapping a visual element in the web page - 'video, 'img', or 'picture' - and associating them as figures within the larger page context. The "figcaption" resides inside the 'figure' element and often appears under the visual item with a "caption" describing the item. In the sample above, I demonstrate an 'img' element with a 'figure' and 'figcaption' as well as a full suite of attributes that assist visual and non-visual users alike in viewing the complete image as a figure within the page. Note that the 'figure' element has additional formatting that enhances the frame around the image as it might appear in an article. The child 'figcaption' element has placed a nice caption on the image. Notice the image has its native width and height attributes added, a title, alt value, and additional CSS to create the padded border. Adding dimensions on the image allows the "Render tree" in the browser to reserve space for the image in the figure and viewport as it downloads. I have also added an ARIA label (see below) to connect the figure with its caption for screen readers. Note that there are more complex 'figure' structures you can use. This one just demonstrates the most common one, which is an image with a caption.
Figure Tag Structure: The 'figure' element always contains a 'figcaption' element with text that resides directly underneath the video, img, or picture element. You always place description text or the "caption" describing the visual object inside 'figcaption'. Note that you can use 'figure' and 'figcaption' with a wide range of other objects, not just images.
The child 'figcaption' really does not need many attributes beside 'id', which is critical in associating it with its matching 'figure' parent. Its generally a best practice today to use ARIA attributes to assist the blind and screen readers in locating the correct text describing the visual element. The best way to associate the 'figure' with any visual object in your web page is to add an 'id' attribute to the 'figcaption' tag, then in its parent 'figure' element add an 'aria-labelledby' (ARIA accessibility attribute) with the 'figcaptions' id as its value. This tells the viewer that the figure's text label for the object is provided by the 'figcaption' text below. Your parent 'figure' tag's 'aria-labelledby' attribute will then tell screen readers any objects inside 'figure' are associated with the child 'figcaption' element and its text. To do so, use the ARIA attribute like so: aria-labelledby="myfigcaptionid"
Why Use 'figure' at all? Images and videos are often difficult to interpret for the blind. Most developers provide an 'alt' or 'title' attribute on those items to assist screen readers in interpreting their content correctly. The 'title' attribute on the 'img' element offered web page viewers rollover text prior to clicking an object, or for a small set of alternate textual info about the page item beyond its visual information. The 'alt' placeholder text for images was also used as a replacement for information about an image as it downloaded, as a placeholder in the page for slow image downloads, or in case the image was missing. Other attributes assisted images and videos in other ways. In the "old days" we used "longdesc" with a URI link on our images to provide a link to more detailed information about the image. But this attribute was not helpful and cumbersome to use. It is now either experimental or deprecated. But none of these attributes truly added reliable, rich textual information about the visual objects in web pages for screen readers. The 'figcaption' now directly identifies itself as the primary source for textual descriptions of the object to all users, so is directly related to assisting the blind as well as page viewers. It also avoids the confusion associated with various paragraphs of text around objects which might not be directly associated with them. The 'figure' element can give screen readers all the information they need about your images or objects without confusing the object with other parts of the page. Visual viewers can get added info about the objects embedded in the web page using 'figcaption', and use the text as fallback should the image or video be lost. Use the new 'figure' feature to describe all your page's visual objects, as well as display captions and figures that directly relate the item to the web page's larger content.
Browser Support: 'figure' is new in HTML 5 and so has moderate browser support across the full range of more recent browsers. However, all Internet Explorer browsers prior to IE9, and a range of older pre-2008 browsers, will not support it as they do not know what 'figure' and 'figcaption' are. To support older browsers (like IE 8 or older) I've added "display:block" to 'figcaption' since its a new unrecognized HTML 5 element with no defined structure. Older browsers that do not know these elements will often default them to "display:inline", pushing caption text to the right of the image and messing up the figure and caption design. Adding a small CSS style fixes it in the sample code above. In general, if you want wider support of figures around objects, consider using a 'div' and 'p' tag with 'id' and ARIA values. But, if you use my sample HTML code above, I do support use of 'figure' element, as it will display well enough in older browsers to be useful,
Note: Below in my section called "How to Display Images in HTML" I demonstrate a non-figure design that can be used to display larger captions that become more like descriptions, if your object needs to share more textual information with the viewer than a simple caption.
<font>
font
Font
<font size="3" face="courier" color="#0000ff">This text is wrapped by 'font' tags and should be blue "courier" font if your browsers supports older HTML4 'font' attributes.</font>
This text is wrapped by 'font' tags and should be in a blue "courier" font if your browsers supports older HTML4 'font' attributes.
My Recommendations:
The 'font' element is deprecated now and was a member of old HTML4. 'font' was used to change the font size, face, and color of text in your page. It is now deprecated. 'font' was fully supported in ALL browsers prior to 2000 at least, as CSS1 was not implemented in browsers until some time after 1996. 'font' is generally not supported in HTML 5 browsers today. For that reason, I do not recommend you use it to control visual formatting in your web pages. Older web pages using 'font' will support the tag, but likely not the font style attributes. Use CSS to format font styles.
Note: Old IE 1-2 (1996) and Netscape 1-3 (1997) were the main browsers using 'font' when styling page text, as they did not yet support Cascading Style Sheets.
<footer>
footer
Footer
See also <header>, <nav>, <main>, <section>, <article>, and <aside>
<footer id="footer" role="contentinfo" aria-label="Footer" >Footer</footer>
Header
Main
* A typical web page structure is shown above.
My Recommendations:
The 'footer' element is new in HTML 5 and defines an independent, self-contained piece of page content. It is used for defining a larger block-level area of content in a web page. Typically, the 'footer' element holds supplemental information at the bottom of the web page. In HTML 5, the 'footer' is part of a set of new structural page elements that define the overall layout of most HTML 5 website pages designed today (<header>, <main>, and <footer>, etc.).
The New HTML 5 Structural Elements include: header, nav, main, footer, section, article, and aside.
ARIA: The 'footer' element is a top-level, "self-describing" structure recognized by most modern screen readers without additional assistance. In the case of 'footer', it is recommended you add an ARIA "role=contentinfo" and an ARIA "aria-label=Footer".
See the <main> element section for more details about this new HTML 5 element.
<form>
form
Form
Shown below, is a complete code sample for the <form> element which you can copy-and-paste into your web projects. It has a complete set of attributes (I recommend), plus an example of every HTML form field element possible in a traditional form. Use it as a template for all your web projects, modifying it as needed. The visual design for this form is shown below the code.
The 'form' element defines an top-level element that wraps around form fields and buttons. It is used to tell the browser that a collection of data inputs is available for a user to fill out and submit. The 'form' element has been around since the birth of the web and has changed very little over the years.
Form Structure: The 'form' element generally is your starting point for creating interactive forms with inputs and buttons. It must wrap around all your form field child elements, and has many attributes that allow you to control how form fields send their data to the server (see below). But the 'form' element acts like a 'div' element in that by default it has no look-and-feel, acts like a block-level element, and serves no visual purpose other than to collect lots of form fields together for data entry and submission to the web server. Keep that in mind. It is both critical as a wrapper around form fields and buttons, yet has no visual design. In terms of structure, always add the <fieldset> and its <fieldset> element inside your 'form' element. Add all your form fields must reside inside the 'fieldset' element. Remember, you can add nested fieldsets inside each other to allow better partitioning of your form fields, but may not ever nest 'form' elements. In addition, the W3C recommends you wrap all your individual form fields in either paragraphs <p> tags or <div> tags. This gives your form fields structural grouping inside your fieldsets. You can also assign your form fields to unordered lists ('ol'), add headings ('h1') at the top of each set, and use other structural HTML elements inside forms. Note: Because some older Netscape browsers destroyed their forms when 'p' tags were wrapped around form fields, I recommend you use 'div' instead for all your inputs and button form fields wrappers, and use 'p' just for text. (see my code examples above).
Multiple Forms in your Pages: The 'form' element can have multiple forms in a page, one aspect many developers fail to recognize. This allows you to have pages that submit data to different web server locations, have separate sections for complex form processing (like file uploads), and associate different submit buttons with specific forms of data.
Attributes: The 'form' element has many attributes, which I have listed below. There are many others, but these are the main ones that work cross-browser reliably and which you will find useful. Note: I have added many of these attributes listed below to the "form example" above. So, you can copy-and-paste that sample code and get a great example of a form with a full set of attributes ready to use in your application:
'id' and 'name' - Always use 'id' and a matching 'name' with the same value when possible. The 'id' affects the client-side scripts that must have an 'id' value in order to access the form and all its form field children. If there are multiple forms, this is critical. If you have buttons or inputs outside the form, the "form={id}" attribute tells the browser which form they are associated with. I like to match this 'id' value to the 'name' attribute, as I do in all my form field 'input' elements. The 'name' attribute is what is often sent to the server, and helps your server-side processes identify which form you are processing. If the two values match its very easy to locate and sort client-side from server-side form processes when they use the same value for 'id' and 'name'.
method="get" - This attribute is optional and controls how data gets posted to the server via HTTP. HTTP works as a request-response protocol between a client and server. Your form must send data using one of these methods (GET, POST, PUT, HEAD, DELETE, PATH, OPTIONS). The two most common methods are GET and POST. GET ("method=get") is the default if you leave off this attribute. It sends your form data using the brower's URL. It is sent via a query string in name-value pairs ('name' and value' attributes of each 'input' element). POST ("method=post") is not the default, but more common in forms. So the "method=post" attribute on forms is more common, and represents a "post of data" back to the server in the HTTP protocol list servers are designed to support and receive from clients. It must be manually set to "post" to send the data over HTTP (hidden form the browsers and user). Only use GET if you are using plain text and smaller, simpler text input data. Otherwise, POST is more adaptable to different types of data, especially file upload data. It also allows you to use different "enctypes" (see below) for things like file uploads. Note: There are other HTTP methods, like PUT and DELETE. We often use those as well for specific form submission to narrow processing on the server to one way alterations/additions of data (PUT) or when deleting records (DELETE). It's not really necessary to use those optional HTTP protocols unless your server is specifically designed to respond to these methods with special actions your browser forms must support.
action="{url string}" - This attribute is also optional and controls the URL location on the server where your form will send and receive form data. If you leave this attribute off or blank, your form posts to the same URL as the current web page, which is typical. Thats why in old web form pages there often was no action path or value, as they defaulted to the same page. In the example above I set action="#", which posts back to the same page and avoids a call to the server. You would want to set this attribute to a new URL value if your form needs to push data to a URL that is different from the current page or send the user a response that takes them to a new URL (i.e. move them away from the original web page). That is often the case with login pages, though redirects can replace the need for that. It is more common to leave this attribute off. Note: Do NOT ever add query strings to your form "action" URL like so: "action=http://mywebsite.com/?name=JohnSmith". Why? When a form is submitted it will ERASE the query string when "GET" (default value) is used for the "method". When using "POST", your query string will pass to the server correctly in parallel with the form fields which POSt using HTTP headers to the server. But it is not reliable and risks being lost in some older browsers. If you need to pass data this way from a form, do not use a URL and a query string, but use "type=hidden" input types instead.
autocomplete="off" - "autocomplete" is new in HTML 5! This is another optional attribute. It allows forms (or specific form fields) to control whether form field text can be auto-populated with a user's previous text entries from other website pages that have form fields with the same "name" attribute as the current form's "name" attribute. The "autocomplete" value can be a range of custom values, like "name", "email", "tel", "photo", "username", "new-password", "current-password", and others. The most common values are "on" and "off", and most widely supported. This then gives you some control over which previous values for certain text boxes you want to display. The problem is browser support varies by each type. The only other values other than "on"/"off" I do recommend are "username" and "new-password" as they will have some security value in controlling choices users may enter in login page input fields. The problem is most of the others have only partial browser support. None have support in Internet Explorer. Beside, as we will see, I recommend you rarely allow users to use previous entries. It has less and less value and can be a security risk. So I do not recommend their use. Setting this value to "off" seems more important. Note that "autocomplete" is "on" by default due to the parent form's default value, so will set all fields to allow previous entries by default. That is another reason to disable this feature in the 'form' element, first. If yuou allow the default, modern browsers will allow user the ability to fill out fields with text values from a dropdown of choices that a user has already used before, and so avoid having to re-enter them again. The idea is to save users the hassle of retyping common values, like email addresses, into form fields. If you wish to use this feature just do not add the attribute at all, or set it to "autocomplete=on".
As I said, I recommend you disable all these fields for "autocomplete" starting at the parent form tag. The problem is "autocomplete=off" often lists previous input text entries for a user regardless of your author settings. In addition, Chrome browsers still do not support "off". So, depending on the browser, it can ignore your settings completely and still try and use previous data based on browser settings. In addition, as a user fills out a form that may have used the same 'name' attribute on another website, they might see a large list of unsecured login usernames and passwords. Because the form's default setting is "autocomplete=on", it allows users to use or see previous entries for commonly named form fields from website to website. It's then possible for other users on a laptop to see another user's login info. Often secured passwords or financial info must hidden. You must prevent users from seeing "autocompleted" options cached in the browser for security reasons, as doing so risks sharing private data with other websites. Using an 'input' of "type=password" with "autocomplete=on" (the default) on the 'form' means listed entries for prior passwords could appear in a dropdown beneath a user's username or password can be a security risk. Many browsers now have turned off "autocomplete" for "password" input types for this reason, by default. Older browsers may not. That is why for this one case, try "new-password" for "password types to disable this feature in some browsers. Nut even that may not be enough!
I often recommend you turn this feature "off", for all the above reasons and more. To do so, first set "autocomplete=off" on the parent form (other than "new-password" for the "password" input type) if you need all your form fields to require users to enter fresh input data. The text they enter in most modern HTML 5 browsers should then always be unique in your web page. But that might not be enough. The best way to permanently disable this feature in forms and fields is to simply create a custom "id"/"name" value each time on your 'input' elements using a unique value like a date concatenated to the field ("name=password_{date}"). Doing so, the browsers cannot cache the previous data, and will have no reference of previous passwords for the user in cache using this technique. It will force "autocomplete" to be off, or show a blank list, and will not show any previous passwords ever again! On the server side, you can create these custom input "named" fields and can still identify and extract the right field from the response coming from the user's browser. When the field's "name" value comes in you simply parse for the first part ("password_{date}") and ignore the rest.
Note that you can also apply this on an individual input field. An input's "autocomplete" value always overrides the 'form' element values. So, only rely on this setting on the field, not form, as a global attempt at controlling autocomplete settings in all your form fields may fail. Just remember, this attribute is good to set as a starting point in controlling your form, but do not rely on it.
novalidate="novalidate" - All forms naturally validate. No special attributes are needed. "novalidate=novalidate" disables validation in the form and in all child form fields that would normally validate. When form fields fail to validate they create an "error", preventing further submission of data until the data is fixed. Developers often use this "novalidate" attribute to turn off any natural validation by the browser and enable custom script or server validation. However, I recommend you NOT use it, and let the browser help you validate forms. In HTML 5, newer browsers now return richer validation of form fields with colored boxes and popup bubble messages to alert users. For some fields, like the new "email" input type, there is even built in "pattern matching" validation for email addresses the browser provides when "required" is set on these form fields. When "novalidate" is missing or not added on a form it means your forms will naturally validate all its form field data, by default. Thats a huge bonus when the newer browsers can help you validate like this! (I have decided to leave "novalidate" off in the code above for demonstration purposes and enable validation, the default). As mentioned, in more modern HTML 5 browsers, adding the "novalidate" attribute disables HTML 5 from trying to validate all form fields regardless of other settings. I do not recommend you do that. The exception is the "formnovalidate" added to 'input' elements and submit buttons which does the same, but forces no validation on a field-by-field basis, which is better. When validation is off like this, all kinds of bad data can and would be sent to the server regardless of errors. This could then cause problems on the server, forcing the server to return to the page with a wide list of errors for the user to address. This is another reason to have very powerful data checks on the server-side for all your data, but also on the client-side.
Often some HTML 5 input fields, including newer ones, like "numeric" and "email", require multiple "checks" in order to be valid. Some text field data must first be present (when the "required" attribute is added). The data values must also be valid in terms of format (email or numeric formats, for example). That is two checks. "novalidate" would stop both checks. Example: Using an input element with "type=email" on an input element will ask the user to type a correct email address format into the text box. If the user submits the form and fails to do this, a bubble message appears in most HTML 5 browsers alerting them of a validation error (unless you have added "novalidate="novalidate" to your form). Therefore, adding this "novalidate" attribute disables an important new HTML 5 alert feature in today's browsers. So again, I do not recommend you add this attribute. Like the "autocomplete" attribute, "novalidate" is not very reliable even when added. For starters, JavaScript validation can override validation or no validation settings on the form. Second of all, many browsers have settings that can stop or enforce form validation regardless of form settings. "password" 'input' element "types" are often overridden or controlled by the browsers, regardless of the form or field settings. In addition, some attributes on individual form fields can also affect or override form validation attributes. But it can also work the opposite. Example: You should know that "validation" is not the same as the "required" form field attribute on individual form fields, which determines if a form field can be left blank by the user. However, when "novalidate" is present on a form, "required" attributes on form fields are ignored, or turned off. So, when you do use "novalidate", all fields with any kind of required validation that potentially stop submissions with missing values are now completely ignored. Empty form fields are then allowed to be submitted to the server. Also, know that the natural validation or non-validation of a form and its fields does not stop hidden input fields with missing or bad data from being submitted, or "disabled" fields from posting data at all, regardless of validation. For all these reasons and more, do not rely on "novalidate" or the natural validation of forms and fields to control form validation. Always count on checking data manually on the server as a last resort, but use scripting and the HTML 5 validation on the client side as a first line of defense against bad data. If you decide to support scripted validation and manage without HTML 5 or the server (I do not recommend this) add "novalidate=novalidate" to the form to turn off validation, then use scripts (like JQuery) on the client-side to check each form field for errors and report issues to users as they fill out your forms. But remember, when it comes to form field validation, always rely on server-side validation code first, regardless of form attributes, client-side scripts, or HTML 5 validation! If bad data comes in on the server, and it still has errors, it could cause database issues or worse, SQL injection or hacks that compromise the server! Note: The individual form field equivalent of "novalidate" is "formnovalidate=formnovalidate", which can be used on any form field, like inputs, to disable the form's natural validation setting. This is often used if a form does not use the "novalidate" attribute, and everything in a form needs to validate except the specific input field. I prefer this type of setting. It can be used on "submit" buttons when you want to remove validation when certain buttons are clicked, then allow specific from fields to control validation on a case-by-case basis. Or, it can be used when bolting on scripts that capture button events and don't want the browser to report form errors and let the script handle them. It acts like an override, removing form validation. It is the same as a form adding the "novalidate=novalidate" attribute. Additional: There are some additional modern browser bugs that come with this attribute. While Safari, iOS, and Android browsers do support the "novalidation" attribute, the form in those browsers is often submitted whether the form validates or not, as if the "novalidate" attribute was always present. In other words, those browsers never validate form fields, anyway, and ignore form field errors! So do not rely on HTML 5 browser features such as these, as they are not consistent. Add them as extra enhancements, only. And always rely more on your server-side processing!
enctype="application/x-www-form-urlencoded" - The "enctype" controls how data is encoded when submitted to the server. "application/x-www-form-urlencoded" is the default and the same as using no enctype on forms. A change to the enctype only affects form data when the "method" attribute is set to POST, as all url-encoded data for GET is generally encoded the same. There are three types of form encodings, you can use, however:
"application/x-www-form-urlencoded" - (The default) Using this setting, all data is encoded before sending, with certain characters being converted to lower encoded numerical values. In the old ASCII days, most non-alphanumeric characters were replaced with escapes. In HTML 5, this enctype generally converts form field characters to ASCII (first 127 characters) numbers first (which match UTF-8 values), then the rest of the non-ASCII characters into UTF-8. Any non-ASCII characters are also encoded with '%' (percent encoded) using hex value pairs taken from ASCII, then sent to the server. In addition, form control names are separated from their values by '=', and names are separated by '&'. This is the most common format used.
"multipart/form-data" - Only use this if you are posting 'input' elements with "type=file" (file upload controls) and the form 'method' attribute is set to "post". When a user uploads a file using this multipart encoding type, a batch of binary data is extracted from the file by the browser, encoded into compressed hex values, then converted to a type of delimited block set. This binary data set is then sent as a large binary stream to the server to be decoded in blocks and extracted into a binary BLOB or other format on the server.
"text/plain" - This sends form data without any encoding as is. It is rarely used as it sends many non-ASCII characters without encoding. I do not recommend this as it risks sending many types of scrambled non-ASCII or UNICODE data to the server, with many upper-level characters being misrepresented or lost in translation when decoded on the server. It is also less secure.
The lesson to be gleamed here is, do NOT change the "enctype" unless you are planning to use the 'input' element as a "file upload". Wrap a special form around just that element, if you do, and change the encytpe to "multipart/form-data" in that one case. Leave everything else the default, or even better, just leave off "enctype" entirely. It will use the default value, which is best. You can override the form's "enctype" in an individual form field using "formenctype", but it is not recommend.
target="_self" - 'target' allows you to send the results of a form post to a separate window for processing. In the old days we used "frames" and "framesets" to hold multiple forms and process form data in frames. When posting form data this way, it was possible to process that in another frame or window so users would not have to deal with the results. That is rarely done today. But you might find yourself wanting to process form data in a hidden 'iframe' element which you can still do in HTML 5. But, I do not recommend it.
ARIA - When designing forms for accessibility in a screen reader, there is very little you need to add to the 'form' element, as like many top-level HTML 5 elements, they are self-describing. So the ARIA 'role' attribute is often not needed, unless your form handles specialized data, like "search", "email", "file" uploads, etc. In those cases, you would need to apply a custom role to your forms. If you have multiple 'form' elements in a page with different purposes, then it might be helpful to add an ARIA label. An example of using ARIA form label attributes might be: "aria-label=Website Login Form". Custom "state" ARIA attributes in forms and form fields is optional (example "aria-pressed" or aria-checked="true"). But it should be used as well as updated by JavaScript if you rely on a stateless scripted API in your website, like Google's Angular or Facebook's React. Because the page never refreshes with new updated HTML on events like submissions in these frameworks, screen readers and the blind have no idea if anything changed in the page or its HTML. So you will need to use JavaScript to update the DOM HTML and its attributes using ARIA "live" attributes when data is changed in the page (I do not cover that here as its beyond HTML). The only other 'input' element "types" you might add ARIA "role" attributes to are for the new HTML 5 textbox "types", like "email", "password", "number", "search", etc., or for 'button' and 'input' elements that use "reset", "image", or "file". The latter types might not be described as buttons and confuse a reader when engaged.
title="My Form" - As always, I recommend addition of the 'title' attribute on 'form' elements as it helps some people know what a form does on rollover when inside one of multiple form fields. You can add this to the 'fieldset' tag, as well. I would match these values to the value of your fieldset's 'legend' text value.
Additional Attributes - There are other attributes for the 'form' element not covered here that in general, are either not widely supported across old and new browsers, or not consistent in their implementation. Why use them, then? For that reason, I will not cover those here. Just remember, if it does not work cross-browser its probably not a good addition to your HTML toolkit. In addition, many of the form fields listed above in my code sample also have special attributes based on the parent form field settings. Some affect the parent form's settings or override them. I will cover those under each type of field in this HTML 5 list. But in general, they do not affect the basic functioning of forms.
JavaScript Form Submission Tricks - Because 'form' elements control the processing of data sent to the server, JavaScript has for many decades been used to manipulate, massage, validate, show/hide, and control the processing of form field data. Just know these are "substandard" ways to use basic HTML forms and not the norm. Try and use HTML forms as is, but add scripts on top to validate and enhance it, not the other way around. Knowing the basic HTML way to submit data first will help you if you get deeply dependent on these JavaScript API's, later. Today, many JavaScript API's now create form fields dynamically (often very sloppily), or bypass form processing completely, hijacking the submit button and sending the data via WebAPI's, REST, SOAP, or by other means. This means form data is often not processed at all using a traditional 'form' element. It just is not "submitted" via HTTP. In these JavaScripted systems, the 'form' element is basically disabled so the data can be sent to the server in other non-traditional ways behind the scenes and prevent a "refresh", which is "evil" (for some reason) to JavaScript developers. I personally think this is lazy design. But it is one wave of the future we cannot ignore. When you are thrown into a team doing this type of crazy scripted form processing, it gets confusing as to why the form does not work naturally and what is really happening. The first sign of this type of trick in "hijacked form processing" is when a form "button" control has an event capture script with a "preventDefault()" event processor on it, a "void()" on the "onSubmit" event on a button, or "return false" in the script blocks associated with the form submission. When you see these strange scripts on buttons and forms, know the form submission in the web page has been disabled. All these scripts do the same basic thing......they turn off form and stop the button event that submits the form data to the server. These event capture scripts generally stop the data from going to the server so it can be manually validated by the script internally then shipped to the server manually using "XmlHttpRequest" calls or other special HTTP protocols. (We used these "calls" decades ago when early DHTML was developed. We never dreamed script kiddies would adopt this as a chief technology dependency in these API frameworks!) But, now you know how and why thousands of new web applications today send and receive data from servers this way without use of a real 'form' element. Knowing how things work in basic HTML behind the scenes with heavy scripting like this will help you greatly understand the bigger picture of HTML and how it's often subverted by 3rd party vendors in substandard ways. But just know the old ways will outlast these new ways, as HTML and forms have changed little in over 20 years.
CSS Form Styles - In most cases, the 'form' element does not need styling, as it is an empty semantic element. Almost all the "pretty" designs for form elements you see above in my examples were carefully built using my "Universal CSS Framework" style system, which includes a "reset" sheet that redesigns all the elements, including the form-related ones. If you are interested in recreating this look-and-feel in your form fields, simply copy or download my style sheets from your browser. Note: In HTML 5 you can now respond to "required" and "valid" fields using CSS with colored form boxes or custom designs you create for these events. As mentioned above, many HTML 5 browsers now display popup bubble alerts if fields are required or invalid and fail. But CSS has added new events using ":valid" and ":invalid" CSS pseudo-classes you can also use in CSS, which respond when form elements inside the form are valid or invalid.
The "data-" Attribute in Form Fields: As mentioned below in my "Best Practices" article called "The New 'data-' HTML 5 Attribute", you can now safely use the new "data-" attribute in any HTML form element to store extra data values.
Special Form Issues: Avoid giving forms dimensions or styles, when possible. They are considered empty elements and containers for child form controls. The top-level elements that hold forms are a better place to add styles, colors, borders, etc. Also, use the 'fieldset' and 'legend' inside of forms for design. Avoid wrapping "p" element around any input controls as in Netscape they are treated as containers and the form will fail. Always use 'div' elements instead. You can now use the other server HTTP method types, like PUT, DELETE, etc. when sending form data. Many developers ignored these types in the old days, as they often required custom web server settings to respond to them. But with more control over the server's settings and responses using MVC and other modern frameworks, controllers in these server scripts can now listen to and capture these different types of server methods successfully.
Common Elements Inside Forms: There are several new, "experimental" form field elements included under the 'form' element that are also listed in this HTML 5 list, but which are not shown here (like 'datalist' and 'output', for example). There are also a large list of new 'input' element "types" in HTML 5 which add new features in forms, but which have spotty browser support in 2021. I left these newer HTML 5 form field elements off the 'form' examples shown above as they are still not widely supported, buggy, or require too much scripting. You can read about those new elements elsewhere in this tutorial list. Try and stick with the basic ones shown above and below. They have been around for over 20+ years. See the <button>, <fieldset>, <legend>, <input>, <option>, <optgroup>, <select>, and <textarea> sections of this HTML list for more detail on each of the more common child form field elements available for use in forms.
<frame>
frame
Frame
see <frameset> and <noframes>
<frameset cols="50%,50%">
<frame src="https://www.w3.org/TR/html4/present/frames.html#h-16.2.1" />
<frame src="https://www.w3.org/TR/html4/present/frames.html#h-16.2.2" />
<noframes>
<p>This frameset includes two page views of the W3C websites on frames.</p>
</noframes>
</frameset>
* If you do not see anything below, then the 'frameset, 'frame', and 'noframes' elements are not supported in your browser.
My Recommendations:
The 'frame' element is deprecated now and was a member of old HTML4. A 'frame' resides within a 'frameset' and represents a document window or URL of a web page within the larger browser viewport. In the past, frames were a common way to combine, manage, and display many different web pages within a single web page. Many pages in frames could be displayed in the browser this way. It was a very cool concept at first, but over time became difficult to manage and unnecessary. In HTML 5, 'frames' and its parent 'frameset' are deprecated, though the 'iframe' or floating frame is still supported in a limited way in HTML 5 browsers.
Attributes of Frames: If you do see frames, they always reside inside a 'frameset' parent element. The 'frameset' often defined the percentages of each row and/or column each frame used in the total display. All 'frame' elements included a "src" or source URL attribute, which told the frame what web page to display inside its box. In the old days this could be url and any web page online. This later created a big security risk, as some sites used hidden or tiny frames to hide frames that captured logins from other websites. You often gave your frame an 'id' and 'name' so you could access or manipulate the frame. Adding "scrolling=yes" allowed you to make the frame scrollable. "auto" was the default. "frameborder" was used to provide a border. "noresize" prevented users from grabbing frame borders and changing the size, which was an interesting aspect of frames, as users could customize the display. This latter feature I often used in the old days of page design to allow my users to customize my page's header navigation or hide sidebars. In general, frames and framesets were a bad idea for many reasons, the main one being security, as cross-origin web pages inside the browser window could allow other websites to affect domains in other frames. But to me, frames were not all that bad when used properly. The problem is they were abused and used by some to showcase sloppy web design. That is the real reason they fell out of use.
Do not use the 'frame' element now, as it is deprecated and was a member of old HTML4. HTML 5 browsers will no longer support frames. You might try the 'iframe' instead (see below):
<iframe src="https://www.w3.org/"></iframe>
<frameset>
frameset
Frameset
see <frame> and <noframes>
<frameset cols="50%,50%">
<frame src="https://www.w3.org/TR/html4/present/frames.html#h-16.2.1" />
<frame src="https://www.w3.org/TR/html4/present/frames.html#h-16.2.2" />
<noframes>
<p>This frameset includes two page views of the W3C websites on frames.</p>
</noframes>
</frameset>
* If you do not see anything below, then the 'frameset, 'frame', and 'noframes' elements are not supported in your browser.
My Recommendations:
The 'frameset' element is deprecated now and was a member of old HTML4. A 'frameset' held 'frame' elements which were a document window or URL of a web page within the larger browser viewport. In the past, framesets were a common way to combine, manage, and display many different web pages within a single web page. The 'frameset' replaced the 'body' element when it was used and was seen as a complete replacement for 'body' content. Many pages in framesets could be displayed in the browser this way. It was a very cool concept at first, but over time became difficult to manage and unnecessary. In HTML 5, 'frameset' are deprecated, though the 'iframe' or floating frame is still supported in a limited way in HTML 5 browsers.
Attributes of Framesets: If you do see framesets in older web pages, they always contain both 'frame' and 'noframe' elements. The 'frameset' often defined the percentages of each row and/or column each frame used in the total display. Over time the 'frameset' element and its child 'frame' elements containing URL's to many web pages became a big security risk, as some sites used hidden or tiny frames to hide frames that captured logins from other websites. You often gave your frameset an 'id' and 'name' so you could access or manipulate the frameset. Also, the 'frameset' contained a 'col' and/or a 'row' attribute with dimensions for all the child frames or framesets inside it. You could design very elaborate page layouts this way using multiple columns and rows, which in turn contained more framesets with frames. In general, frames and framesets were a bad idea for many reasons, the main one being security, as cross-origin web pages inside the browser window could allow other websites to affect domains in other frames. But to me, framesets were not all that bad when used properly. The problem is they were abused and used by some to showcase sloppy web design. That is the real reason they fell out of use.
Do not use the 'frameset' element now, as it is deprecated and was a member of old HTML4. HTML 5 browsers will no longer support framesets. You might try the 'iframe' instead (see below):
<iframe src="https://www.w3.org/"></iframe>
<header>
header
Header
See also <nav>, <main>, <footer>, <section>, <article>, and <aside>
<header id="header" role="banner" aria-label="Header" >Header</header>
Header
Main
Footer
* A typical web page structure is shown above.
My Recommendations:
The 'header' element is new in HTML 5 and defines an independent, self-contained piece of page content. It is used for defining a larger block-level area of content in a web page. Typically, the 'header' element holds a logo, navigation, and other features at the top of the web page. In HTML 5, the 'header' is part of a set of new structural page elements that define the overall layout of most HTML 5 website pages designed today (<header>, <main>, and <footer>, etc.).
The New HTML 5 Structural Elements include: header, nav, main, footer, section, article, and aside.
ARIA: The 'header' element is a top-level, "self-describing" structure recognized by most modern screen readers without additional assistance. In the case of 'header', it is recommended you do add "role=banner" if used as a top-level element and add an ARIA "aria-label=Header".
See the <main> element section for more details about this new HTML 5 element.
<h1>, <h2>, <h3>, <h4>, <h5>, <h6>
heading
Heading
An example of a typical "heading" page layout is shown below. This HTML would appear inside the <main> element in the 'body' of your web page:
<section aria-labelledby="heading1">
<h1 id="heading1" title="Example of an H1 Heading">H1 Heading</h1>
<div>
<h2>H2 Heading</h2>
<p>text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 </p>
<h2>H2 Heading</h2>
<p>Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 </p>
</div>
</section>
H1 Heading
H2 Heading
text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1 text 1
H2 Heading
Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2 Text 2
My Recommendations:
The 'h1' element and its siblings (h2, h3, h4, h5, h6) are block-level "headings" (text titles) that appear at the top of web pages. They represent the semantic title of a web page or for a body of text, and usually contain keywords that relate to the content below it. Headings have been around since the birth of HTML and the 1990's, and have changed very little. They are still popular today and used by search engines along with other tags to help identify the subject matter and keywords found in a web page.
The only read attributes needed on headings are the 'id' and the 'title' (tooltip) attribute. Add 'id' if you plan to associate your heading with an ARIA labelledby attribute (see below). The 'title' is optional but nice to have if you plan to provide more info about a section of content defined by the title.
Headings Came from Old Books: Heading elements traditionally have been plain text. They were originally designed to match the old chapter headings found in old books. That design concept continues today, and has not changed much in over 20 years.
Heading Structure: Every web page needs headings! You should have at least a 'h1' heading at the very top of the page. The 'h1' title defines the overall meaning and purpose of the page and its content to readers, to search engines, and to screen readers. So, it has a very important role in page-level structure. For that reason, it often is neglected by web developers who choose to ignore the simple book-like design and purpose of web pages on the World Wide Web today. The Web is primarily used by Humans for reading and gathering text-based information. Multimedia and other properties are always secondary to that purpose. For this reason, each page should have an 'h1' element at the top with keywords in the title that match the web pages text content, then use 'h2', 'h3', etc. to define subsections of your page that enhance the primary subject matter of the page. The top-level 'h1' heading is the most important one, and can be placed either above the navigation in the heading or inside the "main" element as a title heading. Because many modern web pages do not always use heading elements in their navigation because of design issues, you should use CSS to change its placement, design, and use. However, as a warning, you should not use CSS tricks like "visibility" or hide the "h1" title to make your page look sexier without headings as search engines will punish you in rank for that! One strategy is to place 'h1' element and its text inside the page's default home link or image at the top of the page, and add text that summarizes the subject matter of your complete website. A better strategy is to simply add a 'h1' title above each page in your site, above you text content, as it was originally designed to do. Always add sub "headings" in smaller subsections of your page, as they too enhance your pages and make them more readable by your users.
Search Engines and Headings: The 'h1' element is used by search engines to identify content, its primary subject matter, and to define important content sections in pages it needs to parse. For that reason, headings have a powerful influence over how pages are indexed by search engines (like Google) and what keywords define a page of text. It is always a good idea to match the meta "title" element's values and "description" keywords with the "h1" title in the page so they are in sync. Often search engines will parse metadata first, parse the headings next, then lastly parse the text to gather information about keywords and the purpose of your content. They do this to build better indexed pages online so millions of people can consume valuable data about a particular subject more quickly online. All that is driven primarily by text! Use headings to help users and search engines determine "document structure" as well, the primary content of a page, and its dominant subject matter. If your web page's text then discuss the same keywords and subject matter with rich, valuable, unique content, search engines will love this and reward you generously with high search engine rankings for many years. The "h1" element starts that process by being at the top of every web page, front and center! Search engines will read the heading text first and give it importance in its indexing bots, if not use it for search titles in its own search listing. This also happens in cases where the meta tag title is absent or not sufficient in a web page, or keyword content is not clear. So if you want better search engine ranking and thus more visitors, do not forget the 'h1' element!
What is in a Name? "heading", as defined by the 'h1' tag, is often confused with the term "header" and "head". It even gets confused with the term "header" or "heading" when describing the stop section of web pages. Below is a breakdown to make all these terms clearer:
"head" - This is the <head> element of a typical web page. It represents the non-visible metadata section of a web page above the <body>, or area visible to your users.
"header" - This term has been used for multiple meanings. First, it represents the new <header> HTML 5 element, that now defines the top structural section of a web page. The term "header" has for years also been used to describe the top section of a web page. But now that meaning is semantically applied to the new element, as well.
"heading" - Even I get confused, but know that "heading" ONLY represents the "h" elements that contain page title text. But in the past, many of us have called the "header" or top section of web pages "headings", too. I recommend you erase that idea now that we have a real "header" element. So, the top section of pages and elements are always "headers". And "headings" are simply text title.
ARIA: As mentioned elsewhere, you do not need to apply the ARIA "role" to "h" elements, as they are self-describing. But as shown in the example code above, its now a good idea to map a 'section' element with a 'heading' element (or 'h1') using the "aria-labelledby={h1 id}" attribute. The 'section' adds this attribute with a value matching the 'id' attribute of the 'h1' element. This then tells screen readers and search engines that the definition of that section of the page equates to the top-level heading title inside it. This adds more value to the page, associates a section with its top heading, helps screen readers identify the meaning of the page's content, and gives search engines the association of your page with its section, its title, and its text content. This then improves search engine ranking.
Remember to use the 'h1', 'h2', 'h3', 'h4', 'h5', and 'h6', inside smaller and smaller subsections of your pages. Think of your web page as a book that users will read through and navigate, using your carefully placed headers as guideposts along the way.
<hgroup>
heading group
Heading Group
<hgroup>
<h1>Chapter 1</h1>
<h2>Intro to HTML Fundamentals</h2>
</hgroup>
<p>Page text starts here...</p>
Chapter 1
Intro to HTML Fundamentals
Page text starts here...
My Recommendations:
The 'hgroup' element was new in HTML 5, but now partially deprecated. It allowed the primary heading for a document section to be grouped with secondary headings. Doing so, it removed headings from text and grouped them together at the top of a web page for semantic purposes. Because it is now partially supported in HTML 5 browsers, but removed from the W3C recommendations, I do not recommend its use in web pages at this time.
The browser support for 'hgroup' is still decent, but not 100% in newer browsers. In IE8 and older browsers it has no support. I do not recommend use of 'hgroup' due to non-support in HTML 5 browsers as well as modern screen readers. It would complicate heading-text associations and thus confuse many browsers and screen readers, alike. Its use was also not necessary, and only useful in formal document structures online.
<hr>
horizontal rule
Horizontal Rule
<p>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text </p>
<hr />
<p>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text </p>
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
My Recommendations:
The 'hr' element is a horizontal rule that divides text content in a web page from other content. It is a block-level element, so often appears between paragraphs ('p' element) in a web page, and forces content below it on a new line. The horizontal rule has been around since the 1990's and widely used for over 20 years to separate text in web pages. Use it to help you break up all your text, media, form fields, and other content in your web pages.
Its Old Book Design Origins: Horizontal rules contribute semantic meaning as well as design functions in your web pages. By separating content, they tell readers and search engines where content begins and ends in your pages. Rules were created as a way to duplicate the tiny separators found in old books, where a narrative often broke away from the larger context. This often confused readers, so a marker was used between text in the page to tell the reader of the shift in narrative, story, or tone. The horizontal rule has gradually moved from a simple literary design concept to separation between larger blocks of text and page content. As such, it is a powerful tool to separate various types of text, media, form fields, and other page structures in websites. Many young developers never use horizontal rules, so miss out on a powerful element used in millions of web pages. It is still a powerful structural tool in your HTML toolset. The rule is also friendly with search engines, who will identify separation of content and ideas and use them to partition valuable content from media that may not be as important.
What is the Right HTML 5 Structure for the 'hr' Element? As always, the great debate by newbies online demanding we use "void" HTML 5 elements as they were designed continues. Their argument says that any element that has no ending element, is a "void" element in HTML 5 and should NEVER have an end tag (example: <source>). They then apply this argument to a whole host of HTML elements, like 'img', 'hr', and others. I disagree! The horizontal rule is no different! They argue the <hr> format is the right format now in HTML 5, and should not indicate it has ended. But they are WRONG! You should ALWAYS design your HTML 5 to avoid this "void" design and add a forward slash at the end of your horizontal rule element like so: <hr />. This is completely acceptable in HTML 5, as HTML 5 is now a living standard that accepts all types of formats and changes, unlike the W3C recommendations which were more enforced. Using my HTML rule allows your pages to match XHTML/XML standards, allows your HTML to be read faster and cleaner by 3rd party parsers, improves the DOM manipulated by JavaScript, and best of all actually "ends" the horizontal element correctly! The "void" version does not, and spreads inconsistency throughout your websites. As you write thousands of web pages over time, making sure all your HTML is XML-friendly with ending "/" characters means your HTML is now robust, consistent, cross-compatible with multiple standards, fully XML-compatible, and best of all CORRECT!
See my section called "Use Horizontal Rules (hr) when Separating Content" below for additional details.
I have decided to cover all the major HTML "framework" elements in one section so you can see how they create the modern HTML 5 page when combined. They include the following: <!doctype>, <html>, <head>, <title>, <meta>, <body>, plus the "doctype" definition tag <!doctype html> that goes at the top of the page. Combined, these elements are required in all legacy and modern web applications, and define your current web page as HTML 5.
I have created a "bare bones", basic HTML template below with recommended values and meta tags I recommend you use in all your HTML pages. You can cut-and-paste it into any blank page and use it as a solid HTML 5 starting web page template. Just change the values in the attributes for your specific requirements. All other elements listed in this tutorial would appear inside either the <head> or the <body> elements shown below. Note: The 'meta' elements used can include many more than is shown here, or far less, if you choose. Most HTML 5 parsers in browsers will assume values for most of these meta tags, anyway, so most are optional. See my list of required meta tags in the section below.
If you want a full featured HTML 5 template with all the other HTML "goodies" included, like "external" CSS style sheets or JavaScript links used in this section, visit my section below called, "My Complete HTML 5 Template".
The 'html' element represents the "root" of an HTML web page. As such, it defines your web page as a Hypertext Markup Language document. This element has been the root of all HTML websites since the birth of HTML in the 1990's. Very little has changed with this element and its children, beyond the addition of a few added meta tags. There are several other elements besides 'html' that are needed to structure a modern HTML 5 web page. I will cover those elements below.
Modern Structure of an HTML Web Page: Over the past two decades we have seen the rise of HTML, XHTML, and now their newest cousin, HTML 5. But the overall structure of markup has not changed much. I will not cover the history of the 'html' element or the various recommendations and standards. That is a long story. Rather, I want to just talk about the main structural elements that define the modern HTML 5 page, and how best to design your pages using HTML. It is very simple. For more detailed discussions of various meta tags or items in the 'head' or 'body' elements of your web pages, please see my "Best Practices" section below:
<!doctype html> - This truncated, "incomplete" DOCTYPE version for HTML is now required in all HTML 5 pages and defines your document as a "true" HTML 5 document. As a result, you MUST use this code at the top of every web page if you want browsers to define your pages as HTML 5. The newer web browsers will generally assume you are always using HTML 5 by default. But, older browser will not. Most older browsers will default to an older form of "tag soup" HTML, or "quirksmode" HTML, when they see this unusual doctype at the head of your web page. What is defined at the top of the web page often controls the type of HTML used by the older browsers, like IE6. This was known as "doctype switching" in the old days. Keep in mind that most browsers created after 2010 also still support some form of doctype switching, but will generally know HTML 5, which is likely 90-99% of most browsers viewing your website in 2021. Many browsers created before 2010 knew XHTML, however, which relied on doctypes as well to define their XHTML applications as a form of XML. That means many browsers created after, say 2001, may try and use their "switching" abilities to use the HTML 5 DOCTYPE and interpret your web page as a form of invalid XHTML. That is generally ok, as we are not worried about validation in HTML 5. Remember, its a "sloppy" standard and very forgiving in many older browsers, allowing many forms of HTML to be used that likely are still valid in XHTML and HTML4 browsers. There is an "XHTML 5 Polyglot" DOCTYPE you can use instead, if you are truly interested in supporting XHTML in these older agents. I do not cover that here as its a subtype of the same HTML. Because many older XHTML-friendly web browsers use DOCTYPES in general to define whether a page is XHTML/XML friendly or plain HTML, this "partial" HTML 5 DOCTYPE format might trigger some older agents to parse the page as XHTML rather than "tag soup" HTML. Because most web servers, however, rarely delivered true XHTML pages as XML, in the strict sense, these pages would likely fall back to HTML. The HTML tags supported between HTML4 and XHTML1.1 are close to the same, anyway. (My "best practices" section in this page covers a way to make sure your HTML 5 works in XHTML 5 by using XML-friendly code, btw.) So my point is, do not worry about these issues in older browsers and the HTML 5 DOCTYPE. By following my recommendations in this tutorial, your code will work GREAT if one of these older XHTML browsers were to try and parse your page as XHTML/XML using this doctype. Because most would not accept an "incomplete" DOCTYPE as HTML 5 uses, its likely they would fall back to a form of HTML4.1, in most cases. But, just realize DOCTYPES for decades have factored into how older browsers interpret what flavor of HTML you are using. But, know that the majority of the time, because none of the older browsers will know what HTML 5 is, they will just consider your web page "tag soup" HTML, using the server's default HTTP content-type of "text/html" to define the page as generic HTML.
<html xml:lang="en-us" lang="en-us"> - 'html' is the root element of every website, HTML 5 included! As such it defines your page to user agents and browsers as HTML. This includes all the older versions, like HTML3.2 and HTML4.1. Using the HTML 5 DOCTYPE mentioned above in combination with this root element, your pages are recognized as HTML 5 by the nearly all user agents online today. In the past, there have been several attributes added to 'html' tags to help browsers define the language the page is using. "lang" was the main one. Because different browsers come with so many encoding types, Unicode layers, legacy encoding sets, and numbering schemes for characters, its important you always assign a language used (lang="en-us" for US English). This then helps browsers and search engines interpret or "decode" your web page and its character sets better. It also helps them determine if they do not support a given language used in your web page. Because HTML 5 uses UTF-8 by default, it will support all of Unicode and a million or more text encodings and hundreds of language sets, emoticons, etc. used around the world. These browsers also are good at "sniffing" the language used. You can leave off the language attribute for that reason, but I do not recommend it, especially if your page is in a non-English speaking language. The reason is the characters used might not be supported in countries or browsers for some users. There may be mis-interpretations between closely aligned languages, as well. In XHTML, an "xml" version of the "lang" attribute was added and is also optional. I added it here so your pages are XHTML-friendly.
<head> - The 'head' element holds all the meta data for your page and any preprocessing of external files, styles, or scripts required by the page. These include all non-visual design elements in the web page.
<title> - The 'title' element appears directly under the parent 'head' element and should come first before all other elements. It is used by browsers to display the title of your web page in tabs, bookmarks, shortcuts, etc. in the browser. You may see your title appear in the browsers tab text, for example. It also is used by search engines in both their search application titles in search listings and also for determining keywords used in the page when they build page rank. If your website's title has text and keywords that also appear prominently in the subject matter of the web page (i.e. headings and text), then the 'title' element can assist in providing better search engine rankings for your page.
<meta> - "Meta tags" have been around since the 1990's and have changed over the years in type, variety, volume, function, and affect in websites. Because of these changes, the meta tags I have listed in the code above are all optional. None of them are required for your website to function. Only a few are highly recommended, though not critical. If you avoid using the handful that are required, you might see small, very minor effects in how your website is displayed or function in some devices, search engines, or browsers. But none are critical, in my opinion. I have listed the important ones I recommend you use, below:
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> This is the "version" of "charset" I recommend you use, though HTML 5 standards people say to use <meta charset="utf-8">. I disagree, as the first version above supports a wide range of old and new browsers. As mentioned, when you use the HTML 5 DOCTYPE mentioned above, the browser will assume your HTML 5 page uses UTF-8 Unicode encoding. But older browsers will not. So, adding this value here helps them more than newer browsers. Encoding is how a document is saved in terms of the numbers representing characters and the byte sequence used to store them in memory or in the saved document. Over time, we have moved from ASCII in 8-bit to Unicode which holds ASCII and over a million additional characters. But most software today does not default to saving in Unicode, so much of what is saved in HTML pages is still using older encoding. The good news is ASCII, or all the English numbers and characters, translates perfectly into HTML 5's UTF-8 unicode standard without any special requirements. It's when you start using foreign languages or special characters in web pages that you might see problems and might want to check how you encode your web pages. Because older browsers do not know HTML 5 and its UTF-8 default encoding platform, they will not know to use Unicode when translating your web page. That is why you need this special required meta tag. When using this "charset" tag, do remember to place it right after the 'title' element at the very top of your 'head' element (in first 1024 or 256 bytes of page byte code), as the earlier browsers see the encoding type, the faster they parse your page. Web Servers send text in blocks, so that explains the memory limit values and why its critical you send this in the first bit of code from the server. UTF-8 is always the standard for HTML 5 anyway, but this tag helps enforce that fact to all browsers and user agents that parse your web page. In most cases, as I describe in my "Best Practices" section below, browsers use a wide variety of techniques starting with HTTP headers from the server and BOM marks to "detect" what encoding HTML pages, CSS, and script files are encoded in. So, you should not worry too much about all that, as many inexperienced web developers try and convince you that you should.
<meta name="viewport" content="width=device-width, initial-scale=1.0,shrink-to-fit= no" /> This strange little meta tag is one of the rare cases recently where meta tags have made a small comeback to effect millions of web page layouts. I honestly thing it was a dumb idea to go back to old technology and use this. In most cases you still do not need this meta tag. This new "viewport" feature is used for various mobile device display settings, though most of this is controlled by either CSS or server side detection and reformatting via CSS. The "viewport" is not a new term but means any screen or monitor representing the user's visible web page area. It varies with the device and will be smaller on a mobile phone or tablet than on a computer screen. This meta tag gives the browser, and especially newer smart phones and tablets, instructions on how to control the page's dimensions and scaling relative to your HTML page. This is important, as some devices have settings that start out in a zoom mode, a direction, a width, or some scale that is not typical or the default. You always want to try and tell these devices or browsers to start with the "default" viewport settings. In the "content" settings above, I have chosen values I recommend you always use, as they basically "reset" the device or the browser on the device to start with a default width that matches the max width of the screen, turn off all scaling or zoom, set a 1:1 ratio as far as scale for your web page display, turn off "shrink-to-fit" web page features in iPhone Safari, and set all Internet Explorer browsers starting with IE7 to always use the "Web Standards" browser engine in those browsers, never the older "quirksmode" version, when displaying your site. I know there is a lot of stuff hidden in all these crazy settings and things you want to customize. But just try and trust my code above to help take care of a lot of the potential problems in all these various devices and browsers.
<meta name="keywords" content="keyword1, keyword2, keyword3" /> As mentioned in my meta tag "History" below, this keyword tag really carries very little weight when it comes to search engine ranking today. But adding specific keywords that are found in the body of your page text here (which follow the subject matter of your page and website), will enhance or rather help search engine performance, as indexing bots do read this meta tag.
<meta name="description" content="Your Web Page Description, author Your Name 2021" /> Add a description for your website here. As above, this is primarily used by search engines who may take this text and using the 'title' tag mentioned in this article, use them for the text they display in their search engine listing for your website. In that case, this element does give your tag some power over how its displayed in search engines. So, use it as much as possible in all pages. Make sure your description does have keywords from the keyword meta tag and 'title' sprinkled in.
<meta name="author" content="Your Name, https://yourwebsite.com/" /> This is a little-used meta tag that allows you to tell search bots and other indexing parsers who the author is of the web page and its content. This really does nothing important, but over time it may help identify you online as the source for critical information that over time has value to the world and is shared by millions of people online. Knowing who or what the source is of that information will be important later. This is an example where "meta data" matters and adds value, though this "author" information may not appear visibly in web browsers.
A note on the use of "cache control" using meta tags - I have added three types of cache control meta tags in my recommended code above: "pragma", "cache-control", and "expires". The settings above disable all caching, or try to, in the browser using the settings I have added. I will not cover their meaning or purpose here, except to say that different browsers in the past supported the three types shown here. So, I have added all three. This means, using these tags in older browsers should force them to NOT cache your website and its content and always get fresh data on every call to the server. However, this meta tag "cache" code does not work in most modern HTML 5 browsers today. So, do not rely on them. I do not recommend their use except for support of older browsers. That is why for them, I set these to no cache above. For over a decade, these "cache" settings in meta tags worked in many web browsers alongside server HTTP headers to tell browsers when to get fresh web page content and HTML from the server. Caching strategies on the server has been and still is a powerful tool to help browsers not only stay up-to-date on the latest content, but control how often they retrieve that content, saving bandwidth and time. The problem is, meta tag control of that has diminished over time. Today, these techniques rarely work or at the very least are not reliable. So, do not use these tags except as fall backs. Instead, rely on your web server settings when instructing browsers on how to cache your content.
There are numerous meta tags many developers swear by and which they say you must use in every web page. I may add those here over time. But for now, read my "History" of meta tags below for my "opinion" on why I recommend you never rely on meta tags and meta data in HTML going forward.
The History of Meta Tags: In the 1990's, i.e. the "old days", some meta data and their tags were critical in search engine rankings or in controlling features used in web browsers. Others were mandatory in helping browsers parse your page or display various features in your website. So, we adopted a large list of meta tags we would use and began exploring better ways to use meta data in enhancing our websites. After the 1990's, we were very careful in how we used meta tags and which ones were left off. The landscape for meta data was constantly changing back then. Hundreds of meta tags evolved after 2000 and grew to such variety and use that many developers abandoned any kind of consistent use of meta tags. As time progressed, the browsers began creating their own custom meta tags which they encouraged developers to use. But over time, browsers and search engines realized meta data would never replace HTML and good page content, so began to back away from requiring so much meta data. Because of this evolution after 2001, we stopped relying on meta tags for things like enhancing web page displays, refreshing, toolbars, image support, and search engine rankings. They just did not have as much influence over website design or function as before. Even search engines themselves stopped relying on meta tags and meta data, as the content and text in the page is what mattered as time went on. Meta tags "types" like "keywords" and "description" were still parsed and used by major search engines. But they no longer had the dramatic effects on search engine ranking and keywords as they once did in the 1990's. Fewer and fewer of the meta tags that controlled browser features kept working. Most were eventually abandoned. By the end of 2001, the promise of meta tags transforming the web had ended, and the "Golden Age of Meta Data" was gone.
The "wild west" fun days of meta tag use in web pages is now past. Most tags are rarely parsed or used by user agents or search engines. Most of the real utility tags no longer work. Most of the tricks used in meta tags to trigger browsers to do different things have been replaced with JavaScript. Truly helpful features like "meta refresh" tags that once forced browsers to cycle calls to the server for new content have stopped working or are no longer supported in browsers. Even control of page "charset" encoding values and keyword listings are often "sniffed" in other ways by browsers, assumed to be a default value if meta tags are missing, or determined by server HTTP headers or looked for in the 'body' section of web pages now. HTML, CSS, and JavaScript now dominate control of meta data through the use of new attributes like "data-" or microdata. Even "caching" web page schemes using meta tags no longer work reliably in newer browsers, which instead follow server HTTP header cache values, "sniff" URL changes, use cookies, or implement JavaScript API calls to determine caching now. So my point to you is, do not rely on meta tags to do much in 2021, as they once did 20 years ago. Instead, use good meta tag "mixes" of data in your web sites to "enhance" them, knowing most will affect very little in browsers today. Do rely on good, consistent meta tag use to guide search engines. But rely more on good content. Those search engines that do use your meta data can then get a better idea of what to expect in your pages or what you intended.
<body text="black" bgcolor="white"> - The 'body' element contains all your visible HTML elements and page content seen by users online. Anything that needs to be viewed or processed goes in the 'body' element, including some scripting blocks at the end, though the 'head' element is a better place to manage scripting. Note that like all the other elements listed in this section, 'body' is required to create an HTML web page. Note the addition of some "outdated" attributes I have added in my 'body' element above. I generally do not encourage you to use these, as they relate to 1998 browsers and old HTML4. The "text" and "bgcolor" attributes added above are not supported in HTML 5 today. Because I like all my pages to work in ALL web browsers, old and new, even old Netscape, I have added these here to support them. In some rare cases of very old Netscape series 4 browsers, they often defaulted to browser viewports with gray backgrounds and off-color text. Often, CSS or HTML would trigger Netscape to default to black backgrounds with black text, destroying usability. In those very rare cases I like to force Netscape to use black text on a white background using these old 'body' attributes. Know that they do no harm and are cascaded over by CSS in modern browsers when you apply style sheets with CSS properties in the 'body' selector.
If you want a full featured HTML 5 template with all the other HTML "goodies" included, like "external" CSS style sheets or JavaScript links used in this section, visit my section below called, "My Complete HTML 5 Template".
Notes on My Iframes Example: Notice I have wrapped the 'iframe' element with the new HTML 5 'figure' element, like I do with 'video' elements. This allows you to use the caption as a tool to add alternate video URL links. I have also added styles that allows the iframe to expand as the figure expands. It is often difficult to control the iframe size. For that reason stick with styles and use the 'figure' element to control 'iframe' sizes. I am also demonstrating use of a "about:blank" starting page with custom HTML for the source. You can also link to a blank HTML page. The added links inside 'figcaption' are optional and show how you can allow users to load other files, pages, or objects into your iframes. Remember, iframes are a security risk to many browsers, so you must limit its use unless you want to add the new "sandbox" or other security attributes, which I do not recommend at this time.