skip to content
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.

HTML5 Tutorial

HTML5 Element List

HTML5 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 HTML5 recommendations were released for review. Now here in 2022, we have fully embraced HTML5, CSS3, and all the newer changes coming on the horizon that advance better website technologies. However, the basic design of HTML5 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 HTML5, or which only partially support it. Without careful HTML design, you risk locking out millions of viewers from your website. As the HTML5'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 HTML5 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 HTML5 elements supported that are universal to most past and present HTML recommendations, and talk about items unique to HTML5 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 HTML5 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!

HTML5 Element Table
Element Name HTML Example
<a> anchor, link, hyperlink

Anchor

<a href="http://yourwebsite.com/" id="a1" title="View my Website" target="_blank" rel="noreferrer nofollow noopener" tabindex="0" aria-label="Your Website Link">A Hyperlink</a>
My Recommendations:
  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. The 'alt' attribute is not supported in anchors in XHTML and rarely in HTML5. 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.
  10. 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.
  11. 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.
  12. 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 HTML5 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 HTML5 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 HTML5 anchors, now you know why!
  13. 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.
  14. * 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:
  1. The 'abbr' element defines an inline abbreviation or acronym and shows a full text translation on rollover.
  2. 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:
  1. 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:
  1. 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.
  2. 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'.
  3. 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:
  1. 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.
  2. As usual, always include an 'id' and a 'title' on these click-able multimedia objects.
  3. 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.
  4. History: Prior to 2010 and the advent of HTML5, the 'applet', 'embed', and 'object' elements were used to display a wide range of multimedia objects in HTML including: Java 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 HTML5. 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. HTML5 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 HTML5 elements available ('video' and 'audio', for example).
  5. 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:
  1. 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 1
Article 2
Footer
* A typical web page structure is shown above.

My Recommendations:
  1. The 'article' element is new in HTML5 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 HTML5, the 'article' is part of a set of new structural page elements that define the overall layout of most HTML5 website pages designed today (<header>, <main>, and <footer>, etc.).
  2. The New HTML5 Structural Elements include: header, nav, main, footer, section, article, and aside.
  3. 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.
  4. 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 HTML5 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 HTML5 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.
  5. See the <main> element section for more details about this new HTML5 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:
  1. The 'aside' element is new in HTML5 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 HTML5, the 'aside' is part of a set of new structural page elements that define the overall layout of most HTML5 website pages designed today (<header>, <main>, and <footer>, etc.).
  2. The New HTML5 Structural Elements include: header, nav, main, footer, section, article, and aside.
  3. 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".
  4. 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 HTML5 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 HTML5 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.
  5. See the <main> element section for more details about this new HTML5 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>
"Rain Sounds" [CC BY-SA 3.0] , via Wikimedia Commons

(If your browser supports the audio element above you should see an audio control and hear a rain sound when playing.)

My Recommendations:
  1. The 'audio' element is a new HTML5 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).
  2. 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.
  3. As always give your element an 'id' for script control and a 'title' attribute to tell users what the audio control will do.
  4. The 'src' attribute in 'source' elements must point to a valid audio file or the audio controls will not play a file when pressed.
  5. 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.
  6. 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.
  7. 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.
  8. 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!
  9. 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.
  10. 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.
  11. 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.
  12. CSS styling of the audio control is difficult if not impossible, so realize there is limited support for designing audio controls.
  13. 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.
  14. I recommend use of the new HTML5 '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:
  1. The 'b' element defines a piece of "bold" text.
  2. 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.
  3. 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:
  1. 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.
  2. 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!
  3. '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.
  4. 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.
<basefont> basefont

Basefont

<basefont color="#000000" face="Verdana" size="+2" />
My Recommendations:
  1. 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 HTML5, as it was a design element only.
  2. 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:
  1. 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 HTML5, but sadly has no support in any Internet Explorer or in a few others. So, I do not recommend its use. Use <bdo> instead.
  2. 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.
  3. The sibling element 'bdo' works the same but reverses the text direction.
  4. 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:
  1. 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>).
  2. 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.
  3. 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.
  4. The sibling element 'bdi' works the same as 'bdo' but isolates the text direction without changing its current text direction.
  5. 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:
  1. The 'big' element was used to show larger text in an inline block of text.
  2. 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.
<bgsound> background sound

Background Sound

<bgsound source="birdsounds.wav" loop="true" volume="20" />

My Recommendations:
  1. The 'bgsound' element is deprecated now but was a non-standard HTML tag that was used to play a small audio file in the background of a web page (often a .wav or .mp3 audio file). This element was a non-standard element, proprietary to browsers like old Internet Explorer v.5, and no longer supported in HTML5 browsers. At one time it was fun to use in older websites (pre-2001). But over time, it was not good useability to play music in web pages in which a user could not control the audio playback or volume. Besides, it is unlikely to work in modern browsers today as it has never been a part of the evolving HTML5 standards. Do not use <bgsound>. If you need sound in your website, use the <audio> element instead.
<blink> blink

Blink

<blink style="color:green;">This is some text that should flash on and off, if supported</blink>
This is some text that should flash on and off, if supported
My Recommendations:
  1. 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:
  1. 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.
  2. The 'cite' attribute is used to define an online source for the quoted text and its web page.
  3. Always use 'blockquote' for larger separate blocks of text and 'q' for smaller inline quoted text.
<body> body

Body

see <html>
My Recommendations:
  1. The 'body' element defines the main content area of a web page. See the <html> element for a full description.
<bq> bq, block quotes

Block Quotes

<bq>
  <p>Quoted text goes here</p>
  <credit>Credit source text goes here</credit>
</bq>

Quoted text goes here

Credit source text goes here
My Recommendations:
  1. The 'bq' element is a deprecated tag from old HTML3 once supported in Internet Explorer 2 (1990s). It was used to display an early form of an extended block quote, which included a quotation text block and a 'credit' element for a quote source. This element was discontinued following adoption of <q>, <blockquote>, and <cite> elements. It is not part of HTML5. Do not use the 'bq' element.
<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:
  1. 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.
  2. 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% HTML5/XML/XHTML/XHTML5 compatible, while the other forms are not.
<button> button

Button

see <form> for more details using <button> in forms

A Button can "submit" Form Data

<form id="buttonform1" name="buttonform1" action="#" method="get" aria-label="Button Submit Form" title="Button Submit Form" autocomplete="off" autocapitalize="off" spellcheck="false">
<p>
  <label for="buttonexample_username" title="Username">&nbsp;<abbr title="required" aria-label="required">*</abbr>&nbsp;Username</label>
  <input type="text" id="buttonexample_username" name="buttonexample_username" value="" size="20" maxlength="20" title="Username" tabindex="0" autocomplete="username" autocapitalize="off" autocorrect="off" spellcheck="false" required="required" aria-required="true" aria-label="Username" />
</p>
<p>
  <label for="buttonexample_password" title="Password">&nbsp;<abbr title="required" aria-label="required">*</abbr>&nbsp;Password</label>
  <input type="password" id="buttonexample_password" name="buttonexample_password" value="" size="20" maxlength="20" title="Password" tabindex="0" autocomplete="new-password" autocapitalize="off" autocorrect="off" spellcheck="false" required="required" aria-required="true" aria-label="Password" />
</p>
  <button id="buttonexample_button1" name="buttonexample_button1" type="submit" value="submit" form="buttonform1" title="Submit" tabindex="0" aria-label="Submit">Submit</button>
</form>


A Button can send Name-Value Pairs Using the Same "name" Attribute

<form id="buttonform2" name="buttonform2" action="#" method="get">
  <button id="button2a" name="fruit" type="submit" value="apple" form="buttonform2" aria-label="Apple Button" title="Apple Button" tabindex="0" style="min-width:10em;">Apple</button><br />
  <button id="button2b" name="fruit" type="submit" value="pear" form="buttonform2" aria-label="Pear Button" title="Pear Button" tabindex="0" style="min-width:10em;">Pear</button>
</form>


A Button can also be a "Reset" Type, a Plain "Button" Type (no form submission), or "Disabled"

<form id="buttonform3" name="buttonform3" action="#" method="get">
<p>
  <label for="buttonname3" title="My Form Field">My Form Field</label>
  <input type="text" id="name3" name="buttonname3" value="" size="20" maxlength="20" title="name" tabindex="0" />
</p>
  <button id="button3a" name="button3a" type="reset" value="reset" form="buttonform3" title="Reset" tabindex="0" aria-label="Reset" style="min-width:10em;">Reset</button><br />
  <button id="button3b" name="button3b" type="button" value="plainbutton" form="buttonform3" title="Plain Button" tabindex="0" aria-label="Plain Button" style="min-width:10em;">A Plain Button</button><br />
  <button id="button3c" name="button3c" type="button" value="disabledbutton" form="buttonform3" title="Disabled Button" tabindex="-1" aria-label="Disabled Button" disabled="disabled" aria-disabled="true" style="min-width:10em;">A Disabled Button</button>
</form>




My Recommendations:
  1. 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".
  2. 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.
  3. 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.
  4. 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.
  5. 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. Also, in form fields the 'name' attribute is often parsed first as it is used when building name-value form field key-value pair data system sent to the server on submit. So, be sure to give each 'name' a unique value, match the unique name to the 'id' element, and be sure to put both first in the element!
  6. 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.
  7. 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.
  8. 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!
  9. 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.
  10. 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.
  11. 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.
  12. 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.
  13. 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.
  14. 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.
  15. "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).
  16. 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.
  17. 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.
  18. 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!


  19. 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.
  20. 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 HTML5, so is totally safe to use.
<caption> caption, table caption

Caption

<table style="border: 1px solid black;border-collapse: collapse;border-spacing: 0px;padding: 10px;vertical-align: top;">
  <caption style="color:blue;font-weight:bolder;">Your Table Caption Appears Here</caption>
  <thead>
    <tr>
      <th>header cell title</th>
      <th>header cell title</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>body cell text here...</td>
      <td>body cell text here...</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>footer cell text here...</td>
      <td>footer cell text here...</td>
    </tr>
  </tfoot>
</table>

Your Table Caption Appears Here
header cell title header cell title
body cell text here... body cell text here...
footer cell text here... footer cell text here...
My Recommendations:
  1. 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.
  2. 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:
  1. 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 HTML5 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>
Sorry, your browser does not support the new HTML5 canvas object.

(The JavaScript used above in rendering this image is from the standard "Canvas Scripting API")

My Recommendations:
  1. The 'canvas' element is new to HTML5 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).
  2. 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.
  3. 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 HTML5.
  4. 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:
  1. 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.
  2. Cited text is usually in italics.
<code> code, computer code

Code

<code>
  &lt;p&gt;Here is my sample paragraph using HTML with the 'code' element&lt;/p&gt;
</code>
<p>Here is my sample paragraph using HTML with the 'code' element</p>
My Recommendations:
  1. 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.
  2. 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 "&lt;") to show you how that is done.
<col> column

Column

see <colgroup> and <table>

<table id="coltable1">
  <caption>My Table 'col' Example</caption>
  <colgroup>
    <col span="2" style="background-color: lightblue;" />
    <col style="background-color: lightyellow;" />
  </colgroup>
  <thead>
    <tr>
      <th style="width:auto;">header 1</th>
      <th style="width:auto;">header 2</th>
      <th style="width:auto;">header 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>body 1</td>
      <td>body 2</td>
      <td>body 3</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>footer 1</td>
      <td>footer 2</td>
      <td>footer 3</td>
    </tr>
  </tfoot>
</table>

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:
  1. 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.
  2. 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.
  3. CSS Support: 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.
  4. Non-Browser Support: 'col' was never supported by the old Netscape 4 Series browsers between 1999-2001 when the browser wars were going on with Internet Explorer 4 and 5. So, by default 'col' was rarely used by most developers then, which continues till today.
  5. 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.)
<colgroup> column group

Column Group

see <col> and <table>

<table id="coltable2">
  <caption>My Table 'col' Example</caption>
  <colgroup>
    <col span="2" style="background-color: lightblue;" />
    <col style="background-color: lightyellow;" />
  </colgroup>
  <thead>
    <tr>
      <th style="width:auto;">header 1</th>
      <th style="width:auto;">header 2</th>
      <th style="width:auto;">header 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>body 1</td>
      <td>body 2</td>
      <td>body 3</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>footer 1</td>
      <td>footer 2</td>
      <td>footer 3</td>
    </tr>
  </tfoot>
</table>

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:
  1. 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'.
  2. 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.
  3. 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.
  4. 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.)
<credit> credit

Credit

<bq>
  <p>Quoted text goes here</p>
  <credit>Credit source text goes here</credit>
</bq>

Quoted text goes here

Credit source text goes here
My Recommendations:
  1. The 'credit' element is a deprecated tag from old HTML3 once supported in Internet Explorer 2 (1990s). It was used to display credit for a quote of text. This element was discontinued following adoption of <q>, <blockquote>, and <cite> elements. It is not part of HTML5. Do not use the 'credit' element.
<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

  1. This is Product #1
  2. This is Product #2
  3. This is Product #3
My Recommendations:
  1. 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.
  2. 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.
  3. 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.
  4. Use the 'time' element instead if the data is time-based.
  5. 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.)
  6. 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.
<datalist> datalist

Datalist

<form id="datalistform1" name="datalistform1" action="#" method="get">
  <label for="datalistname1" title="My Datalist">Double-lick to Choose a Browser from The Datalist:</label>
  <br />
  <input type="text" id="datalistname1" name="datalistname1" value="" size="20" maxlength="20" title="Double-click to Choose" aria-label="Browser" tabindex="0" list="browserlist" placeholder="Double-click to choose..." />
  <datalist id="browserlist" title="Browser List" aria-label="Browser List" role="listbox">
    <option value="Internet Explorer"></option>
    <option value="Firefox"></option>
    <option value="Chrome"></option>
    <option value="Opera"></option>
    <option value="Safari"></option>
  </datalist>
  <button id="datalistbutton1" name="datalistbutton1" type="submit" value="submit" form="datalistform1" title="Submit" tabindex="0" aria-label="Submit">Submit</button>
</form>

My Recommendations:
  1. The 'datalist' element is new in HTML5 and allows you to assign a select dropdown list to a input "text" box and narrow a user's choice of values. Currently in 2022, few of the new web browsers (and none of the old) consistently support 'datalist'. Therefore, its use is not recommended.
  2. 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.
  3. 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.
  4. The datalist works with number, date, email and other input types.
  5. ARIA: You should always set an "aria-label" to tell screen readers what action to take on this new HTML5 element. Also, I recommend you add role="listbox", as its not clear that this new feature provides a list. This assists screen readers.
  6. 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 HTML5 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:
  1. 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:
  1. 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.
  2. 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.


<details id="detailsexample1">
  <summary style="background-color: #ccccccff;box-shadow: 2px 2px 3px #aaa;">&copy; Copyright 2022</summary>
  <div style="margin:0;padding:.2em 1em;background-color: #efefef;box-shadow: 2px 2px 3px #aaa;">
    <p>Owned by Company ABC. All Rights Reserved.</p>
    <p>All content and graphics on this web site are the property of Company ABC.</p>
  </div>
</details>
© Copyright 2022

Owned by Company ABC. All Rights Reserved.

All content and graphics on this web site are the property of Company ABC.


My Recommendations:
  1. The 'details' element is new interactive element in HTML5 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.
  2. 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.
  3. 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.
  4. Always add a unique 'id' to the 'details' hidden element so it can be manipulated by scripts.
  5. 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 HTML5 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.
  6. 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 HTML5, They also should see the 'summary' and 'details' element text quite easily without any added interactions.
  7. 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.
  8. 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>

Learn more about the Sun

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">HTML5</abbr></dfn> is the fifth version of the standard markup language used in creating web pages.</p>

HTML5 is the fifth version of the standard markup language used in creating web pages.

My Recommendations:
  1. 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.
  2. The 'title' element can be added to a 'dfn' tag to provide an additional definition text on rollover. See example above.
  3. 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.
  4. 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.
  5. 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" HTML5 dialog box)


<div id="dialogbox_alt" role="dialog" aria-label="Alternate Dialog">
<dialog id="dialogbox" aria-label="Dialog" style=" display:none;
width: 20em;
min-height: 15em;
max-width: 50%;
padding: 1em;
background-color: #fff;
border: 2px solid #999;
border-radius: .5em;
/* center all dialogs */
position: fixed;
top: 50%;
left: 50%;
margin-left: -10em;
margin-top: -5em;
z-index: 99;
/* create background screen */
box-shadow: 0 0 0 9999px rgba(0,0,0,0.6);
">
<form id="formdialog1" action="#" method="get" style="position:relative;
width:100%;
height:100%;
padding:0;
margin:0;">
<span id="dialogcloser" style="display:inline-block;
cursor:pointer;
padding:.2em;
position:absolute;
top:-5px;
right:-5px;">X</span>
<div style="padding:1em;">
<p>
<label for="animals1" title="Animals">&nbsp;*&nbsp;Choose an Animal:</label>
<select id="animals1" name="animals1" size="1" required="required" aria-required="true" aria-label="List of Animals" tabindex="0">
<option value="" selected="selected">- choose an animal -</option>
<option value="elephant">Elephant</option>
<option value="zebra">Zebra</option>
<option value="lion">Lion</option>
</select>
</p>
<p>
<button type="submit" name="dialogconfirm" value="confirm">Confirm</button>
</p>
</div>
</form>
</dialog>
</div>
<button id="dialogopener" type="button">Open A Dialog Box</button>



My Recommendations:
  1. The 'dialog' element represents a dialog box/modal/window/popup/interactive box that is new in HTML5 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 HTML5 'dialog' element is JavaScript-dependent, is not supported in many modern HTML5 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.
  2. Add the 'id' attribute to this element so it can be accessed by scripts and styled.
  3. 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.
  4. 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 HTML5 "living" standards. UPDATE (11/2022): Updates to the 'dialog' element in WebKit browsers like Chrome recently changed this form method feature, so method="dialog" fails to submit HTML form data! Do not use method="dialog", but a plain form method like POST or GET.
  5. 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"

    1. "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.
    2. 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.
    3. 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.
    4. 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!
    5. 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 HTML5 guys had designed a dialog "button/box" combo you could customize instead. Then we would not need all of the above!
  6. 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.
  7. 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 HTML5 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.
<dir> directory, directory list

Directory

<dir>
  <li>Directory Item #1</li>
  <li>Directory Item #2</li>
</dir>
  • Directory Item #1
  • Directory Item #2
  • My Recommendations:
    1. The 'dir' element defines a directory list. It was designed to create multi-column directory lists in old HTML4, but has been deprecated. Do not use the 'dir' element as it has been deprecated in HTML5. 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:
    1. 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.
    2. 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.
    3. '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.
    4. 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 HTML5 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>

      <dt id="cat1">Cat</dt>
      <dt>Kitty</dt>
      <dd aria-labelledby="cat1">Our feline friends</dd>
    </dl>
    Dog
    Puppy
    Mutt
    Man's best friend
    Cat
    Kitty
    Our feline friends

    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:
    1. 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. HTML5 now supports it.
    2. 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).
    3. 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'.
    4. 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'.
    5. 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 HTML5 and I do not recommend its use. Use CSS styles instead.
    6. 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.
    7. 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:
    1. 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.
    <doctype> doctype definition

    Doctype

    see <html>
    My Recommendations:
    1. The 'doctype' element defines the doctype definition of a web page. See the <html> element for a full description.
    <em> emphasis

    Emphasis

    <p>This text has <em>emphasis</em>.</p>

    This text has emphasis.

    My Recommendations:
    1. 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.
    2. 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 HTML5, 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.
    3. 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" loop="false" 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>
    Your browser does not support this media object or the embed element.

    (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:
    1. 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 HTML5 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 HTML5 media types. More details below.
    2. 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.
    3. Deprecated Attributes: There are many old attributes used by 'embed' by browsers of the past that may not work. I have listed the ones below I recommend you avoid: bgcolor, hspace, palette, pluginspage, pluginspace, quality, salign, scale, vspace. Note: I have added the "loop=false" attribute to the code above, though it is likely not supported in modern HTML5 browsers today. But it prevents some older browsers from repeating video playback in a loop forever.
    4. As usual, always include an 'id' and a 'title' on these click-able multimedia objects. The 'title' tooltip might not show up on rollover but in some browsers may appear.
    5. 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.
    6. In older pages you may see a strange attribute (not used in HTML5) 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.
    7. Add autoplay="false" to stop videos from automatically playing when the browser loads. Also, some browsers interpret the presence of the 'autoplay' attribute as a boolean 'true' regardless if you set it to 'false'. So remove it completely if that is the case. Never use 'autoplay' without a true/false as it fails in XHTML5/XML parsers.Warning: Videos automatically play in some modern browsers using 'embed' regardless of setting autoplay! 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.)
    8. Use of the 'noembed' element: Today, in HTML5, 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.
    9. 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 HTML5. 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 HTML5-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.
    10. History: Prior to 2010 and the advent of HTML5, the 'applet', 'embed', and 'object' elements were used to display a wide range of multimedia objects in HTML including: Java 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 HTML5 '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 HTML5, 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. HTML5 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 HTML5, use the newer HTML5 elements and media types available ('img', 'picture, 'iframe', 'video', and 'audio' using MPEG4, WebM, etc.).
    11. 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 HTML5'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 HTML5".
    12. 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.
    13. Warning: Use CSS to set custom 'width' and 'height' using 'embed' in supporting newer HTML5 browsers, as the attribute version may not honor the dimensions you set. (see my example above)
    14. 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 HTML5 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.
    15. See my article below called "How to Create a Cross-Browser Video in HTML5" 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.
    <fieldset> fieldset

    Fieldset

    see <legend>

    <form id="fieldsetform" name="fieldsetform" action="#" aria-label="Login" title="Login">
    <fieldset id="fieldset1" name="fieldset1" form="fieldsetform">
    <legend style="background-color: #ccc;color: #fff;">Login</legend>
    <p>
    <label for="fieldsetinput1" title="Username">Username:</label>
    <input type="text" aria-label="Username" id="fieldsetinput1" size="20" maxlength="10" value="" title="Username" tabindex="0" />
    </p>
    <p>
    <label for="fieldsetinput2" title="Password">Password:</label>
    <input type="password" aria-label="Password" id="fieldsetinput2" size="20" maxlength="10" value="" title="Password" tabindex="0" />
    </p>
    <p><button id="fieldsetsubmit1" aria-label="Submit" aria-pressed="false" title="Login" tabindex="-1" disabled="disabled" aria-disabled="true">Login</button></p>
    </fieldset>
    </form>

    * Note: The box around the form fields is the 'fieldset'. The "login" text is the fieldset's 'legend'.
    Login

    My Recommendations:
    1. 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.
    2. The 'fieldset' element supports a number of attributes, including 'form' to connect the fieldset with its parent form element's 'id'.
    3. 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.
    4. 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!
    5. 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.
    6. 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!)
    7. 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.

      Old Browsers Only - Fieldset Design

      
      fieldset {
          display: block;
          width: auto;
          height: auto;
          padding: 8px 16px 16px 16px;
          margin: 8px 0px;
          background-color: transparent;
          /*/*//*/background-color: white;/*end*/
          border: 2px solid #bbbbbb;
      }
      

      Modern Browsers Only - Fieldset Design

      
      fieldset {
      	display: block;
      	width: auto;
      	height: auto;
      	max-width: 100%;
      	padding: .5em 1em 1em 1em;
      	padding: .5rem 1rem 1rem 1rem;
      	margin: .5em 0em;
      	margin: .5rem 0rem;
      	border-radius: .2em;
      	border-radius: .2rem;
      	background-color: #f3f3f3;
      	border: 2px solid #bbb;
      }
      
    8. Browser Support: 'fieldset' has wide support in nearly all browsers, old and new. So, it is fully supported.
    <fig> fig, figures

    Figures

    The <fig> element is a lost relic from old HTML 3.0 (1995). It is no longer supported, but oddly was redesigned back into HTML5's 'figure' element.


    <fig src="cat.jpeg" align="left">
      <caption>My cat's name is 7-Up!</caption>
      <p>My cat loves fish and to roam outside after his meal.</p>
      <credit>Cat Daddy wrote this!</credit>
    </<fig>
    My Recommendations:
    1. The 'fig' element or figures, is now fully deprecated. It represented a "figure caption" element in old HTML 3.0 (1995) which contained text and images around which web page content would flow. The 'fig' element has inspired the current HTML5 'figure' and 'figcaption' elements used in modern web pages today. For that reason, Do not use the 'fig' element as it has been discontinued. Use the 'figure' and 'figcaption' instead.
    <figcaption> figure caption

    Figure Caption

    see <figure>
    My Recommendations:
    1. The 'figcaption' element defines a title or "figure caption" for a visual object. See 'figure' below.
    <figure> figure

    Figure

    <figure style="padding: .5rem;border:1px solid #bbb;background: #f0f0f0;width: auto;height: auto;display: inline-block;" aria-labelledby="myfigureimage">
      <img id="figureimage" src="www.jpg" width="255" height="200" alt="image:World Wide Web" title="World Wide Web Image" onerror="this.onerror=null;" loading="lazy" />
      <figcaption id="myfigureimage" style="text-align:center;display:block;">This is the <cite>World Wide Web!</cite></figcaption>
    </figure>

    * 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).

    image:World Wide Web
    This is the World Wide Web!
    My Recommendations:
    1. 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 HTML5 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.
    2. 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.
    3. 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.
    4. 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"
    5. 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.
    6. Browser Support: 'figure' is new in HTML5 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 HTML5 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,
    7. 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:
    1. 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 HTML5 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.
    2. 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
    Footer
    * A typical web page structure is shown above.
    My Recommendations:
    1. The 'footer' element is new in HTML5 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 HTML5, the 'footer' is part of a set of new structural page elements that define the overall layout of most HTML5 website pages designed today (<header>, <main>, and <footer>, etc.).
    2. The New HTML5 Structural Elements include: header, nav, main, footer, section, article, and aside.
    3. 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".
    4. See the <main> element section for more details about this new HTML5 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.


    <form id="f1" name="f1" method="post" action="#" title="Form Example" aria-label="Form Example" autocomplete="off" autocapitalize="off" spellcheck="false">
    <fieldset id="f1_fieldset" name="f1_fieldset" form="f1">
    <legend style="background-color:#999;color: #fff;">Form Example</legend>
    <fieldset id="f1_fieldset_1" name="f1_fieldset_1" form="f1">
    <legend style="background-color: #aaa;color: #fff;">Text Example</legend>
    <p>You can add plain text inside a form.</p>
    </fieldset>
    <fieldset id="f1_fieldset_2" name="f1_fieldset_2" form="f1">
    <legend style="background-color: #aaa;color: #fff;">Login with Submit</legend>
    <div>
    <input type="text" id="f1_username" name="f1_username" size="20" value="" autocomplete="username" autocapitalize="off" autocorrect="off" spellcheck="false" tabindex="0" placeholder="Enter username here..." title="Enter Username" aria-label="Username" required="required" aria-required="true" />&nbsp;*&nbsp;
    </div>
    <div>
    <input type="password" id="f1_password" name="f1_password" size="20" minlength="8" maxlength="12" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,12}" value="" autocomplete="new-password" autocapitalize="off" autocorrect="off" spellcheck="false" tabindex="0" placeholder="Enter password here..." title="Enter Password: (8-12) characters, must contain one number, one uppercase and lowercase letter" aria-label="Password" required="required" aria-required="true" />&nbsp;*&nbsp;
    </div>
    <div>
    <button id="f1_login" name="f1_login" value="Login Submit" title="Login" aria-label="Login" aria-pressed="false" tabindex="0" form="f1">Login</button>
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_3" name="f1_fieldset_3" form="f1">
    <legend style="background-color: #aaa;color: #fff;">Checkboxes</legend>
    <p>Which colors do you like?</p>
    <div>
    <input type="checkbox" id="f1_checkboxgreen" name="f1_checkboxgroup" "autocomplete=off" value="green" title="green" aria-label="green" aria-checked="false" tabindex="0" />
    <label for="f1_checkboxgreen" title="Green" style="color:green;">Green</label>
    </div>
    <div>
    <input type="checkbox" id="f1_checkboxred" name="f1_checkboxgroup" "autocomplete=off" value="red" title="red" aria-label="red" aria-checked="true" tabindex="0" checked="checked" />
    <label for="f1_checkboxred" title="Red" style="color:red;">Red</label>
    </div>
    <div>
    <input type="checkbox" id="f1_checkboxblue" name="f1_checkboxgroup" "autocomplete=off" value="blue" title="blue" aria-label="blue" aria-checked="false" tabindex="0" />
    <label for="f1_checkboxblue" title="Blue" style="color:blue;">Blue</label>
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_4" name="f1_fieldset_4" form="f1">
    <legend style="background-color: #aaa;color: #fff;">Radio Buttons</legend>
    <p>Choose A Favorite Pet</p>
    <div>
    <input type="radio" id="f1_dog" name="f1_radiogroup" "autocomplete=off" value="dog" title="dog" aria-label="dog" aria-checked="false" tabindex="0" />
    <label for="f1_dog" title="Dog">Dog</label>
    </div>
    <div>
    <input type="radio" id="f1_cat" name="f1_radiogroup" "autocomplete=off" value="cat" title="cat" aria-label="cat" checked="checked" aria-checked="true" tabindex="0" />
    <label for="f1_cat" title="Cat">Cat</label>
    </div>
    <div>
    <input type="radio" id="f1_bird" name="f1_radiogroup" "autocomplete=off" value="bird" title="bird" aria-label="bird" aria-checked="false" tabindex="0" />
    <label for="f1_bird" title="Bird">Bird</label>
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_5" name="f1_fieldset_5" form="f1">
    <legend style="background-color: #aaa;color: #fff;">Textarea</legend>
    <div>
    <textarea id="f1_textarea" name="f1_textarea" title="Textarea" aria-label="Textarea" tabindex="0" contenteditable="true" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="true" maxlength="200">Enter your text here...</textarea>
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_6" name="f1_fieldset_6" form="f1">
    <legend style="background-color: #aaa;color: #fff;">File Upload</legend>
    <div>
    <input type="file" id="f1_fileupload" name="f1_fileupload" title="Multiple File Upload" aria-label="Multiple File Upload" tabindex="0" enctype="multipart/form-data" accept="image/*" multiple="multiple" aria-multiselectable="true" />
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_7" name="f1_fieldset_7" form="f1">
    <legend style="background-color: #aaa;color: #fff;">Select List</legend>
    <div>
    <select id="f1_select" name="f1_select" title="Select List" aria-label="Select List" multiple="multiple" size="6" aria-multiselectable="true" tabindex="0">
    <option value="" selected="selected">-- select an option --</option> <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
    <option value="4">four</option>
    <option value="5">five</option>
    <option value="6">six</option>
    <option value="7">seven</option>
    <option value="8">eight</option>
    <option value="9">nine</option>
    <optgroup label="ten to twenty" role="group">
    <option value="10">ten</option>
    <option value="20">eleven</option>
    </optgroup>
    </select>
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_8" name="f1_fieldset_8" form="f1" >
    <legend style="background-color: #aaa;color: #fff;">Hidden Inputs</legend>
    <div>
    <input type="hidden" id="f1_hidden1" name="f1_hidden1" value="one" aria-hidden="true" tabindex="-1" />
    <input type="hidden" id="f1_hidden2" name="f1_hidden2" value="two" aria-hidden="true" tabindex="-1" />
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_9" name="f1_fieldset_9" form="f1" >
    <legend style="background-color: #aaa;color: #fff;">Image Button</legend>
    <div>
    <input type="image" src="yourimagebutton.gif" id="f1_imagebutton" name="f1_imagebutton" alt="Image Button" title="Image Button" aria-label="Image Button" tabindex="0" form="f1" style="border:2px solid #bbb;" />
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_10" name="f1_fieldset_10" form="f1" >
    <legend style="background-color: #aaa;color: #fff;">Reset, Disabled, and Read-only</legend>
    <div>
    <input type="reset" id="f1_resetinput" name="f1_resetinput" value="Reset Button" title="Reset Button" aria-label="Reset Button" tabindex="0" form="f1" />
    </div>
    <div>
    <input type="submit" id="f1_disabledinput" name="f1_disabledinput" value="Disabled Button" title="Disabled Button" aria-label="Disabled Button" disabled="disabled" aria-disabled="true" tabindex="-1" form="f1" />
    </div>
    <div>
    <input type="text" id="f1_readonlyinput" name="f1_readonlyinput" size="20" maxlength="20" value="This is Read-only Text" readonly="readonly" autocomplete="off" tabindex="-1" title="Read-only Text" aria-label="Read-only Text" />
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_11" name="f1_fieldset_11" form="f1" >
    <legend style="background-color:#aaa;color:#fff;">Plain Buttons</legend>
    <div>
    <input type="button" id="f1_plaininputbutton" name="f1_plaininputbutton" value="Plain 'Input' Button" title="Plain 'Input' Button" aria-label="Plain 'Input' Button" tabindex="0" form="f1" />
    </div>
    <div>
    <button type="button" id="f1_plainbutton" name="f1_plainbutton" value="Plain 'Button' Button" title="Plain 'Button' Button" aria-label="Plain 'Button' Button" tabindex="0" form="f1">Plain 'Button' Button</button>
    </div>
    </fieldset>
    <fieldset id="f1_fieldset_12" name="f1_fieldset_12" form="f1" >
    <legend style="background-color: #aaa;color: #fff;">Submit Buttons</legend>
    <div>
    <input type="submit" id="f1_inputsubmit" name="f1_inputsubmit" value="Input Submit" title="Input Submit" aria-label="Input Submit" tabindex="0" form="f1" />
    </div>
    <div>
    <button type="submit" id="f1_buttonsubmit" name="f1_buttonsubmit" value="Button Submit" title="Button Submit" aria-label="Button Submit" tabindex="0" form="f1">Button Submit</button>
    </div>
    </fieldset>
    </fieldset>
    </form>
    Form Example

    Form Example

    This is an example of a single form. It has multiple sections defined by 'fieldset' elements which contain different types of inputs, buttons, and content. The form contains a master fieldset which holds all its child fieldsets. Each child holds one example of all the main types of form field controls that can be used in a typical web form. Placing your form fields inside fieldset sections like this allows you to control how parts of your form are filled out and submitted. We could have used multiple form elements, each one wrapped around a single fieldset below, with their own submission button. This would allow each form section to submit its control data to the server separate from the others. Instead, I have created one master form below, which contains multiple sections of fields and their controls, which all get submitted as one. This means any submit button below would submit all the fieldsets as one batch when pressed.

    Text Example

    You can add plain text inside a form.

    Login with Submit

    This is a common use for 'form' elements: Logins. Note the clean, simple design below. You can add more features like "forgot password", "register" links, and elaborate JavaScript techniques. Notice that you should always use the <label> element and its 'for' attribute assigned to the 'input' element's 'id' value. This associates the label with its sibling form field. Also add a 'title' attribute to every label with a description of the form element associated with the label. This improves usability. Ive added a general "submit" button which would submit this data and every other form field below (inside the 'form' element) to the server. The inputs have a few extra attributes, like autocomplete, ARIA labels, maxlength, title, and others I will go over in more detail under 'input' in this HTML5 list.

     * 
     * 
    Checkboxes

    Which colors do you like?

    Radio Buttons

    Choose A Favorite Pet

    Textarea

    The Textarea allows users to submit larger volumes of text. Notice I have added "spellcheck" which means in newer browsers, as you type, any bad spelling added to the textarea box will now have a squiggly line under it.

    File Upload

    Note that "File Upload" controls typically need their own 'form' element and a special 'enctype' attribute added. They usually are also sent to the server with a 'form' attribute of "enctype=multipart/form-data". I have added it to the file upload element instead of the form. I have also customized this file upload element to only allow the user to choose common image formats only for the file upload type. And this version supports multiple file uploads. Note that IE9 and many earlier browsers don't support multiple file uploads.

    Select List

    A select list is also called a "dropdown list" to some. You can set a single select or add the "multiple=multiple" attribute to support multiple choices, as I've done below. I am also using "optgroup" in the 'select' element below to show how items can be grouped, and I have set the "size" or number of items to display to "6".

    Hidden Inputs

    You cannot see these "hidden" input controls as they are not visually shown to the user. These are often used to store "user settings", sessions, cookie info, or other alphanumeric data that needs to be pushed between the server and the user, back and forth. You can also set these special inputs to "disabled". (code shown below)

    <input type="hidden" id="f1_hidden1" name="f1_hidden1" value="one" aria-hidden="true" tabindex="-1" />
    <input type="hidden" id="f1_hidden2" name="f1_hidden2" value="two" aria-hidden="true" tabindex="-1" />
    Image Button

    Note that the "image" button is actually just an <input> element with a "type=image" attribute. They act like "submit" type buttons and will submit all form data as a regular "submit" type input button does. Besides the 'input' element, the 'button' element can also use images as a background and act like an 'image' button. It would not have an 'image' type attribute, just wrap an image with its tags, and use "type=submit".

    Reset, Disabled, and Read-only

    Use the "type=reset" attribute on buttons to create a "reset" button that clears out all fields in a form. Add the "disabled="disabled" attribute on buttons to disable a button and prevent it from posting data back to the server. Add the "readonly=readonly" field for text boxes that have values that are submitted to the server, can be read, but cannot be changed by the user.

    Plain Buttons

    Note that these plain buttons do NOT submit data or do anything without the help of JavaScript!

    Submit Buttons

    "Submit" buttons are default button types used by most browsers to submit all form field data values entered by users back to the server for processing. If you add an 'input' element of "type=submit" it will be a submit button. The "type=image" setting is also a "submit" button for inputs. A 'button' element without 'type' is a "submit" type by default, as well. Setting its "type=submit" is usually what most developers use to make sure it is explicit. Both 'input' and 'button' elements work the same as far as being "submit" type buttons, and post all form field data to the server when pressed.

    My Recommendations:
    1. 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.
    2. 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).
    3. 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.
    4. 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:
      1. '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'.
      2. method="get" - This attribute is the default value and optional. It 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. Note: Do NOT send type="password" form fields using the default "get" value. Use "post" instead so your password is not shipped over the Internet in full view in the URL string sent to the server. Old browsers struggled with how form data was sent to the server. Example, Internet Explorer v5 would add "+" signs to the spaces in the form field URL string on submission. Often "method=post" is a better, more secure way to fix these issues.
      3. 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, which then defaults to the same url as the form page. 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. Note: In the old days we would send form results to an email using a "mailto:email@example.com".
      4. autocomplete="off" - "autocomplete" is new in HTML5! 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" (new login/registration page setting), "current-password" (Chrome browser login setting), 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", "new-password", and "current-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. Do NOT use 'autocomplete' in radio or checkbox type input types. 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 HTML5 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.
      5. 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 HTML5, 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 HTML5 browsers, adding the "novalidate" attribute disables HTML5 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 HTML5 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 HTML5 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 HTML5 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 HTML5 validation on the client side as a first line of defense against bad data. If you decide to support scripted validation and manage without HTML5 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 HTML5 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 HTML5 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!
      6. 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:
        1. "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 HTML5, 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.
        2. "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.
        3. "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.
      7. 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 HTML5. But, I do not recommend it.
      8. 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 HTML5 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 HTML5 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.
      9. 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.
      10. 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 HTML5 list. But in general, they do not affect the basic functioning of forms.
    5. 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.
    6. 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 HTML5 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 HTML5 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.
    7. The "data-" Attribute in Form Fields: As mentioned below in my "Best Practices" article called "The New 'data-' HTML5 Attribute", you can now safely use the new "data-" attribute in any HTML form element to store extra data values.
    8. 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.
    9. Common Elements Inside Forms: There are several new, "experimental" form field elements included under the 'form' element that are also listed in this HTML5 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 HTML5 which add new features in forms, but which have spotty browser support in 2022. I left these newer HTML5 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>
      <frame src="https://www.w3.org/TR/html4/present/frames.html#h-16.2.2"></frame>
      <noframes>
      <p>Alert! Frames are not supported in your web browser. This frame should includes two page views of the W3C website.</p>
      </noframes>
    </frameset>

    * If you do not see anything below, then the 'frameset, 'frame', and 'noframes' elements are not supported in your browser.

    <p>Alert! Frames are not supported in your web browser. This frame should includes two page views of the W3C website.</p>
    My Recommendations:
    1. 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 HTML5, 'frames' and its parent 'frameset' are deprecated, though the 'iframe' or floating frame is still supported in a limited way in HTML5 browsers.
    2. 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.
    3. Do not use the 'frame' element now, as it is deprecated and was a member of old HTML4. HTML5 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>
      <frame src="https://www.w3.org/TR/html4/present/frames.html#h-16.2.2"></frame>
      <noframes>
      <p>Alert! Framesets are not supported in your web browser. This frameset should includes two page views of the W3C website.</p>
      </noframes>
    </frameset>

    * If you do not see anything below, then the 'frameset, 'frame', and 'noframes' elements are not supported in your browser.

    <p>Alert! Framesets are not supported in your web browser. This frameset should includes two page views of the W3C website.</p>
    My Recommendations:
    1. 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 HTML5, 'frameset' are deprecated, though the 'iframe' or floating frame is still supported in a limited way in HTML5 browsers.
    2. 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.
    3. Do not use the 'frameset' element now, as it is deprecated and was a member of old HTML4. HTML5 browsers will no longer support framesets. You might try the 'iframe' instead (see below):

      <iframe src="https://www.w3.org/"></iframe>
    <head> head

    Head

    see <html>
    My Recommendations:
    1. The 'head' element defines the non-content head area of a web page. See the <html> element for a full description.
    <header> header

    Header

    See also <nav>, <main>, <footer>, <section>, <article>, and <aside>
    <header id="header" role="banner" aria-label="Header" >Header</header>
    Main
    Footer
    * A typical web page structure is shown above.
    My Recommendations:
    1. The 'header' element is new in HTML5 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 HTML5, the 'header' is part of a set of new structural page elements that define the overall layout of most HTML5 website pages designed today (<header>, <main>, and <footer>, etc.).
    2. The New HTML5 Structural Elements include: header, nav, main, footer, section, article, and aside.
    3. 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".
    4. See the <main> element section for more details about this new HTML5 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:
    1. 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.
    2. 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. Note: Many old HTML attributes are deprecated (like 'align'), so do not use them. Rely on CSS for all formatting of headings instead.
    3. 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.
    4. 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.
    5. 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!
    6. 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> HTML5 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.
    7. 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.
    8. 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:
    1. The 'hgroup' element was new in HTML5, 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 HTML5 browsers, but removed from the W3C recommendations, I do not recommend its use in web pages at this time.
    2. 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 HTML5 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:
    1. 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.
    2. 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.
    3. What is the Right HTML5 Structure for the 'hr' Element? As always, the great debate by newbies online demanding we use "void" HTML5 elements as they were designed continues. Their argument says that any element that has no ending element, is a "void" element in HTML5 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 HTML5, and should not indicate it has ended. But they are WRONG! You should ALWAYS design your HTML5 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 HTML5, as HTML5 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!
    4. See my section called "Use Horizontal Rules (hr) when Separating Content" below for additional details.
    <!doctype>,
    <html>,
    <head>,
    <title>,
    <meta>,
    <body >
    doctype, html, head, title, meta, body

    HTML

    I have decided to cover all the major HTML "framework" elements in one section so you can see how they create the modern HTML5 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 HTML5.

    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 HTML5 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 HTML5 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 HTML5 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 HTML5 Template".

    Basic HTML Web Page Template Code

    
    <!doctype html>
    <html xml:lang="en-us" lang="en-us">
        <head>
            <title>Your Website Title</title>
            <meta http-equiv="content-type" content="text/html; charset=utf-8"
            <meta http-equiv="content-style-type" content="text/css; charset=utf-8;">
            <meta http-equiv="content-script-type" content="text/javascript">
            <meta name="viewport" content="width=device-width,initial-scale=1.0,shrink-to-fit=no">
            <meta http-equiv="x-ua-compatible" content="ie=edge"> 
            <meta name="keywords" content="keyword1, keyword2, keyword3">
            <meta name="author" content="Your Name, https://yourwebsite.com/">
            <meta name="description" content="Your Web Page Description, author Your Name 2022">
    
            
            <meta name="copyright" content="© Copyright 2022, Your Name | All Rights Reserved">
            <meta name="classification" content="business">
            <meta name="rating" content="general">
            <meta name="revision" content="1.0">
            <meta name="distribution" content="global">
            <meta name="resource-type" content="document">
            <meta name="doc-class" content="Living Document">
            <meta name="document-type" content="Public">
            <meta name="document-rating" content="General">
            <meta name="robots" content="all">
            <meta http-equiv="pragma" content="no-cache">
            <meta http-equiv="cache-control" content="no-cache">
            <meta http-equiv="expires" content="0">
        </head>
        <body text="black" bgcolor="white">
        ...
        </body>
    </html>
    
    My Recommendations:
    1. 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 HTML5 web page. I will cover those elements below.
    2. 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, HTML5. 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 HTML5 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 HTML5 pages and defines your document as a "true" HTML5 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 HTML5. The newer web browsers will generally assume you are always using HTML5 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 HTML5, which is likely 90-99% of most browsers viewing your website in 2022. 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 HTML5 DOCTYPE and interpret your web page as a form of invalid XHTML. That is generally ok, as we are not worried about validation in HTML5. 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 "XHTML5 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" HTML5 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 HTML5 works in XHTML5 by using XML-friendly code, btw.) So my point is, do not worry about these issues in older browsers and the HTML5 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 HTML5 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 HTML5 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, HTML5 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 HTML5 DOCTYPE mentioned above in combination with this root element, your pages are recognized as HTML5 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 HTML5 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 HTML5 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 HTML5 DOCTYPE mentioned above, the browser will assume your HTML5 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 HTML5'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 HTML5 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 HTML5 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 2022" />
          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 HTML5 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 2022, 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. In the old days of the Internet, many browsers did not support CSS and even when they did, still did not support many styles of the 'body' element. This allowed and required the use of many proprietary HTML attributes including the following that are no longer used by modern HTML5 browsers: background, bgcolor, text, bgproperties, margin family, and link family of <body> attributes.
        I generally do not encourage you to use these, as they relate to 1998 browsers and old HTML4 and CSS in the 'body' element has now almost universal support. The "text" and "bgcolor" attributes added above are not supported in HTML5 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.
    3. If you want a full featured HTML5 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 HTML5 Template".
    <ibobject> backstage object

    Backstage Object

    <ibobject name="backstage_object />

    My Recommendations:
    1. The 'ibobject' element is deprecated but was a non-standard HTML element related to a now deprecated "backstage server" server and web page system. 'ibobject' was mainly used by early Web browsers, like Netscape v3 and Internet Explorer v3. Do not use the 'ibobject' element as it is now deprecated.
    <iframe> iframe, inline frame

    Iframe

    also see <frameset>
    <figure aria-labelledby="iframecaption1" style="padding: .5rem;border: 1px solid #bbb;background: #f0f0f0;width: 400px;height: 300px;display: block;text-align: center;">
    <iframe id="myiframename" name="myiframename" title="Internet Archive Movies" loading="lazy" referrerpolicy="no-referrer" style="width:auto;height:auto;min-width:100%;min-height:80%;" src="about:blank" srcdoc="<!doctype html><html xml:lang='en-us' lang='en-us'><head></head><body style='width: auto;height: auto;text-align: center;background: white;'><p>Welcome to My Iframe!</p></body></html>"></iframe>
    <figcaption id="iframecaption1" style="font-size: smaller;"><a href="https://archive.org/details/TheSpiritOf43_56" target="myiframename" title="Donald Duck Movie" rel="noreferrer nofollow noopener">Load Donald Duck Movie</a><br /><a href="https://archive.org/details/CC_1914_08_31_TheGoodforNothing" target="myiframename" title="Charlie Chaplin Movie" rel="noreferrer nofollow noopener">Load Charlie Chaplin Movie</a><br /><a href="about:blank" target="myiframename" rel="noreferrer nofollow noopener">Load Blank Screen</a></figcaption>
    </figure>

    Notes on My Iframes Example: Notice I have wrapped the 'iframe' element with the new HTML5 '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.

    Load Donald Duck Movie
    Load Charlie Chaplin Movie
    Load Blank Screen

    My Recommendations:
    1. The 'iframe' element is an inline frame element that contains an independent window or URL within the current browser window. The 'iframe' creates a floating document window to an outside web page URL within the larger browser viewport, allowing viewers to see additional content inside the existing web page. The 'iframe' was a member of old HTML4 and supported in the first Internet Explorer browser (1997). And so, it has been around for some time and supported in all the browsers. It was removed from XHTML, however, so still not supported in XHTML5. It is the only "frame" element still supported within the current HTML5 recommendation, however. In HTML5, the old 'frameset' is now deprecated, though the 'iframe' is still supported in a limited way (security limitations) in modern HTML5 browsers.
    2. Attributes of Iframes: I will not cover all the iframe attributes, as most are either deprecated or not supported consistently across numerous browsers, old and new. So, I cannot recommend their use. The main attributes I do recommend are listed below:
      • "src" - Add the URL path to your internal or external source here. This can be a URL to a web page, a file, media, etc. But understand the security risks and get permission when possible before using someones online material inside your own.
      • "srcdoc" - This new attribute is not supported by a wide range of browsers, like Internet Explorer 1-11. So I do not recommend it. But it is a safe "add-on" you can try if you need insert some custom HTML you want displayed into the iframe and you need a starter or blank iframe page. You can use "about:blank" or custom HTML for the value and this is what appears when the page loads, saving your page from having to download external pages at first. I use this attribute in the code same above.
      • "name" - Use a "name" with a matching "id" value. The "id" allows scripts to access the 'iframe'. "name" allows links to access the "src" attribute of the 'iframe' and change it to a new location (see my code example above).
      • "width" and "height" - I recommend use of the "width" and "height" attributes only to reserve space in the browser layout while the page loads. Match those to "width" and "height" CSS values using styles, as you want to always control those dimensions using style sheets. Often the dimensional attributes are ignored in HTML5 browsers on multimedia elements like this. So, always rely on style sheets to control dimensions.
      • allow="fullscreen" - Use this attribute and value if you want your iframe to activate fullscreen mode. To me this is pointless. You might as well just link to the iframe page.
      • loading="lazy" - Use this attribute and value if you want to delay download of the 'iframe' source page until the user scrolls down to view it. This is not supported in IE, Firefox, Opera, and other browsers. So use it as a limited add-on to help your page manage downloaded material in a very limited way.
      • referrerpolicy="no-referrer" - Use this attribute and value if you want to block the external source or server of your iframe file from getting your user's referrer or source information. This blocks the origin data sent to their servers, which shows up in their logs every time a visitor of your web page uses one of the video or files imported into the iframe. Note: If this prevents you from accessing the external file, then you might have to remove it.
      • Use CSS - Always use CSS style sheets to control the border, size, background, scroll bars, margins, and position of your 'iframe'. CSS is far superior in controlling the design of HTML than an element's attributes.
      * Avoid these old, deprecated attributes once used in old browsers (pre-2001): align, frameborder, hspace, vspace, marginheight, marginwidth, scrolling
    3. History of Iframes: The 'iframe' has been around since the 1990's, and is still used today to display independent content inside existing web pages. 'iframe' was primarily an old Internet Explorer element and not supported by old Netscape 4 Series (c. 2000). But over time the 'iframe' element has been used less and less due to security concerns and the demands on browsers when displaying outside media and content like this. The unknowns of cross-domain displays and various media, scripts, and players means 'iframes' like 'frames' open up the user to numerous vulnerabilities online. In addition, many content providers block 'iframe' use of their material, or encourage other forms of displaying them. Some clever 'iframe' websites now use small, hidden frames to hide data processes, capture secret content from users, display advertising, or preload large JavaScript libraries behind the scenes. All are bad web design concepts. Browsers now, by default, disallow iframes to do much inside the browser for security reasons. So many of the benefits of iframes for some has diminished. But use of the 'iframe' element is not all that bad when used conservatively, which is what I recommend you do.
    4. Changing Iframes URL's: You can actually change the location of an iframe's URL externally in HTML by simply adding links. You can see this technique used in my code example above. The anchor tags (link) contain a "target" attribute that matches the "name" attribute of the 'iframe'. Clicking the link sends the "href" URL value of the anchor to the 'iframe' "src" attribute and changes its display to the new 'href' URL value of the anchor. Using the 'target' attribute like this means anchor tags and many other elements can now manipulate what appears in iframes!
    5. Iframes and Host Servers: When adding an 'iframe' element to a web page, when the iframe calls a foreign domain for a URL page, it is designed to be accepted or rejected based on a number of special server checks. This is again for security reasons, but also to stop some from illegally planting copyrighted material into a source page that can pretend to claim or use the material as their own. The 'iframe' in a parent page often sends its own special instructions behind the scenes that tell the source server the page is bound inside another domain or web page as an "x-frame". It will send the server "notes" via an HTTP header saying an iframe is being used and the browser will listen for an "X-Frame-Options" value from the source. Servers can then decide if they will authorize such a use if the parent page is not from the same domain or subdomain as theirs with either "sameorigin" (denial) requirement, "allow-from" (is your site on their list), or a "allowall" (accepted). Often companies block 'iframe' use of their material, so you can get a denial response. To try and bypass this security check and enable some sort of foreign page display of their material, most large sites reject 'iframe' use of their pages and include an "embed" option to iframes instead with instructions. Youtube now does this to stop users from linking to their content inside other web pages without tracking their use or paying for its use. One trick you can also do to improve the chances a foreign server accepts your 'iframe' URL use is remove the "https://" from 'iframe' element URL's (src="//www.youtube.com/embed/..."), which will now make several calls to the server to negotiate a more secure call to their material, and lets them decide if your use of their secure material is allowed and if the parent page allows SSL/TLS, etc. Any such conflicts listed above could block the material coming from the host server inside your 'iframe'! Your 'iframe' will then show a warning or white error page. Again, all this increases the issues surrounding 'iframes' and why, like frames, they are not reliable.
    6. Additional Security Concerns with Iframes: Besides sites now blocking 'iframe' use of their material, there is an opposite problem: Security! 'iframes' often display risky outside URL's of content and various media, so naturally runs the risk of having dangerous scripts in foreign code or hijacked web pages secretly run in your page's 'iframe' and access the browser's primary window. The 'iframe' can then force download of dangerous files or scripts, run plugins, or execute dangerous applications on the user's computer from unknown locations. To prevent this, most modern browsers today now lock down or prevent many type of 'iframe' access to the main windows by default, including blocking many devious foreign processes, like secret file downloads, running unknown scripts, manipulation of content outside the iframe, running dangerous players and plugins, manipulation of same-origin-policy, triggered popup advertising, secret form field captures, click-jack attacks in frames, and more. To enable any of these features now requires the web author add a new attribute called "sandbox" and the "allow-{policy name}" value to their 'iframe' element. This allows you to open up what the 'iframe' can do in a user's browser (Google "sandbox", "iframe", and "allow-" to get a full list of the available settings). Without use of "sandbox", the 'iframe' and its URL page has very limited control over the brower's threads, memory, and execution routines. This is a good thing. By default it means nothing much is allowed and secures the browser when 'iframe' is used to host foreign web pages inside their own. Keep in mind older browsers (IE9 or less, for example) have no such protection. It's also very easy to manipulate this attribute to enable more features and weaken security in the browser. The "sandbox" attribute also adds complexity and uncertainty to secure aspects of the 'iframe' that are not necessary, if not dangerous. Because "sandbox" is required to enable more features in your 'iframe', yet risks changing security in your user's browser, I feel its unwise to use this feature at this time and just leave the 'iframe' default security as is.
    7. Do not use the old 'frameset' element now, as it is deprecated and was a member of old HTML4. HTML5 browsers will no longer support framesets. Stick with the 'iframe' instead!
    <ilayer> ilayer, in-line layer

    In-line Layer

    <ilayer>Text Content Here</ilayer>

    Text Content Here
    My Recommendations:
    1. The 'ilayer' element is deprecated but was a non-standard HTML element supported only by old Netscape 4 Series browsers designed to position elements of content within the main web page flow. The 'layer' and 'ilayer' element in Netscape browsers acted like a form of 'div' or 'iframe' alternative. Do not use this element as it is now deprecated.
    <img> image

    Image

    also see <picture>

    Using Plain Images

    Below is the more traditional way to use images in web pages. If you just need an image to appear in a web page, you can drop in the 'img' element anywhere in your page. Note: The sample code below has a full suite of attributes I recommend you use which will allow your image to perform at its best in various scenarios in HTML.

    <img id="imagexample1" style="border: 4px solid #999;" src="www.jpg" width="255" height="200" alt="image: World Wide Web" title="The World Wide Web" aria-label="Image of the World Wide Web" loading="lazy" onerror="this.onerror=null;" referrerpolicy="no-referrer" />

    image: World Wide Web

    Images With Text that Wraps

    Most 'img' elements are "inline", meaning they flow with text horizontally across the page. Text does not wrap around the image by default but with the image horizontally. This allows you to drop images inside of paragraphs or text and they become part of the flow. Many people want text to flow around images, however, and float inside paragraphs. In most cases, text will not scroll around the image like this unless you change its display to "display:block" and add "float:left" in CSS. In the old days you could avoid this and set the "align:left" attribute on the 'img' element and force text to scroll to the right of it with mixed results. But it was not reliable as the image remained an "inline element" like the text beside it and part of the normal flow of text. I recommend you manipulate the image instead to float as described above using CSS rather than the "align" attributes on the 'img' tag.

    <div style="padding: 1em;border: 1px solid #999;background-color: #ccc;">
      <img id="imagexample2" style="width: 255px;height: 200px;display: block;float: left;margin: 0em 1em 1em 0em;border: 4px solid #999;" src="www.jpg" width="255" height="200" alt="image: World Wide Web" title="The World Wide Web" aria-label="Image of the World Wide Web" loading="lazy" onerror="this.onerror=null;" referrerpolicy="no-referrer" />
      <h5>Sample Title</h5>
      <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 </p>
      <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 </p>
    <div id="clearingdiv" style="clear: both;"><!--empty--></div> </div>


    image: World Wide Web
    Sample Title

    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


    Using Images with the New HTML5 <figure> and <picture> Elements

    Below is the more modern HTML5 way to use the 'img' element. Below I have wrapped the 'img' element in a 'figure' element, then a 'picture' element. The 'figure' element provides a 'figcaption' or text caption for the image, assisting non-visual readers. The 'picture' element provides alternative image formats based on browser support, viewport size, or other checks in the <source> tags. The browser first checks these 'source' elements one at a time, and if the image "type" is supported and/or viewport dimensions match, then the alternate "src" image is passed into the 'img' element below. If none are supported, then the default 'img' tag's image "src" is used. Understand that 'picture', like 'figure', is just a hollow "shell" element and does not do anything other than to group images with these other features, as well as give the 'img' tag alternate image choices. It simply injects alternative image formats into the 'img' element, if the user's browser supports them. So keep in mind, the 'img' element remains the PRIMARY container of the image inside all these other elements.

    The 'img' element below also has a set CSS "style" attribute with variable width and height added to support the possible variable dimensions of the alternate image types assigned by the 'source' elements. It does have "width" and "height" attributes whose values are based on its default image, which the browser should only use if it defaults to its first image. But those will be ignored as each source image with different dimensions is applied.

    So, if you see a "flowering tree" image ("webp" type) below, your browser supports one of the new alternate HTML5 image formats that the picture's 'source' element has assigned your 'img' element. If you see the "weather map" image it means your browser does not understand the WebP image type or failed the "media" viewport check in the previous 'source' element. Finally, if you see the default 'img' element's "World Wide Web" globe image ("jpg" type), the previous two image types failed and your browser only supports "jpegs".

    <figure aria-labelledby="imgcaption3" style="padding: .5rem;border: 1px solid #bbb;background: #f0f0f0;width: auto;height: auto;display: inline-block;">
    <picture id="imgpicture3">
    <source srcset="image.webp" type="image/webp" />
    <source srcset="weather.gif" media="(min-width: 800px)" type="image/gif" />
    <img id="imagexample3" style="width: auto;height: auto;max-width: 100%;" src="www.jpg" width="255" height="200" alt="image: World Wide Web" title="The World Wide Web" aria-label="Image of the World Wide Web" loading="lazy" onerror="this.onerror=null;" referrerpolicy="no-referrer" />
    </picture>
    <figcaption id="imgcaption3" style="display:block;">
    "Which Image Appears?"
    </figcaption>
    </figure>


    image: World Wide Web
    "Which Image Appears?"

    * Note: My host provider does not support "WebP" images I found out, so if no "flowering tree" WebP image appears, it is not the code but my host provider. :(

    My Recommendations:
    1. The 'img' element is an inline media element that displays an image in a web page. The 'img' was a member of the original HTML specifications in the 1990's and has not changed in over 20 years, so is fully supported in all the browsers. In HTML5, the 'img' element has now matured a bit more, and can now be contained within a 'figure' and 'picture' parent element to enhance the image with captions and more advanced HTML5 alternative image formats like WebP, Base64 encoded images, etc.
    2. What is an Image? It has been around since the birth of HTML and web pages in 1990. The 'img' element is actually a "replaced" or embedded element in HTML. Such elements are typically managed outside the web page and generated by the browser. The 'img' display is not really connected to HTML and markup, but added as a special "control" in the web page the browser and operating system manages. The pics and graphic display is a separate part of the browser from the textual markup. Like the 'select', 'file', and 'textarea' replacement elements, image layouts and limitations are often controlled by the browser and cannot always be styled or affected or altered by code or scripts like CSS or JavaScript, either. In older browsers, controlling images in the 'img' tag was sometimes difficult. However, 'img' elements have over the years been more "stylable" than most replaced elements. If you want to see all the COOL ways you can use images and the 'img' element in web pages, see my article below called "How to Display Images in HTML". I cover all the basics of using images in HTML.
    3. Image Element Attributes: I will not cover all the 'img' attributes, as many are either deprecated or not supported consistently across numerous browsers, old and new. The main attributes I do recommend for images are listed below:
      • "src" - Add the URL path to your image on your server here. This must be a absolute path ("/") or a relative path ("../") to your image on your web server using one of the many "image" formats types (jpg, gif, png, bmp, webp, etc.) supported by most web browsers.
      • "id" and "name" - Always add a unique "id" value to your image so you can manage it quickly and consistently by scripts on the client. The "name" attribute has been deprecated for 'img' elements in HTML5, so avoid its use.
      • "alt" - The 'alt' attribute is a text "replacement" for the image when it is slow to appear, fails to appear, or not viewable by the blind in a screen reader. 'alt' text should describe the image if the image contains information that is important to a screen reader. If the image is wrapped in an anchor (a hyperlink) the 'alt' text should explain where the link goes if the image is clicked. You can also use an alt="" blank value if the image is only for decoration. This tells screen readers the image is not important and if its missing, no placeholder will create a empty image box. But always add an "alt" attribute with a simple description of the image in as few words as possible. This text is what will appear inside the image box in your web page if the image is missing for some reason. The role of the 'alt' attribute is critical in all the scenarios described above and more, so I like to use this text format in mine: alt="image: World Wide Web". Note: The alt text should not exceeds 150 characters. Use null "alt" text as in alt="" on images that serve only a structural purpose, which is good for hiding spacers or design images that do not need to be identified. These are hidden from screen readers. Don't use suspicious alt text as follows: alt="photo.gif", alt="234 bytes", alt="image", "graphic", "photo", "photograph", "drawing", "painting", "artwork", "here", "click here", "click", or starts with "graphic of" or "image of". "alt" should apply to any HTML element that represents a visual image of some kind. Every image should have at least an empty alt="", if the image is not important. Lastly, old IE 4-6 had issues with "alt" attributes, where if you left off the "title" attribute, suddenly the alt appeared as a rollover tooltip! This was incorrect. So, that is why every image should always have both attributes. When doing so in old IE browsers, the "title" tooltip will suddenly replace the alt tooltip ad prevent it from appearing.
      • ARIA labels and the "title" - Like the "alt" attribute described above, ARIA label and "title" attributes are vital in allowing both visual and non-visual people to understand your image textually. I like to give a full description for the image in my title. The rollover tooltip that appears then allows users to see more information about the image. If the image is inside a link, its vital you tell a visual person what it is they are clicking before they do so. The ARIA "aria-label" works like title, but is ONLY seen by screen readers. So for them, you just want to identify what the image is, not a provide full description in the label, which they can get from the "title" attribute or using the "figcaption" element text. WARNING: Do NOT duplicate the text in the "text" attribute with what is in the "alt" attribute, as each serve different roles and screen readers may repeat both with the "aria-label" text. Remember, 'alt' as "alternative text" for a missing image, "title" or tooltips are descriptive and additive to the image, and ARIA labels provide information only for screen readers that can never view the image or understand its meaning.
      • "width" and "height" - I recommend you ALWAYS add the explicit "width" and "height" attributes with the image's true dimensions on all images only to reserve space in the browser layout while the page loads. Match those to "width" and "height" CSS values using styles, as you want to always control the final dimensions using style sheets. The style values will override the attribute values, so you can scale images using CSS quite easily. Note: In the old days in older browsers we were able to use the "width"/"height" attributes to expand or shrink the actual true size of images. In HTML5 this causes severe problems now as the recommendation tells browser to focus on the images true dimensions which it uses to calculate an aspect ratio in memory for the image. If you try and enter dimensions that are not the image's true values, HTML5 browsers will ignore your values anyway and use the image's true values anyway.
      • DO NOT USE "srcset" and "size" - "srcset" and "size" on 'img' elements are non-standard attributes and will fail in many old and new browsers, anyway, including all versions of Internet Explorer 1-11. However, in some limited cases you might find it helpful. For now, I RECOMMEND YOU DO NOT USE the "srcset" and 'size' attributes! I recommend you use the new HTML5 'picture' element instead of "srcset" and allow its 'source' element with the 'img' element to control source images and media, instead. Why?
        • 'srcset' - This attribute is new in HTML5. But it comes with numerous bugs and counter-intuitive features I do not recommend. With this new attribute you can now apply "alternative images" to your 'img' elements. This is supposed to be another form of responsive design, delivering several images in various sizes inside the "srcset" attribute. With this feature you are supposed to be able to deliver images based on the width of the viewport of the user's browser. You are letting the browser decide what alternate images to use based on some logic related to available screen width in a user's device and browser. Typically, we do this using CSS style sheets and "media queries", which measure the width of a viewport or uses other conditions to set styles that refit layouts and choose images that fit well into the browser. Often you can switch out images this way and have more control. This "srcset" feature works the same, but on an image-by-image basis which to me is tedious. But if you had multiple versions of a very large, high resolution or PPI image, you could use "srcset" provide alternates at smaller sizes in its "srcset" attribute and save bandwidth via smaller downloads. The user's browser will then switch the image out with the new images as the users screen width increases or decreases. That is the hope, at least. But its not reliable. Though the "srcset" attribute allows you to list multiple images to download based on viewport widths, multiple image size choices often fail to change them from using any of the alternatives if all three will fit into a given viewport. So, it is pointless. Often the browser doesn't know which image ideally works best beyond just seeing if its width will fit, which all threes often will. So nothing really changes. You set this like so: "srcset=255.jpg 255w, 200w.jpg 200w, 100w.jpg 100w". The browser should pick the small images as screen width reduces. You can also use "1px, 2px", etc. instead of the width values, that read the "device pixel" values of the device, then choose images with higher resolutions. Many iPhones, for example, use 2 or 3 pixels per CSS pixel, meaning higher resolution images look better on those devices. But again, you are hoping the browser even knows what the "device pixel" is on a given phone or high-resolution device. Its all pretty dicey to me and not reliable. "srcset" on images was also shown to fail, or be partially supported, on many of the newest HTML5 browsers. Example: in Chrome, even though you set three alternative images with various widths, it rarely picked smaller images in any device viewport, anyway. And when it picked an image it still tried to use the "width" and "height" dimensions of the original 'img' dimensions anyway, not the new one's dimensions, which is bizarre. It just dropped the smaller or larger image into the existing medium image's width and height as set on the 'img' attributes, for example. It should resize itself to the chosen image's new dimensions. When I removed those dimensional attributes on 'img' to try and "coax" it to use the new images actual size, it made the default image as large as the parent block instead (same as setting "size=100vw"), not its actual size. It should always default to the actual image's first size even with the "sizes" attribute removed. Who sets images to viewport width anyway? That just creates blurry, distorted images. So "srcset" failed numerous basic tests for me.
        • The "size" attribute they say must always be assigned if you use "srcset". This attribute allows you to physically change the size of an image larger or smaller from its ACTUAL size to a viewport "stretched" size, away from the image's actual property size. Again, why create stretched, blurry images? Note that "sizes" does not interfere with the "srcset" attribute's image choice. It simply resizes the new image, yet again, which to me is confusing. "sizes" simply allows you to resize that chosen image bigger or smaller relative to the viewport. "size" is also problematic as it alters the image's size to a "viewport size" instead of using or starting with its actual size, when making the new calculations. Some additional confusion with "size" is that often images sit inside a parent block that constrains its dimensions, so resizing is redundant. Why not just use "width:100%" in CSS if you want some viewport stretched image, anyway? On smaller images using say "10vw" or one tenth the viewport width for the images new width, it works ok. But on larger image sizes, say "100vw", it cannot set that value to 100% of the device's screen width as most images are constrained by the parent's width. Example: An image in a 'div' element set to 50% of the viewport width will never allow its child 'img' element to be 100% of the screen width, as in "sizes="100vw", as its constrained to the 50% viewport width of its parent. I also saw "bleed over" of the image outside the box when this event occurred. In addition, setting "width" and "height" attributes on the 'img' tag, as mentioned above, messed with these viewport dimensions and often deleted them. I tested this using "width" and "height" attributes, or CSS dimensions, or even with no attribute dimensions, and "sizes" had variable results honoring or ignoring these values. On "sizes" attributes, you can also use "media queries" to further control image viewport image resizing (this doesn't affect the "srcset" image choice though, which is confusing!) Example: "sizes=(max-width: 800px) 50vw" tells the browser, after choosing one of the three images in "srcset", if the browser window is less than 800 pixels, resize that image down yet again to 50% of the viewport. I find this feature a bit sloppy and poorly thought through. For starters, we used to do this resizing of images manually inside parent containers using "width:50%" in style sheets on the parent container. The viewport width then really doesn't matter. The parent's width matters! We also manipulated this by resetting the "width" and "height" attributes (this "stretch feature using attributes is now disabled in HTML5). So "sizes" destroys the main features of good image size control we used to have which was much simpler and always based on an image's actual "width" and "height".
        • "all:revert" when used on the image element, ERASES the previous or even actual image size, which is lost in the browsers render and paint processes on the DOM, so breaks all use of "srcset" and "size" attributes.
        • ONLY use 'picture element, instead of "srcset" anyway. Because the "media" attribute of 'source' elements offer multiple choices for the browser and works the same as the 'image' "srcset" attribute, but in combination with the more advanced image "type" attribute to help control when image alternatives are chosen, you will get more "predictable" results than using "srcset" and "size". The 'picture' element' also fails gracefully in older browsers, while the 'srcset' has no support in browsers like IE, so will not work anyway.
        But if you want to try "srcset" and "size" together, below is an example of an 'img' element code with those attributes added. Just create three images of different sizes and try scaling your browser window in size to see if it works. Notice, you can offer a comma-separated options list for both alternative image types and a media query for when to apply different sizes of images based on size of the viewport. The browser will use one of these images or the default image in src to start. It will then use one of the widths, like the "640w" value for example, to determine if this sized image will fit "better" into the user's display and reserve space for it. Note that without these explicit widths, it cannot know what dimensions to expect for each image. "sizes" allows you change the width again on your image based on the viewport width. (confused yet?).
        Below is an example of three images for a JPEG image where three image widths are offered (320w, etc.). The browser should first use the image widths to decide which one fits best in the users screen size. It should then use the "sizes" attribute to determine if the chosen image should be resized based on some media query condition related to the device's viewport width or other criteria, and if those conditions are met, resize the image to a new value relative to the viewport width (not the image's). "50vw" should mean the image is sized 50% of the device's screen width (if not in a constraining container!). Note: Its important you include your default image in the "srcset" attribute list below:

        <img id="srcset_image" src="medium.jpg" srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w" sizes="(max-width: 800px) 50vw" />

      • longdesc - This is a link to a separate file with a description for the image. Use of "longdesc" with a URI link was once used alongside 'title' to provide a link to more detailed information about the image. But this attribute is now either experimental or deprecated. We never used these in the past anyway, as it was overkill. The new HTML5 'figure' and 'figcaption' elements really contain more info on an image and should be enough.
      • loading="lazy" - This attribute is not widely supported by browsers. But for those that do, it adds a valuable way to delay image downloads until the user scrolls down to view the image. At that point, the browser actually downloads the image into the 'img' placeholder element (hopefully with its reserved "width" and "height" attributes set). For image heavy websites, this might be valuable too. I have seen this feature wait to load a large image as you scroll a web page, but the delay cause a "flash" of the image. So, with all sketchy features like this, do not rely on it.
      • referrerpolicy="no-referrer" - This attribute is widely supported by most browsers, except Internet Explorer and some overseas browsers. But for those that do want to use it, it adds a valuable way to show/hide referrer data when calling a foreign image from another server. This applies mostly to cases where you link to an external image found on a foreign server. Often, when you paste a URL to an image from an external website into your web page, when your web page and your user's browsers call the foreign server to download the image, they can read your IP, domain of origin, path used, and other information. In the past this was not important. But to hackers and spammers today in 2022, it can be. If they know an image in an email or website was read by you, they could use your origin information to continue to target you. Most web developers now use large amounts of CDN's and foreign URL's to download external files into their user's websites. These come from numerous external sources. They do not realize that these sources can track your usage or your user's usage of their services via images and files your users constantly download to their browsers when viewing your website. For that reason, I recommend you NOT rely on CDN's for files. However, if you do, you can always set the "referrerpolicy=no-referrer" attribute on all such external or foreign images to stop access to your website origin data. This then tells the external server logs access to their image was a simple Google "direct" or plain link, and hides your user's data and your server path from their logs. The default for "referrerpolicy" is "no-referrer-when-downgrade", which means by default the referrer header info will be sent to them as long as you use HTTPS. Thats very bad! Without adding "no-referrer", all your image path data and origin info is sent to their servers when you create a path to their images or files. For you and your web user's sake, I recommend you always set images with the attribute "referrerpolicy=no-referrer" when using external images, so they have no way to know of the source of these calls. Note: This matches the same feature found in 'a' element links where the "rel" and "noreferrer" attribute value is used.
      • onerror="this.onerror=null" - You know me, I do not like scripted dependencies. But this little extra trick might help some browsers handle issues where images are lost. The script then nulls out the "broken" error icon if the image is slow to download or missing on the server. If an image is not found or is missing, you have a choice: Either let the browser show a broken error image and hopefully your 'alt' attribute text replacement, or use JavaScript to degrade gracefully and hide the error completely. You can use this 'img' attribute trick by adding this: "onerror=this.onerror=null;" or "onerror=this.remove();", which will be applied when an image is missing, corrupted, or slow to download and times out. Because this will rarely occur, its an extra but of HTML code that will not hurt your page, but allow the 'alt' text to appear quicker when an image is missing from the page, while removing the error from the reported list of errors created by the browser. Note: You can also assign a universal fallback image instead, like a transparent spacer or custom error image, if any image is missing in your website. In that case it will show a replacement image. Just add the following to your "onerror" event attribute on 'img' with a path to your default image like so: "onerror=this.onerror=null;this.src='default.jpg';". Update (11/2022): Recent browser updates have disabled 'onerror' script. When a bad image path is detected, the error is thrown, cannot be captured using 'onerror', but is logged in devtools anyway. A broken image icon is then returned in the HTML view. So, my recommendation is to abandon this attribute now.
      * The following is a list of deprecated attributes no longer used by modern HTML5 browsers and the 'img' element: align, border, controls, dynsrc, hspace, vspace, ismap, loop, lowsrc, start, vrml.
    4. Image Figures and Captions - In HTML5, the 'figure' and 'figcaption' elements are now used by modern browsers to wrap around images and add captions beneath then in HTML5. The 'figure' element wraps around the image and the "figcaption" usually appears under it with text describing the image. Most photographic websites, online magazines, or article images carry more visual information in the 'img' element than normal, so require a text caption to connect the image with the article text. So, be sure to add captions when using images in HTML5. See my article below called "How to Display Images in HTML" for a great rundown of how to add rich textual content to your images.
    5. Using Background Images: Background images are becoming more popular, simply because some developers want to trick browsers into delaying download of images by using them as tiled backgrounds in CSS instead. In the past, we traditionally only used background images when needing tiny "tiled" web page wallpaper backdrops or to contain logo headers at the top of web page. If used to show visual queues like photographs in pages, background images in CSS do create a semantic problem. The issue with background images is when used this way they are no longer part of the page layout or page flow, so are "semantically" not viable either for search engine indexing or even viewing in some browsers that may fail to download them. Often block-level elements will collapse, hiding the image. Screen readers certainly would not have a way to know about these visual queues like they would traditional images in 'img' tags with 'alt' attributes. I discuss the right way to use background images elsewhere in this tutorial, though I rarely support their use.
    6. Images Inside Links - In the old days, we liked to use images with anchor tags wrapped around them, creating powerful "image links" or buttons from page to page. Weird browser issues occurred, however, like the strange blue borders around images in Netscape 4 which were hard to remove (see my <a> element recommendation above for two ways to fix this using "border:0" and adding "width" and "height"). Over time, use of image links like this have faded as far as use cases. But keep in mind, you can still do this trick. Just make sure you use enough CSS, tooltips, and figure captions on the image to design it properly and to tell users the purpose of the image link before they click on it.
    7. Compressed Images and Faster Page Loads - There is no doubt that in 2022 most developers have lost the knowledge needed to compress JPG, GIF, PNG, or other image formats. I see HUGE uncompressed images and photos all over the Web today. By compressing images and limiting color palettes, you can greatly speed up the download of your web pages just as reducing the megabytes of JavaScript downloaded can speed up pages. We learned how to compress images using limited color palettes (like Netscape's "Web Safe" 216 palette for GIFs, minus 40 colors reserved for the Netscape logos) and LOSSY JPEG photos compressed by image programs like Adobe's "ImageReady" 20 years ago. Developers today have completely forgotten how to do that. So instead, they've created bloated images that are never compressed or ever use reduced image palettes. This can save gigabytes of downloads over years. Remember, bandwidth costs big bucks! But you can shave off megabytes of data per page download alone by reducing your image sizes using compression and limited palettes. So please consider doing that using image software.
    8. Images and CSS - Always use CSS style sheets to control the display, width, height, border, background, padding, margins, visibility, and position of your 'img' elements. CSS is far superior in controlling the design of HTML than an element's attributes.
    9. For more advanced examples using the 'img' element and new 'picture element, see my two articles below: "How to Display Images in HTML" and "The New Picture Element".
    <input> input

    Input

    see <form> for more details using <input> in forms

    Shown below is a complete code sample of the <input> element, which you can copy-and-paste into your web project. It has a complete set of inputs by "type", along with a rich set of attributes I recommend you use for each scenario. The visual design for this form is shown below the code. With these examples you have a complete set of inputs you can use in your web forms.

    <form id="forminput" name="forminput" method="post" action="#" title="Input Example" aria-label="Input Example" autocomplete="off" autocapitalize="off" spellcheck="false">
    <fieldset id="forminput_fieldset1" name="forminput_fieldset1" form="forminput">
    <legend style="background-color:#aaa;color:#fff;">Input Types List</legend>
    <div>
    <input type="text" id="forminput_text" name="forminput_text" size="20" value="" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" placeholder="Enter text here..." title="Enter Text" aria-label="Text" tabindex="0" required="required" aria-required="true" />
    <label for="forminput_text" title="Text">Text</label>
    </div>
    <hr />
    <div>
    <input type="password" id="forminput_password" name="forminput_password" size="20" minlength="8" maxlength="12" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,12}" value="" autocomplete="new-password" autocapitalize="off" autocorrect="off" spellcheck="false" placeholder="Enter password here..." title="Enter Password: (8-12) characters, must contain one number, one uppercase and lowercase letter" aria-label="Password" tabindex="0" required="required" aria-required="true" />
    <label for="forminput_password" title="Password">&nbsp;*&nbsp;Password</label>
    </div>
    <hr />
    <div>
    <input type="button" id="forminput_button" name="forminput_button" value="Button" title="Button" aria-label="Button" tabindex="0" aria-pressed="false" form="forminput" onClick="JavaScript:alert('::: This Button Type only works with Added JavaScript :::');return false;" />
    <label for="forminput_button" title="Button">Button</label>
    </div>
    <hr />
    <div>
    <input type="submit" id="forminput_submit" name="forminput_submit" value="Submit" title="Submit" aria-label="Submit" tabindex="0" aria-pressed="false" form="forminput" />
    <label for="forminput_inputsubmit" title="Submit">Submit</label>
    </div>
    <hr />
    <div>
    <input type="image" src="imagebutton1.gif" id="forminput_imagebutton" name="forminput_imagebutton" alt="Image Button" title="Image Button" aria-label="Image Button" tabindex="0" aria-pressed="false" form="forminput" style="border:2px solid #bbb;" />
    <label for="forminput_imagebutton" title="Image">Image</label>
    </div>
    <hr />
    <div>
    <input type="reset" id="forminput_reset" name="forminput_reset" value="Reset" title="Reset" aria-label="Reset" tabindex="0" aria-pressed="false" form="forminput" />
    <label for="forminput_resetinput" title="Reset">Reset</label>
    </div>
    <hr />
    <div>
    <input type="file" id="forminput_fileupload" name="forminput_fileupload" tabindex="0" enctype="multipart/form-data" accept="image/*" multiple="multiple" aria-multiselectable="true" title="Multiple File Upload" aria-label="Multiple File Upload" />
    <label for="forminput_fileupload" title="File">File</label>
    </div>
    <hr />
    <p>Checkbox</p>
    <div>
    <input type="checkbox" id="forminput_checkboxgreen" name="forminput_checkboxgroup" "autocomplete=off" value="green" aria-checked="false" tabindex="0" title="green" aria-label="green" />
    <label for="forminput_checkboxgreen" title="Green" style="color:green;">Green</label>
    </div>
    <div>
    <input type="checkbox" id="forminput_checkboxred" name="forminput_checkboxgroup" "autocomplete=off" value="red" aria-checked="true" tabindex="0" checked="checked" title="red" aria-label="red" />
    <label for="forminput_checkboxred" title="Red" style="color:red;">Red</label>
    </div>
    <div>
    <input type="checkbox" id="forminput_checkboxblue" name="forminput_checkboxgroup" "autocomplete=off" value="blue" aria-checked="false" tabindex="0" title="blue" aria-label="blue" />
    <label for="forminput_checkboxblue" title="Blue" style="color:blue;">Blue</label>
    </div>
    <hr />
    <p>Radio</p>
    <div>
    <input type="radio" id="forminput_dog" name="forminput_radiogroup" "autocomplete=off" value="dog" aria-checked="false" tabindex="0" title="dog" aria-label="dog" />
    <label for="forminput_dog" title="Dog">Dog</label>
    </div>
    <div>
    <input type="radio" id="forminput_cat" name="forminput_radiogroup" "autocomplete=off" value="cat" checked="checked" aria-checked="true" tabindex="0" title="cat" aria-label="cat" />
    <label for="forminput_cat" title="Cat">Cat</label>
    </div>
    <div>
    <input type="radio" id="forminput_bird" name="forminput_radiogroup" "autocomplete=off" value="bird" aria-checked="false" tabindex="0" title="bird" aria-label="bird" />
    <label for="forminput_bird" title="Bird">Bird</label>
    </div>
    <hr />
    <p>Hidden</p>
    <div>
    <input type="hidden" id="forminput_hidden1" name="forminput_hidden1" value="one" aria-hidden="true" tabindex="-1" />
    </div>
    <hr />
    <p><strong>Special Input Attributes</strong></p>
    <div>
    <input type="submit" id="forminput_disabledinput" name="forminput_disabledinput" value="Disabled Button" disabled="disabled" aria-disabled="true" tabindex="-1" form="forminput" title="Disabled Button" aria-label="Disabled Button" />
    <label for="forminput_disabledinput" title="Disabled Button">Disabled Button</label>
    </div>
    <div>
    <input type="text" id="forminput_readonly" name="forminput_readonly" size="20" maxlength="20" value="This is Read-only Text" readonly="readonly" autocomplete="off" tabindex="-1" title="Read-only Text" aria-label="Read-only Text" />
    <label for="forminput_readonly" title="Read-Only Text">Read-only Text</label>
    </div>
    <div>
    <input type="text" id="forminput_required" name="forminput_required" size="20" maxlength="20" value="This is Required Text" required="required" aria-required="true" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" tabindex="0" title="Required Text" aria-label="Required Text" />
    <label for="forminput_required" title="Required Text">&nbsp;*&nbsp;Required Text</label>
    </div>
    <div>
    <input type="text" id="forminput_states" name="forminput_states" size="2" minlength="2" maxlength="2" value="" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" tabindex="0" title="Please Enter a US State Code (2)" aria-label="Pattern Attribute Text" pattern="[A-Za-z]{2}" />
    <label for="forminput_states" title="States">Pattern Text</label>
    </div>
    <div>
    <input type="text" id="forminput_hidden" name="forminput_hidden" size="20" maxlength="20" value="This is Hidden Text" hidden="hidden" autocomplete="off" tabindex="-1" title="Hidden Text" aria-label="Hidden Text" />
    </div>
    <hr />
    <p><strong>Non-Recommended Elements that Use 'input'</strong></p>
    <div>
    <input type="text" id="forminput_datalist" name="forminput_datalist" value="" size="20" maxlength="20" tabindex="0" list="forminput_list" placeholder="Double-click to choose..." title="Double-click to Choose" aria-label="Fruit" />
    <datalist id="forminput_list" title="Fruit List" aria-label="Fruit List" role="listbox">
    <option value="apple"></option>
    <option value="orange"></option>
    <option value="pear"></option>
    <option value="grape"></option>
    <option value="banana"></option>
    </datalist>
    </div>
    <div>
    <input type="range" id="forminput_range" name="forminput_range" value="50" min="1" max="100" minlength="1" maxlength="3" tabindex="0" autocomplete="off" title="Slide the Range Indicator" aria-label="Slide the Range Indicator" /> +
    </div>
    <div>
    <input type="number" id="forminput_number1" name="forminput_number1" value="0" min="1" max="100" minlength="1" maxlength="3" tabindex="0" title="Number" aria-label="Number" /> =
    </div>
    <div>
    <output id="forminput_output1" name="forminput_output1" for="forminput_range forminput_number1" tabindex="0" value="0" title="Number Output" aria-label="Number Output"></output>
    </div>
    <hr />
    </fieldset>
    </form>
    <form id="forminput2" name="forminput2" method="post" action="#" autocomplete="off" autocapitalize="off" spellcheck="false" title="New HTML5 Input Types" aria-label="New HTML5 Input Types">
    <fieldset id="forminput2_fieldset" name="forminput2_fieldset" form="forminput2">
    <legend style="background-color:#aaa;color:#fff;">*New HTML5 Input Types</legend>
    <p><strong>Recommended New Types</strong></p>
    <div>
    <input type="search" id="forminput2_search" name="forminput2_search" value="" tabindex="0" autocomplete="on" aria-autocomplete="inline" required="required" aria-required="true" novalidate="novalidate" spellcheck="false" placeholder="Search this site..." title="Search" aria-label="Search" />
    <label for="forminput2_search" title="Search">&nbsp;*&nbsp;Search</label>
    </div>
    <div>
    <input type="email" id="forminput2_email" name="forminput2_email" value="" tabindex="0" autocomplete="on" aria-autocomplete="inline" required="required" aria-required="true" placeholder="Enter an email address..." title="Enter a valid Email Address: x@x.com" aria-label="Email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" multiple="multiple" aria-multiselectable="true" />
    <label for="forminput2_email" title="Email">&nbsp;*&nbsp;Email</label>
    </div>
    <div>
    <input type="tel" id="forminput2_tel" name="forminput2_tel" value="" tabindex="0" autocomplete="on" aria-autocomplete="inline" required="required" aria-required="true" placeholder="XXX-XXX-XXXX" title="Enter a valid US Phone Number: xxx-xxx-xxxx" aria-label="Phone" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" />
    <label for="forminput2_tel" title="Telephone Number">&nbsp;*&nbsp;Telephone</label>
    </div>
    <div>
    <input type="number" id="forminput2_number" name="forminput2_number" value="0" min="1" max="100" minlength="1" maxlength="3" tabindex="0" autocomplete="off" required="required" aria-required="true" title="Enter a valid Number: 1-99" aria-label="Number" />
    <label for="forminput2_number" title="Number">&nbsp;*&nbsp;Number</label>
    </div>
    <div>
    <input type="submit" id="forminput2_inputsubmit1" name="forminput2_inputsubmit1" value="Test" tabindex="0" form="forminput2" title="Press Submit to Test HTML5 Validation" aria-label="Press Submit to Test HTML5 Validation" />
    </div>
    <p><strong>Non-Recommended New Types</strong></p>
    <div>
    <input type="url" id="forminput2_url" name="forminput2_url" value="" tabindex="0" autocomplete="on" aria-autocomplete="inline" required="required" aria-required="true" spellcheck="false" placeholder="Enter a URL..." pattern="https?://.+" title="Enter a valid URL: http://..." aria-label="URL" />
    <label for="forminput2_url" title="URL">&nbsp;*&nbsp;URL</label>
    </div>
    <div>
    <input type="date" id="forminput2_date" name="forminput2_date" value="" tabindex="0" autocomplete="off" required="required" aria-required="true" spellcheck="false" title="Date" aria-label="Date" min="2020-01-01" />
    <label for="forminput2_date" title="Date">&nbsp;*&nbsp;Date</label>
    </div>
    <div>
    <input type="datetime-local" id="forminput2_datetimelocal" name="forminput2_datetimelocal" value="" tabindex="0" autocomplete="off" required="required" aria-required="true" spellcheck="false" title="Datetime-Local" aria-label="Datetime-Local" />
    <label for="forminput2_datetimelocal" title="DateTimeLocal">&nbsp;*&nbsp;Datetime-Local</label>
    </div>
    <div>
    <input type="time" id="forminput2_time" name="forminput2_time" value="" tabindex="0" autocomplete="off" required="required" aria-required="true" spellcheck="false" title="Time" aria-label="Time" />
    <label for="forminput2_time" title="Time">&nbsp;*&nbsp;Time</label>
    </div>
    <div>
    <input type="week" id="forminput2_week" name="forminput2_week" value="" tabindex="0" autocomplete="off" required="required" aria-required="true" spellcheck="false" title="Week" aria-label="Week" />
    <label for="forminput2_week" title="Week">&nbsp;*&nbsp;Week</label>
    </div>
    <div>
    <input type="month" id="forminput2_month" name="forminput2_month" value="" tabindex="0" autocomplete="off" required="required" aria-required="true" spellcheck="false" title="Month" aria-label="Month" />
    <label for="forminput2_month" title="Month">&nbsp;*&nbsp;Month</label>
    </div>
    <div>
    <input type="color" id="forminput2_color" name="forminput2_color" value="Enter hex color value..." tabindex="0" autocomplete="off" required="required" aria-required="true" title="Color" aria-label="Color" />
    <label for="forminput2_color" title="Color">&nbsp;*&nbsp;Color</label>
    </div>
    <div>
    <input type="range" id="forminput2_range" name="forminput2_range" value="50" min="1" max="100" minlength="1" maxlength="3" tabindex="0" autocomplete="off" required="required" aria-required="true" title="Slide the Range Indicator" aria-label="Slide the Range Indicator" />
    <label for="forminput2_range" title="Range">&nbsp;*&nbsp;Range</label>
    </div>
    <div>
    <input type="submit" id="forminput2_inputsubmit2" name="forminput2_inputsubmit2" value="Test" tabindex="0" form="forminput2" title="Press Submit to Test HTML5 Validation" aria-label="Press Submit to Test HTML5 Validation" />
    </div>
    </fieldset>
    </form>
    Input Types List







    Checkbox


    Radio


    Hidden

    <input type="hidden" id="forminput_hidden1" name="forminput_hidden1" value="one" aria-hidden="true" tabindex="-1" />

    Special Input Attributes

    Below are examples of special attributes used with 'input', and which are either widely supported by browsers or add value.

    • disabled="disabled" - This attribute must be spelled out as such to support XHTML. Disabled text or buttons cannot be changed and will never submit data to the server. It is for viewing only by users. There is universal browser support for this attribute. Notice I set "tabindex=-1" so the user does not tab through disabled form fields. I also added a matched ARIA "aria-disabled=true" attribute for screen readers.
    • readonly="readonly" - This attribute must be spelled out as such to support XHTML. Read-only text cannot be changed but will be submitted to the server. There is universal browser support for this attribute. Notice I set "tabindex=-1" so the user does not tab through readonly form fields.
    • required="required" - This attribute must be spelled out as such to support XHTML. Required text means the form field must be filled out with some data by the user or an error will be generated and the submission will fail. In most HTML5 browsers, adding "required" triggers validation of an empty field or with pattern matching of the data entered. When it fails a "bubble" alert appears instructing the user of the error. Note: In Internet Explorer, the browser also adds whatever text is in the "title" attribute to the end of this bubble message. So, you can essentially customize the error message, where Firefox and Chrome will add their own data type errors based on the type of form field input("email", "url", etc.). This attribute can be overridden by add the "novalidate=novalidate" on the form or form field. It's good to also add a matching ARIA aria-required="true".
    • pattern="[A-Za-z]{2}" - The "pattern" attribute value shown in this last 'input' element includes a "Regular Expression" (REGEX) pattern that entered text must match. It says to enter a alphabetic US state code two characters in length. I have also added "minlength" and "maxlength" attributes to further enforce the text values. These attributes are used to enhance "text" input fields for users and control data. If validation is enabled, most HTML5-supporting browsers will also enforce text to match the REGEX or other text pattern when submitted. These attributes will also work with many 'input' types, including "text", "date", "search", "url", "tel", "email", and "password". Please note that there is still limited browser support for the "pattern" attribute, so do not depend upon it. Note that even without the new "pattern" attribute added, many HTML5 browsers have built in pattern matching for several types, like "email", "number", "url", etc. They will provide a warning if the type of text entered does not match the minimum character string requirements. But it is still a nice additive feature that can fail and not harm the user experience. Just remember to always validate your 'inputs' with scripts and server processes, as well as pattern matching.
    • hidden="hidden" - In modern HTML5 browsers, a form field element with the added "hidden" attribute will not be seen by the viewer but remain an active form field. Note: Remember, if your browser does not supports HTML5 your form control will not be hidden! The new "hidden" attribute is redundant, however, as there is a "hidden" 'input' type you can use instead which is always hidden and always submitted. But, there may be rare cases where you just need to hide it. In those situations I recommend you use CSS "visibility" instead to hide things, as it will work more reliably in older browsers. If you use "display:none" to hide controls, remember the input will not be seen AND will not be sent to the server on submission, unlike the CSS "visibility" property or the "hidden" element attribute. See my section called "How to Hide HTML5 Elements and Content using CSS" for more information on hiding elements in HTML correctly.

    <input type="text" id="forminput_hidden" name="forminput_hidden" size="20" maxlength="20" value="This is Hidden Text" hidden="hidden" autocomplete="off" tabindex="-1" title="Hidden Text" aria-label="Hidden Text" />

    Non-Recommended Elements that Use 'input'

    The 'datalist' does not have wide enough modern HTML5 browser support to be usable with 'input' at this time. The 'output' element below is not supported in Safari, any Internet Explorer browser, or even Edge 12 (only supported in the newest Windows 10 Chrome-based Edge 13 browser.) So, I cannot recommend its user, either.

    The 'output' element (last box below) allows a user to use the "range" and "numeric" input types to combine values and then post the mathematical result to the new 'output' element box. But 'output' does not have wide enough browser support to be usable, and requires custom JavaScript to work when it does.

     +
     =

    *New HTML5 Input Types

    The New HTML5 'input' Element "types" listed below allow you to expand the type of data collection your forms provide your users, adding date/time features, numeric values, a color picker, search, and more. The problem is many browsers (like IE 9 or less, Safari, some phone browsers, and others) do not fully support them. If you use them, you will likely exclude a wide range of users who will fail to send you any data whatsoever. Because so many of the newer, more modern HTML5 browsers (and all the older ones) do not support these new form field types, its dicey implementing them reliably in web forms today, even with "hacks".

    For that reason, I have divided the ones I recommend and that are safe to use into one list, and the rest I do not recommend in another. All fields below have a full suite of custom attributes added, so you can cut-and-paste them into any project (use code listed above).

    I have added "required=required" to each of these new types and a submit button so you can try and submit their data, see if they work or validate, then review any bubble alerts HTML5-supporting browsers will create for you. You can then tab through each one and see if your browser supported these types and of they trigger validation on each new control. Again, these are built in HTML5 features that require no special scripts, CSS, or other tricks to work! Some HTML5 browsers will even validate by checking text formats for you using added "pattern matching" attributes that are built into the browser for those types (like with the "email or "tel" types below), while others will not know pattern matching and how to validate bad formats. Be sure to click the "Test" submit button below to see this HTML5 validation in action. It is one of the increasing number of built-in, value-added features of modern HTML5 browsers that are coming!


    Recommended New Types

    I recommend these new 'input' "types" below, though all have various issues in some browsers, and no support in older ones. Because these all collapse back to plain "text" types in older browsers, they are additive features you can safely use in your web applications which will not harm user interactions when not supported in their browsers. Be sure to add good JavaScript validation as well as server-side validation to all data coming in from these controls.

    Note: The "search" type typically has its own 'form' and 'submit' button separate from the larger web page. Extensive parsing and validation should be used by both scripts and the server to prevent SQL Injection and other security risks, and to extract out important text string combinations created by the user when typing search strings into "search" type text boxes. I recommend you enable "autocomplete" as I have done below to allow users to use previous search terms.

    Note: I have added the "pattern" attribute with a REGEX text matching pattern to the "email" and "tel" types below. In many modern browsers, the "email" type has built in pattern matching validation, anyway. "tel" does not. But I added my own for those that do not support it. This will only enhance these elements in HTML5 browsers, which will require user's text match a valid email or telephone address pattern when submitting data to the server. This feature has very limited cross-browser support, so do not rely on it to validate every time. I have also enabled "autocomplete". The same in the "tel" type. And in "email", it supports multiple emails using a comma separated list. So I have added "multiple=multiple" to add that support.

    Note: The "number" type should use "min" and "max" numeric values, plus "minlength" and maxlength" text values to control user input ranges on the text box. Again, this works well in newer HTML5 browsers, but will collapse back to a plain "text" type in older ones. Most new browsers support "number" except Internet Explorer. Even IE 11 did not show the number increment buttons. So, remember to always validate these fields for numeric values in older browsers that will allow alphabetic text to be inserted, creating form field errors.

    Be "extra" cautious using any of these new HTML5 types. Besides non-support of these features in non-HTML5 browsers, support is sketchy in newer browsers, too, and has been for years. Test in Internet Explorer 10-11, Edge, Safari, mobile browsers, and more. But always try and stick with the old reliable input "types" I have listed above, when possible.


    Non-Recommended New Types

    I do not recommend use of the new HTML5 input "types" below, as they are not only NOT supported in all older browsers but not supported in many of the newest ones, either. Those that do, have spotty support for both the 'input' "type" but also for pattern matching, So, essentially they act like "text" boxes, in most cases. Therefore, why not use the "text" type for most of these, then add JavaScripted validation and custom controls that apply to everyone? Some developers like to use elaborate "hacks" or scripted polyfills to force these "types" to work in certain browser versions. Thats poor design, as it still leaves out most web viewers! Only use these "types" if you are ONLY supporting the newest browsers and ignoring everyone else. An internal company "intranet" web application, where everyone has to use the same browser, would be a reason to support these, but not on the Internet. Personally, if something is "broken" in most modern browsers, like these are, why bother using them? Always rely on solid HTML you can count on in numerous browsers without extra scripting.

    * A typical web form is shown above.
    My Recommendations:
    1. The 'input' element defines a type of form control used for submitting data to the server. There are many types of 'input' element "types", including many forms of the classic text box, various buttons, and newer HTML5 types. I will discuss all those "types" of inputs in the code samples above and in the text descriptions below. The 'input' element has been around since the 1990's and in the earliest of HTML recommendations by the W3C. It has changed very little in the past 20 years, so is a bedrock form field element supported in all browsers and versions. As such, it can be safely used in all your web forms. Only the newest HTML5 "types" are sketchy.
    2. The Major 'input' Element Types: In the code examples above, I have listed all the various "types" of 'input' elements you can use. (The many new HTML5 ones I recommend are listed in the next section). These below have been around for over 20 years and 100% reliable. Because the code samples above showcase all the 'input' types possible, there is no need to list them below. However, below I will list a few factoids about the various "types" and their unique characteristics you might not know about:
      • The Four Button Types - There are four main "button types" you can use in 'input' elements to create buttons: "submit", "reset", "button", and "image". The "submit" and "image" types act like submit buttons, sending form data to the server. Note that the "image" type also allows you to replace a standard button with an image added via a "src" attribute and image path on the server. These types are always "submit" buttons, and when pressed will submit all form data as the normal "submit" type will. The "button" type does nothing until scripted. And "reset" buttons clear the form fields of all data. Note that the "submit" and "image" types have additional power over how, when, and where form field data gets submitted, beyond what the parent 'form' element says. Because of this submission power, they can override the 'form' attribute settings using new attributes, though I do not recommend you do that as it adds more confusion. These optional overrides are: "formaction", "formenctype", "formtarget", "formnovalidate", and formmethod". Note that these are rarely used, and are overrides of the parent form attributes. They only work when using the "submit" button types of 'input' (see the 'form' element for more details).
      • "checkbox" and "radio" - These unique types give you the ability to offer a multiple choice form fields to users. Checkboxes offer multiple selections of many, while radio offers only one selection of many. Both types of controls must all have the same "name" attribute value to group their values together (see my code sample above) when they are submitted to the server, along with their their text 'value' also submitted to the sevrer. So both send a "name=value" for every item checked or chosen. 'radio' types using the same "name" attribute value create a single choice multiple choice selection. 'checkbox' types using the same "name" attribute value allow a multiple choice selection, same as radio but with multiple possible values using the same name. You can also assign unique "name" values to checkboxes, which allow only one choice in each case, but still multiple, making each name-value more unique. Its more common for 'radio' buttons to have multiple inputs assigned to one "name" than the 'checkbox' type, where there are cases you might want to let users toggle a checkbox on or off which sends a unique name along with its value. Note that data submitted will only submit the items selected or checked, sending the "name-value" attribute to the server of those items the user actual chose, ignoring the rest. These are flagged in the browser, and sometimes on the server with an "on" flag. Some Firefox browsers persist a page as checked even on refresh, so always use "autocomplete=off" attribute on your 'input' elements to disable persistence (you will see that in my code samples above).
      • "text" - This is by far the most common and most popular of the 'input' element types. Any type of text entry you can imagine can be done using this simple "text" type. All the new HTML5 types, like "email", "tel", and "url" are variations on the "text" type. You can use various attributes to restrict the physical size of the box and limit its text entry. Use the "size" attribute to limit the physical text box's character size (default is "20"). Know that "size" only resizes the textbox, not how many characters a user can enter. To limit characters, you can use "minlength" and "maxlength" to control actual characters users can type in the textbox. Also use "placeholder" text to fill the box with gray-scale instructions for the user (like sample text), and "title" or a tooltip to help instruct users what should be entered into your text boxes on rollover.
      • "password" - This attribute value, like the text box version, has been around for years and is often used by authors in login screens. It does not come with any special features beyond hiding the password text. But over the years browsers have begun to assign "password" type text boxes special security features to harden them in the browser and to secure user data. You can also add the new "pattern" attribute to these types to try and enforce or validate early text entries by users. I like to add other attributes, like autocomplete="new-password", which is the same as "autocomplete=off", except this new version prevents most occurrences of previous passwords from showing up in Chrome browsers. You can add limiting attributes like "size=12", "minlength=8" "maxlength=12" (limits password to 8-12 characters) to control the allowable limits of characters used in password text boxes. Most add elaborate JavaScript filtering on top of "password" boxes to control stricter validation. But the extra HTML attributes really help. NEVER submit a form with a password using default form method of "get" for security reasons! Change it to "post". Otherwise, the password will be seen in plain text when submitted via the URL to the sever.
      • "file" - This is a very special type of 'input' that is also widely supported in browsers old and new. The "file" type allows uploads of files to the server and usually resides in its own personal 'form' element with "method=POST" and "enctype=multipart/form-data" attributes set in the 'form'. You must also add a "submit" button to your file upload form, which when clicked, allows users to choose files on their device and upload them to the server from a popup the browser provides. The server must have the ability to process the binary block data stream it will receive from these controls (see <form> for more details on "multipart/form-data"). The "file" input type also has a special attribute calls "accept", which allows you to control what types of files are uploaded by a user. In the code example above you can see how I have added "accept=image/*". This says to only allow images, but of any subtype or extension. The wildcard "*" attribute creates this "any" feature. There are many other arrangements of file types you can add to the "accept" attribute. I have listed a few below:
        • accept="image/jpg" - This input would only accept JPEG images which could have extensions ".jpg" or ".jpeg".
        • accept="image/*" - This input would only accept images, but of many types, including JPEG, PNG, GIF, etc.
        • accept="video/mp4" - This input would only accept MPEG-4 video files, which could have a variety of extensions and codecs.
        • accept="video/*" - This input would only accept video files, but of many types.
        • accept="audio/*" - This input would only accept audio files, but of many types.
        • accept=".pdf,.docx" - This example shows how you can enforce files by file extension rather than file type. Only Adobe Acrobat files with the .pdf extension, or newer formats of Microsoft Word Docs (2007+) would be allowed to be uploaded.
        • accept="image/*,.pdf" - This example shows how you can mix and match file types with extensions.
        • accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" - This example would allow a wide range of Microsoft word types and extensions, and shows how you can try and maximize coverage and upload of a given type of file (Microsoft Word documents) by adding all its older variations of extensions and types into the "accept" list.
        In HTML5, you can also set the "file" type to submit multiple files using the "multiple=multiple" attribute on the 'input' "file" type element. Note that some older browsers have buggy support for multiple file support, including IE version 1-9. As an added feature, my CSS style sheet used for this tutorial contains a very fancy style sheet, which redesigns the "file" type so it looks close to the same in numerous browsers, old and new.
      • "hidden" - (Note: This is not the same as the "hidden=hidden" attribute!) The "hidden" input type ("type="hidden") is not seen by the user (though they can easily see it under a page's "view source") and is often something many developers forget to use, or grossly abuse. It's often misused by new developers today and JavaScripted API's as a vehicle for passing values around because their server is stateless, they don't understand sessions, or they think they need to track each user exchange while ignoring the natural ability of servers to manage sessions. That means they use these "hidden" controls to pass large amounts of data back and forth between the client and server, including huge piles of sensitive and unnecessary information. Often this data is passed anyway by servers in HTTP variables or via cookies. I personally think all this is a mistake and a waste of time. If your server must track the user, but must not use the server to track users, yet must force all this data back on the client, what is to stop hackers from exploiting this data even with SSL/TLS? Adding huge data layers in the client then sending more and more hidden insecure data just increases the risk, as well as slows down page rendering. A BETTER use of 'input' in forms is to simply see it as stateless and letting web servers either not use session state, or manage all the state without use of the client. Try and use "hidden" inputs to pass tiny pieces of data your server cannot store in session but which aids identification of data or the user only, like a product or small user id. Your application is then free of cookies, user sessions, even TLS encryption, as the identification of a web page id does not depend upon sessions, encrypted values, or login data in most cases. One example would be passing a simple user ID or product ID so when data is passed back in say a form, the server knows what record is effected. Besides, using state should be as simple as a single session value anyway, not piles of hidden or encrypted data in a user's browser. But if you choose to use the "hidden" input type for your own purposes, know it is there. Just remember, "hidden" input types are really great places to pass back information that aids processing of a large form or a single record of data on the server, but not so good at storing multiple data records or sensitive data on the client.
      • Required, Disabled, Read-only, and Hidden - For any form field that must be filled out or selected, you must use the "required=required" attribute. Be sure to set any buttons or fields you do not want pressed or sent to the server as "disabled=disabled" in your inputs. Also, data you do want sent to the server, but not changed by the user should be set using the "readonly=readonly" attribute. For rare times you do not need to use the "type=hidden" input type, but simply want to hide an active 'input' control from the user, use the "hidden=hidden" attribute. Note: Always use the "XML-friendly" version of these attributes so your tags are always cross-compatible with both XHTML and XML. Do not use "readonly", but type "readonly=readonly".
    3. New HTML5 Input Element Types: There are many new HTML5 'input' element types and elements, as shown in the code above. Like the 'video' element, these new types remove the need for fancy CSS, JavaScript, plugins, or players to display these interactive components. The browser is now responsible for creating them internally, rather than using 3rd party products, DHTML, or JavaScript polyfills. For example: An 'input' with "type=color" would show a "color picker" popup created by the browser when clicked. No scripting needed! Try recreating that in JavaScript.
      However, even in 2022, support for these new input types is not complete in a number of browsers, including Internet Explorer, Firefox, and Safari. Generally, only Chrome or Webkit browsers offer close to complete support. Even Chrome has issues with some of the new types, however. For that reason and more, use caution when adding these to web projects.
      In the list below (and code above)I have created a list of the major new 'input' types available to you to use in your web forms. I have then placed a "(yes)" next to the ones I fully recommend you use, and nothing next to the others I do not recommend. Most of the "yes" ones are not supported in IE 9 or less and most older browsers, but are supported by everyone else. These "yes" types do have enough built in "fallback" control design to be functional. In all cases, these new types default to "text" type 'input' controls when not supported, so users can at least enter plain text if they are not supported. Some browsers support the new "pattern" attribute to enforce text and numeric data entry in the 'input' elements. But many of these still leave users in many browsers, old and new, lost not knowing what "format" the data must be in. That is why I recommend above, if you use the new 'input' types, that you follow up with carefully coded client-side and server-side validation.
      Most of the new HTML input types I do not support, as they have either no Internet Explorer, Safari, or Firefox browser support, their designs are broken, or they are missing control features necessary to function. There are many people posting solutions to those "broken" controls, which again, add cross-browser complexity way beyond the normal functioning of HTML. Most of these also, as mentioned, do fall back to plain "text" boxes. In many cases this might be enough. But if you want to use non-recommended types and are targeting older user agents, you would need to provide alternative designs and solutions for non-supported ones using very elaborate CSS and scripted solutions. You also would need to add validation and instructions on what data to enter. Because that adds very complicated CSS, HTML, and JavaScript to your projects, I recommend you stick with plain "text" type input controls, or just the handful of new 'input' types below I do recommend. Note: The HTML code for the 'input' types I do recommend are listed above in my examples. However, I have added the non-supported ones, too, so you at least can see how they might function in supporting browsers and can copy some code to help you get started.

      New HTML5 'input' element "types"

      • color
      • date
      • datetime-local
      • email (yes)
      • month
      • number (yes)
      • range
      • search (yes)
      • tel (yes)
      • time
      • url
      • week
    4. Always Wrap a <form>: Element Around Your 'input' Elements: When you wrap a form tag around a submit button 'input' control, it tells the browser your submit button is associated with a specific form "id" value and will only submit the field elements associated with that control. If you have multiple forms of forms and form fields to submit in a web page, it is crucial you know what input button submits which forms. You can still place the 'input' submit button element outside a form, if you give it a 'form' attribute with value associated with a specific form "id". 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 the right data when submitted.
    5. Always Use the <label> Element with Your 'input' Element: Try and use the 'label' element before or after your 'input' tag, then add the "for" attribute with a value that matches the input's 'id' value to associate the two together. This links the label to the 'input' or form field and allows the browser, search engines, and screen readers to connect the two, adding semantic meaning. Always add a 'title' attribute to labels with a description of the field in order to associate the label with it. This is just good usability. Often, the browsers will float the label text beside the form control, with minimal CSS design changes needed to position it (see my code samples above for examples of labels and inputs). Additionally, in most browsers "clicking" on the label's text auto-selects the 'input' text box, giving it focus for fast data entry!
    6. Collecting Form Field Data Using Inputs: The process of using 'input' and other form fields to collect and process data is way beyond the scope of this tutorial. Know that 'input' controls manage maybe 95-99% of your data collection in typical web forms today. As such, the single most important aspect of good form field design (beyond HTML) is validation. That is discussed in-depth in the 'form' element section. The main thing to understand about forms and form fields is that data collection is the single most complicated aspect of web design, simply because it requires so many levels of exchange, validation, processing, analysis, and storage. Data collection and processing of 'input' elements data is way beyond the scope of this tutorial. Just know, I have built dozens and dozens of large data collection applications in my life-time, and I can tell you good data collection always begins with solid HTML design, not fancy JavaScript, not fast REST API's, not secure server processes, not relational databases, and not fancy business applications. HTML is always King simply because HTML is the gateway between your users, your server, and your database.
    7. Always use the 'id' and 'name' Attributes: Always use 'id' and a matching 'name' attribute with the same value when possible on all 'input' elements. The one exception is the "checkbox" and "radio" types which must all share the same name so they are grouped. The 'id' affects client-side scripts that must access a unique 'id' on the form field in order to access the control and its data. But 'id' is never sent to the server, unlike 'name'. If there are multiple inputs, it is critical each have a unique 'id'. This value must be unique for each element in the current web page. As mentioned, I like to always match the 'id' value to the 'name' attribute (except for checkboxes and radio types), as I do in all my other form fields. Why? The 'name' attribute is what is always sent to the server, along with the input's "value" attribute. Assigning both 'id' and 'name' to the same value helps your server-side processes identify which 'input' you are processing and align the 'input' with any client-side scripted validation or pre-processing that uses the 'id'. If the two attribute values match, it's very easy to locate and sort client-side from server-side processes if all the values are the same. Also, in form fields the 'name' attribute is often parsed first as it is used when building name-value form field key-value pair data system sent to the server on submit. So, be sure to give each 'name' a unique value, match the unique name to the 'id' element, and be sure to put both first in the element!
    8. Always Use the 'value' Attribute: The 'value' attribute is what is sent to the server as data, and part of the "name-value" attribute pair sent to the server from your input control when a "submit" button is pressed. Always add "value" as an attribute on all your 'input' elements, even if empty, as it controls what data is sent to the server for that control. In some cases, "submit" button types and "hidden" types will have a static, predefined string for 'value', while "text" 'input' types will have a user-entered one for "value". In some cases its important to add a "dummy" value to help define a form field control when say a "submit" button is pressed by the user and sent to the server as a "name-value" pair along with the other form fields. You may want to know what button was pressed and the "value" would be sent along with the name to help identify it on the server when it receives all the name-value pairs for the form. In the case of the "checkbox" type, each box checked will always send the same "name" for all the fields in the group, but with a different values. So make sure each value is unique, as you have to loop through the same array of names to get each value selected. The data for checkboxes with multiple boxes checked will appear like this: mycheckbox=red&mycheckbox=green&mycheckbox=blue.
    9. Always Assign a 'tabindex' Attribute Number: Almost all browsers, old and new, add 'input' elements to a "tabindex" list. This means that all interactive elements are available for tabbing through by a user in the browser as they fill out larger forms. You really do not have to add this extra attribute to your 'input' elements or worry about this feature as it's built into all modern browsers. Most of the old ones, as well new ones will logically add all your form fields and buttons to a tab list. Nearly all form fields, links, and buttons are added to the tabindex, by default. However, you can manipulate this to change the tab order of your 'inputs', remove a input control from the tabindex, or add one that was missed by using the "tabindex" attribute. I always add the "tabindex=0" attribute to all my form fields to enforce addition of each control to browser's tabindex, which also lets the browser reorder everything, naturally. I add "tabindex=-1" to remove fields from the tabindex I do not want included. "hidden" types fields are never added to the tab index anyway, but I add the "-1" value to all other interactive form controls I don't want users stumbling across (including disabled fields, read-only fields, etc.). You can also granularly control tabindex by setting each of your controls to a specific number in an order, like "tabindex=2", and set the specific order you want your users to use. You can also set "autofocus=autofocus" to force focus immediately to a specific 'input' button, button, or other field. This overrides the natural tabindex, however. Remember, the browsers also automatically assign the ENTER/RETURN key to the first available "submit" button type in the web page. So, again you don't have to override these features in browsers unless you want to change tab indexing. "tabindex" and "autofocus" can help enrich your 'input' controls and add more control over how you intend users to use your web forms. (See my code samples above which use "tabindex", and read my section in this page called "TabIndex and Autofocus in HTML" for more details on "tabindex".)
    10. 'image' Type Attributes: The "image" type of input allows you to create a submit button which uses an image for the button. To enable this feature you will need to add three additional attributes: "src" for the image URL on the server, then "width" and "height" for the image dimensions. Be sure to also add the same dimensions in your CSS and other styles for more control over the final image button design. This works like the 'img' element, and allows the image button to reserve space in the rendered page for the image while it downloads. Important: You must add "alt" attribute to "image" types, like 'img' elements use. Of course, add a tooltip or "title" attribute and ARIA, as well.
    11. Optional 'placeholder' Attribute Text: The "placeholder" attribute is a nice place to add special grayscale text inside text boxes which assists users with the type of data they must enter. Use this with the 'title' or tooltip attribute to assist users with data entry formats.
    12. Optional 'autocomplete' and 'novalidate': I discuss these two attributes in more details under the 'form' section (see <form> for more details), as the form really controls this setting over all its child 'input' fields. But often you will have a 'form' with default settings and want to override them in each form field. The two most difficult ones to manage are "autocomplete" and "novalidate". In general, to summarize, the code samples above showcase my "best practices" and recommendations for how each field should use these two attributes.
      I do not like "autocomplete", but sadly the default in form fields and in browsers is the "on" setting. This means when a user sees a form field in another website with a similar "name" attribute value as yours, it tries to pull a dropdown list of previous text choices for the user to choose from, which they entered in previous websites. I find this helpful, sometimes, but in the case of "logins" it is a terrible feature and a HUGE security risk! For that reason I ALWAYS recommend you manually add this attribute ("autocomplete=off") to EVERY form field and 'input' you have to make sure you turn autocomplete OFF and force users to ignore past text entries. For "password" you always want your users to enter fresh data into your forms fields, and NEVER reuse saved ones, so use "new-password" to disable this feature on password field. I like to remove this feature on most other inputs, setting the attribute "autocomplete=off" on each one. WARNING: Even after adding this "autocomplete=off" attribute, the browser often overrides this feature anyway, and gives users the previous options in a dropdown beside your form fields. But there are more tricks you can do as a page author to stop "autocomplete", as mentioned in the 'form' section of this page.
      As for 'novalidate', good news is it is "off" by default, meaning validation is always enabled by default, which in my opinion is a good thing as HTML5 browsers now come with a new array of validation checks and features. Again, see my 'form' section for more details on how these work and some additional tricks to force them to do what you expect. But if you want to turn off validation on a field and override the 'form' element's default value, you can add the "novalidate=novalidate" attribute to your 'input' element.
    13. Optional "autocorrect", "autocapitalize", "spellcheck": These attributes are really not widely supported. "autocorrect" only works in Safari browsers on Macs. "autocapitalize" is not supported in IE 1-11, Firefox browsers, Safari desktop, and possibly many android browsers. "spellcheck" I cover in the 'textarea' element, and does have wider browser support. But, rarely do you want to force users to correct typos. I have added most of these attributes anyway to many of the code examples for inputs in this page to DISABLE or turn "off" these features in browsers that support them. It is always best to disable any spell-checking, correcting, completing, capitalizing, or other "auto" features on form fields. This just gives the user the power and freedom they need to decide what data they are entering without interruption. But, if you find you need to channel your data entry users into highly filtered and customized data choices, try enabling these and see how they perform by browser and version.
    14. Do Not Use "accesskey": I do not recommend use of this attribute. Long ago, it was designed to allow keyboard presses to access form fields. But it is not reliable and requires various additional combinations of keys to work that are specific per device or just not accessible. It also conflicts with operating system shortcuts and could trigger other features on a laptop or phone by accident.
    15. Do Not Use "step": I do not recommend use of this attribute. The "step" attribute works with the following numeric input types: number, range, date, datetime-local, month, time and week. It allows you to try and control intervals of numbers entered, but is poorly supported and unreliable in browsers as is the new 'input' types it supports. Use JavaScript to control this, instead.
    16. Do Not Use New "inputmode": This new attribute is gaining in popularity, but still poorly supported in browsers. "inputmode" is now used as a "hint" to tell browsers the type of data to expect, like "email", "search", "url", etc. Because its not supported in IE, Safari, or Firefox browsers prior to version 24, it is not helpful or reliable.
    17. The Optional "data-" Attribute: As mentioned below in my "Best Practices" article called "The New 'data-' HTML5 Attribute", you can now safely use the new "data-" attribute in any HTML form element to store extra data values. Know that this is an extra attribute, and that "data-" values are not submitted to the web server anyway, so pretty useless. Its mainly an add-on for JavaScripted frameworks on the client-side.
    18. ARIA Attributes: The 'input' element is another "self-describing" structure recognized by most modern screen readers, and by its various "types" that help define its use. Most screen readers can read each form fields quite well, and understand an 'input' type's value. They can identify its semantic purpose that way. However, it is recommended you add an ARIA "aria-label={Name of Item}" on each 'input' element to give screen readers more details about your input's purpose and meaning within a form. You should also use the "aria-multiselectable=true" on "file" or "email" types that allow multiple file uploads or comma-separated emails, "aria-checked=true" for "radio" and "checkbox" types that are pre-selected, aria-pressed="false" for buttons that are not active yet, aria-autocomplete="inline" when "autocomplete="on" is used, and "aria-hidden=true" for the "hidden" input type. I would avoid "roles" attributes for most or all your 'inputs' as they are understood based on their "types". However, when delivering a "search form", "email", "file", or other specialized form submission, its advisable to wrap a specific form around these selective form inputs then add "role=search", for example, to the parent 'form' element. This "landmark role" tells screen readers the function of the input group and the overall form submission.
      You do not need the ARIA "live" attributes telling screen readers the "state" of your controls or buttons as they change unless you are manipulating the DOM using JavaScript. For example, "aria-pressed" and "aria-checked" do not need to be updated, unless you do.
      Use my code samples above to see "best practice" uses of ARIA attributes in 'inputs' when designing form fields that assist screen readers.
    19. Additional Input Attributes Supported: The list of attributes for inputs is extensive. Instead of listing all the combinations, I have added the attributes I recommend for each subtype of 'input' in the code above, including the new HTML5 ones. Just copy the code and you will have a great start using form 'input' controls with 99% of what you need as far as attributes, settings, and what is widely supported. In addition, below in "best practices", I have listed numerous examples of code using various attributes for input form fields and button types. Use those examples to help you understand what attributes work best in custom HTML situations beyond the norm.
      * Many deprecated attributes from the past still exist for 'input'. Avoid the following which either no longer work or which can be controlled with CSS now: align, height, width.
    20. The Optional Pattern Attribute: "pattern" is a new HTML5 attribute that allows you to assign a REGEX pattern to an 'input' element. When validated by the browser, it will check the user's entries to see if it fits within the pattern's constraints. The 'pattern' attribute only works when using the default validation setting on 'form' elements (no attribute), removing or overriding the "novalidate=novalidate" added to form fields, or when adding "required=required" to each form field. Note that the "novalidate" attribute added to forms overrides the "required" attribute on fields when added, so your forms will still not validate. When a "submit" button is pressed and "novalidate" is not applied, most modern HTML5 browsers will validate each form field and show bubble validation messages for any field either missing data when set to "required", or validate the text data that does not pass pattern matching attribute values. It will start with the first invalid field and show a bubble alert for each field that fails validation in this way. These checks include one bubble alert for empty required fields and then one for data entered but which is invalid, as defined by the pattern matching attribute. (Keep in mind some browsers come with their own built in pattern checking for certain 'input' types formats, like "email" or "url"). Note that Internet Explorer will add the "title" attribute text to the end of these bubble messages, so you can customize the error alert. The other browsers are better at showing additional data-specific error information, like whether the text is supposed to be in a "number", "email", "url", etc. format and is not. In this way, the HTML5 browsers often assist with validation using the "pattern" attribute or built in pattern matching using special regular expressions for each type of input added to your form. "pattern" is a new attribute in HTML5, so not very reliable or supported across browsers. I have found that "email" had the widest support for both browser native pattern matching and for support of the custom "pattern" attribute on the 'input' element. When supported, the "pattern" attribute works great in forcing allowing the browser to look at user data and make sure it fits a given text string format before data will be submitted or passed to JQuery or scripted validation. Because its non-intrusive and additive, if browsers do not support it, it does no harm. It adds value as no scripting is needed. Because of variable support in browsers today for patterns means there is one more reason not to rely on these new HTML5 additions and design solid validation on the client and server, instead.
    21. Form Field Validation: As mentioned above and in the <form> section, it is not enough to drop form fields like 'input' onto web pages and then hope the data coming into the server works. I have found too many cases where poor data processing ends up destroying a website! Even with fancy JavaScript, you cannot ignore the HTML design and server processing. That also includes heavy database scrubbing and processing. You need to always validate your form fields, no matter what the type, in ALL layers of your application. Do it not just to improve data collection, but for security reasons as well! Data validation is not part of the scope of this tutorial but is native to the specific language, framework, network, and database architecture you are using. Don't rely on a single product like JQuery (JavaScript) either. Rely on good server-side validation, always, but good HTML design, too. It will help the user get the data right on their end without waiting on elaborate scripts to warn them later. Getting the HTML design right helps them navigate your forms faster, and makes it much easier for them to enter good data. Good HTML means it's one less layer you have to wrestle with. And it frees up control of data entry to your users, not your script libraries or your server.
    22. See the <form> element section for more details about this element within a form.
    <ins> insert

    Insert

    see also <del>

    <p>Did you know my favorite pet is a <del>dog</del> <ins>cat</ins>.</p>

    Did you know my favorite pet is a dog cat?

    My Recommendations:
    1. The 'ins' element represents a piece of inline text that has been recently inserted. The 'ins' tag will draw a line under any text it wraps around.
    2. The 'ins' 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.
    <isindex> isindex

    Isindex

    <isindex prompt= "cats" action="http://google.com/" />
    My Recommendations:
    1. The 'isindex' element is a deprecated, non-standard HTML element once used to display search strings in a web page. It would be placed in the 'head' section of a page and used as a search prompt in querying the contents of the web page. It was rarely used and not used today. Do not use the 'isindex' element.
    <i> italics

    Italic

    This is some <i>italic</i> text.
    This is some italic text.
    My Recommendations:
    1. The 'i' element defines a piece of "italic" text.
    2. Do not use the 'i' element, but use 'em' instead! Because 'i' is a purely visual element, use of its semantically important brother, <em>, is recommended instead of 'i'. You can also use CSS styling and 'font-style: italic' on spans of text segments if you just want a design change, but its not as search engine friendly as 'em'.
    <kbd> keyboard input

    Keyboard Input

    <p>Press <kbd>ctrl</kbd> + <kbd>v</kbd> to paste text in Windows.</p>

    Press ctrl + v to paste text in Windows.

    My Recommendations:
    1. The 'kbd' element represents a inline piece of text representing keyboard input or keyboard combinations. It often wraps around text that displays a key combination for a user to type. Often these were used in online teaching manuals, or computer instruction in web pages for keyboard triggered features (in the example above, I have applied CSS styles to add the "bubble" effect for 'kbd' text). This element is similar to <code>, <var>, and <samp> in that 'kdb' formats text to represent abstract computer programs, keys, equations, or ideas.
    2. 'kbd' and Screen Readers: This element has been around for some time, though rarely used. One reason is the fact there are few cases where instruction online in browsers uses or requires keyboard inputs. In that sense, 'kbd' only adds a little semantic meaning beyond its visual "monospace" display of keys in the text. The one exception is with screen readers, where such keyboard displays do have meaning beyond the visual. If you have a website where certain HTML is assigned "accesskey" attribute values (that are supported) with keyboard combinations, for example, and you intend to enable instruction for visitors and screen readers to use such combinations, then you might have a case for using 'kbd' elements. Often you can achieve much better design for "keyboard text" using CSS on say a "span" element. But again, that would not provide the same semantic meaning needed for non-visual readers as the 'kbd' element would. So, use 'kbd' on a case-by-case basis, as needed.
    <keygen> keygen, key generator

    Keygen

    <keygen id="securekey1" name="securekey1" challenge="abc123" keytype="DSA" keyparams="somekeygenstring" />
    My Recommendations:
    1. The 'keygen' element represents a new HTML5 "hidden" form field designed to hold a public encrypted key. When this was sent with a form, it was designed to provide a client page a secure way to connect to a private key on a server and to communicate with its web-based certificate system, creating a secure connection for data transfer. This element is now deprecated, no longer supported by most browsers, and no longer used in HTML5.
    2. The 'keygen' element is no longer used, so I will not discuss its attributes and features. I do not recommend its use at this time.
    <label> label

    Label

    <form id="forminput" name="formlabel" method="post" action="#" title="Label Example" aria-label="Label Example" autocomplete="off" autocapitalize="off" spellcheck="false">
    <fieldset id="formlabel_fieldset1" name="formlabel_fieldset1" form="formlabel" style="background-color:#fff;">
    <legend style="background-color:#aaa;color:#fff;">Label Example</legend>
    <div>
    <label for="formlabel_text" title="My Text Field">My Text Field</label>
    <input type="text" id="formlabel_text" name="formlabel_text" size="20" value="" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" placeholder="Enter text here..." title="Enter Text" aria-label="Text" tabindex="0" />
    </div>
    </fieldset>
    </form>
    Label Example
    My Recommendations:
    1. The 'label' element represents an inline text element that displays text next to a form field or other element. The 'label' element is designed to not just label a form field but associate textual meaning to it.
    2. The 'label' element is associated with a form field using its "for" attribute. The value of the "for" attribute is associated with the "id" value of the form field, connecting the two together. Always add a 'title' attribute to your label with a description of the field associated with the label. This is just good usability. As such, the 'label' element really does not need any additional attributes.
    3. Special Features of Labels: 'labels' have been around since the 1990's and were part of the first W3C recommendations. They are a powerful way to associate a span of text with a given form field element, giving it a label. For starters, labels can be associated with many types of form fields (input, textarea, select, progress, meter, etc.). Second of all, screen readers will often read out the label text when the form field is given focus. The connection between a form field and its text label also means you can "click" the label and it will automatically move your cursor into the form field (i.e. text box), giving it focus. Traditionally, its best to add the label BEFORE a form field. In the case of the "checkbox" and radio" 'input "types", its always better to add the label AFTER the element. Most browsers will align the label text perfectly centered, right, or left of the form field. You can also add a break and have the label text sit ABOVE the form field (good in 'select' controls).
      Some developers wrap the label AROUND the form field element, and so avoid using the "for" attribute. This was how we used to associate labels with text boxes, then struggle with CSS to center the label text. Today it is a BAD IDEA as it not only makes aligning label text difficult, but breaks the connection between the two. Also, many times form fields are block-level elements that should not be inside the an inline label element. Note: I often change my 'label' element selectors in my CSS "reset" style sheets to use "display:block-inline" so they sit next to form fields but act like block-level elements and have dimensions and positioning I can manipulate.
    4. I highly recommend you get in the habit of adding a label for EVERY form field you create, even it is not needed, as it adds important semantic and descriptive meaning to your forms. For more example of labels with different for fields see the <input>, <select>, and <textarea> examples in this HTML5 list.
    <layer> layer

    Layer

    <layer id="mylayer">Some text content</layer>
    Some text content
    My Recommendations:
    1. The 'layer' element is a deprecated, non-standard HTML element once supported in Netscape 4 Series browsers and used to position and content separate from the main web page content flow. The 'layer' and 'ilayer' element in Netscape browsers acted like a form of 'div' or 'iframe' alternative. It was rarely used then and is not used today. Do not use the 'layer' element.
    <legend> legend

    Legend

    see <fieldset>

    <form id="legendform" name="legendform" action="#" method="post" aria-label="Login">
    <fieldset id="legendfieldset" name="legendfieldset" form="legendform">
    <legend style="background-color:#ccc;color:#fff;">Login</legend>
    <p>
    <label for="legendinput1" title="Username">Username: </label>
    <input type="text" aria-label="Username" id="legendinput1" size="20" maxlength="10" value="" title="Username" tabindex="0" />
    </p>
    <p>
    <label for="legendinput2" title="Password">Password:  </label>
    <input type="password" aria-label="Password" id="legendinput2" size="20" maxlength="10" value="" title="Password" tabindex="0" />
    </p>
    <p><button id="legendsubmit1" aria-label="Submit" aria-pressed="false" title="Login" tabindex="-1" disabled="disabled" aria-disabled="true">Login</button></p>
    </fieldset>
    </form>

    * Note: The box around the form fields is the 'fieldset'. The "login" text is the fieldset's 'legend'.
    Login

    My Recommendations:
    1. The 'legend' element is a title that appears inside a fieldset in a web form. It is often used to present a text title inside a box that labels a group of form fields, and appears in the upper left corner of a forms's fieldset box. Note: It is recommended you use multiple 'fieldsets' with 'legends' if you plan to have multiple 'submit' buttons or subsections inside your forms.
    2. Every 'fieldset' should have a 'legend'. The legend always appears just inside the parent 'fieldset' element and is used to add a title or caption at the top of the fieldset block. As such, it is helpful when identifying sections of your form. The 'legend' text title is placed on top of the fieldset box/border line, though you can style it to appear anywhere or any way you like. (In the example above, I have added a gray background to my 'legend' and left it at the top left). The 'legend' allows you to give each section of your form a title explaining what that form section represents. In giant data entry pages online, this is extremely helpful as it breaks up a form for users. Users can then fill out data in sections and submit partial or complete parts of larger online forms as they finish them.
    3. Visual Problems with Legend: There are some minor visual issues with 'legend', 'fieldset', and its design layout in some older browsers. Typically, the 'legend' text sat on top of the 'fieldset' box border. This border often had a background color with the 'legend' box text floating on top of the border removing its lines from the fieldset box, but not affecting the background color. Some browsers added a gray background for the fieldset which then bled the background color of the 'fieldset' box under the 'legend' text, creating an ugly display. Other browsers allowed text to jump in or outside of the 'fieldset' box itself, pushing the text on top of the fieldset line. To prevent this, either leave the default CSS and background of the 'fieldset' as set by the browser (often white like the page), set the 'legend' background to a color that sits over 'fieldset' background color completely (as my examples do), or just set the 'fieldset' background to "transparent". All these solutions will allow the 'legend' text to float between the fieldset lines and ignore the background color underneath.
    4. Browser Support: 'legend' has wide support in nearly all browsers, old and new. So, it is fully supported.
    <li>,
    <ol>,
    <ul>
    list, ordered list, unordered list

    List

    also see <dl> and <nav>

    I have combined the three main elements that control lists below: <ul>, <ol>, and <li>.

    There are three main "types" of lists: Unordered <ul>, Ordered <ol>, and Description <dl>. We will demonstrate the first two here. Description lists <dl> are shown elsewhere as they have unique sub-elements and perform a slightly different role in HTML. You may also see how to style unordered lists to build a "menu" in the <nav> section of this page.

    Shown below are examples of "unordered" and "ordered" lists. Both types use the 'li' child element to hold "list items". Unordered lists can be in any order, so their bullets or icons are generic types. Their list items can be arranged in any order. Ordered lists are numbered in an ordered sequence. I have also included "nested" lists below so you can see how nested lists work, and how the bullets change in style using the browsers default bullet styles.


    Unordered List

    
    <ul id="unorderedlist1">
        <li>List item 1 : Level 1</li>
        <li>List item 2 : Level 1</li>
        <li>List item 3 : Level 1
            <ul>
                <li>List item 1 : Level 2</li>
                <li>List item 2 : Level 2</li>
                <li>List item 3 : Level 2
                    <ul>
                        <li>List item 1 : Level 3</li>
                        <li>List item 2 : Level 3</li>
                        <li>List item 3 : Level 3</li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
    
    • List item 1 : Level 1
    • List item 2 : Level 1
    • List item 3 : Level 1
      • List item 1 : Level 2
      • List item 2 : Level 2
      • List item 3 : Level 2
        • List item 1 : Level 3
        • List item 2 : Level 3
        • List item 3 : Level 3

    Ordered List

    
    <ol id="orderedlist1">
        <li>List item 1 : Level 1</li>
        <li>List item 2 : Level 1</li>
        <li>List item 3 : Level 1
            <ol>
                <li>List item 1 : Level 2</li>
                <li>List item 2 : Level 2</li>
                <li>List item 3 : Level 2
                    <ol>
                        <li>List item 1 : Level 3</li>
                        <li>List item 2 : Level 3</li>
                        <li>List item 3 : Level 3</li>
                    </ol>
                </li>
            </ol>
        </li>
    </ol>
    
    1. List item 1 : Level 1
    2. List item 2 : Level 1
    3. List item 3 : Level 1
      1. List item 1 : Level 2
      2. List item 2 : Level 2
      3. List item 3 : Level 2
        1. List item 1 : Level 3
        2. List item 2 : Level 3
        3. List item 3 : Level 3
    My Recommendations:
    1. The 'li', 'ul', and 'ol' elements are block-level elements representing a list. The unordered list ('ul') and ordered list ('ol') elements hold child list items ('li') elements. These elements are used to show generic lists of items in HTML. You can also use the description list ('dl') for defining the meaning of list items, like in a dictionary. These more generic unordered and ordered list elements have been around since the early HTML days, and so are a reliable tool for sharing lists. HTML5 now supports them, as well.
    2. The Structure of a List: The child element, 'li', is contained inside the 'ul' and 'li' tags and is used to hold the list item text. The unordered list is for lists whose bullets and list items should not be numbered. The ordered list type is for lists that should be in a specific numbered order. You can have as many list items under each list type as you want, mix and match them, have any elements you like inside each list item (block or inline elements), any nested combination inside these lists, and can design lists in any way you prefer using CSS. Just remember to place all your 'li' elements under a parent list element and wrap 'li' elements around all content.
    3. The Semantic Power of Unordered Lists: Often, child list items in unordered lists can be used to do things beyond displaying simple text lists. They can hold lists of links as menu items, for example, or other non-typical elements and content that must be grouped. Lists can even be used for structural layout sections of a web page. Because the list is a powerful semantic "grouping" element, it allows you to go beyond its generic use as a simple text list and hold groups of similar HTML elements or content together. This assists end-users but also search engines and screen readers in associating list items with larger context and meaning. So, use unordered lists as often as possible in your web pages where you have groups of items that must be associated together.
    4. The Design of Lists: Lists often come with a style supplied by default in every web browser that shows numbers or bullets in a block-level indented design made to hold text. This style has not changed in over 20 years! So, I encourage you to use it as is. I often repeat the exact same bulleted list style in all my "reset" CSS style sheets when styling 'ul', ol', and 'li' elements. This allows me to force all browsers to use the exact same styles, bullets, margins, and padding for list designs across all browsers, old and new.
      You also need to know two features of lists. The first is, they are "block-level" elements, like 'div', meaning that they always have dimensions unlike paragraphs or spans, always have padding and margins, and always drop down to a new line. As such, consider lists as structural elements, which implies you can use them to create things like menus, navigation blocks, even page-level structures or sections of web pages. Just remember, lists are always grouping mechanisms, though the children under them are still part of the larger list structure. This means screen readers will create a permanent association semantically between all list items and the blocks of content inside them.
      Finally, understand that beyond the default bullets that decorate the 'li' items and the margins and padding most browsers apply, lists and their list item children have no real "design function". They are empty elements. In other words, their semantic "list powers" are more important than how they look on a web page. You can always strip away their bullets and padding using CSS. But their semantic powers remains. So, do not go designing elaborate styles on these elements, except when needed. But think of their real powers as residing in their semantic meaning.
    5. Supported List Attributes: The "id" attribute with a unique value is the only real attribute I would add to 'ul' and 'ol' list elements. This allows you to at least control the list using scripts, if you need to. The 'li' should have no attributes beyond CSS class styling.
    6. Non-Supported List Attributes: The 'li' element has one older attribute called "value" which allows you to set the current number of your bullet in ordered list items. However, I do not recommend its use and prefer you let the browser build the numbers for you. You can set a "type" attribute on 'ul' and 'ol' elements to control the bullet style. But, I do not recommend its use as CSS allows you to do the exact same thing using the "list-style-type" property. Do not use the "compact" attribute, either. In old HTML 4 you could use the "type" attribute to set bullets on ordered lists ("ol"). For example, "type=A" created a list with bullets that used uppercase letters (A, B, C, etc.). "type=i" created a list with bullets that used lowercase Roman numerals (i, ii, iii, etc.). But this has been deprecated. Use the "list-style-type" CSS property on ordered lists, instead. Most of these attributes are part of old HTML4 and are also no longer supported in HTML5. They can also easily be created in CSS.
    7. What Bullets Should you Use?: The 'ol' and 'ul' elements as mentioned historically have supported a limited number of bullets (pre-2001). However, over time many bullets have been added. But for maximum cross-browser support I recommend you start with the basics in your CSS that have support of bullet types from the 1990's then add your own. My Universal CSS Framework uses this basic list. older browsers also supported the following subtypes:

      Ordered Lists:
      1. decimal (primary)
      2. lower-alpha (primary)
      3. lower-roman (primary)
      4. upper-alpha
      5. upper-roman
      6. upper-latin
      7. lower-latin

      Unordered Lists:
      1. disc (primary)
      2. circle (primary)
      3. square (primary)
    8. ARIA Attributes: I do not recommend use of any ARIA attributes on HTML lists, as like with most HTML elements, they are self-describing and do not need to provide additional information to screen readers. You should only use the "role=list" and role="listitem" on non-traditional list items, like 'div' tags, if you use them as lists. In that one case, screen readers may not readily identify these elements are lists and need the "role=list" and "role=listitem" assigned. The one exception for adding ARIA on true list elements is if you use unordered lists for "menus" links inside 'nav' elements (see my <nav> for an example of using ARIA when lists are used as menus). These designs allow you to use unordered lists to display a styled set of navigation buttons in your web pages. In this case, you may use CSS to have their bullets removed, their margins and padding reset, and their block-level design altered to fit into custom menu designs or buttons at the top of your web page. In this case, the list item role has changed and you are using lists for a new "menu" and "menuitem" role in the web page. When you use lists for menus, you need to tell screen readers their semantic purpose has changed using ARIA. So visit the 'nav' element area mentioned above in this page for an example of how best to do that.
    9. Additional List Goodies: You can always customize the default "bullets" which come with 'ul' and 'ol' list elements by using the CSS property "list-style-type" property. My style sheet associated with this web page attempts to use the same generic list styles used by browsers for over 20 years (see the nested list example above to see the default bullets for a 3-nested list). These bullet designs generally change for each level of each nested list. But you can change those bullet designs any way you like, add custom image bullets, or remove bullets easily using CSS. No scripting required!
    <link> link

    Link

    also see <style>


    A 'link' element is a non-visual (invisible) element that resides inside the <head> element of a typical web page. Below I have listed a rich set of <link> code examples and the many ways you can use this element to enhance your website. Note that I have added the right mix of attributes to the code examples below, so you can cut-and-paste my code and get up and running fast knowing that my 'link' examples will work well in most browsers. You just need to replace the "href" URL values and other element attributes with your own values, in most cases.


    Link with Favicons

    Always include a "favicon.ico" link your website!

    <link rel="shortcut icon" href="favicon.ico" />

    Link with External Cascading Style Sheet

    This example below demonstrates the two most important use cases for the 'link' element in websites today: External CSS style sheets. Always include links to external style sheets in your website! Why? External style sheets are cached for days, weeks, or months by the browser and control the look-and-feel of thousands of pages in your websites, unlike their less efficient cousins, "embedded" styles using the <style> tags and "inline" styles in elements.

    <link media="print" rel="stylesheet" type="text/css" href="print.css?v=1.0.0.1 />
    <link media="screen" rel="stylesheet" type="text/css" href="style.css?v=1.0.0.1" />

    Link with External RSS File

    If you deliver news feeds of your articles or blog, you can link to your RSS XML file using the 'link' element below.

    <link rel="alternate" type="application/rss+xml" title="RSS" href="rss.xml" />

    Link with "Prefetch"

    Add resource prefetch call below to preload assets in other pages you hope users will access when they visit a new web page. These files will be cached, but implementation of the call is optional for the browser as these are flagged as low-priority. Note: Browser support of this feature is limited. See my recommendations below for more details.

    <link rel="prefetch" href="someresource.jpg" />

    Link with "Prerender"

    Add resource prerender call below to preload complete web pages and all their associated resources you hope users will access after the viewing the current web page. These files will be cached, but implementation of the call is optional for the browser as these are flagged as low-priority. If this feature is enabled, the browser will "switch" the page to the new page already rendered. Note: Browser support of this feature is limited. See my recommendations below for more details.

    <link rel="prerender" href="somewebpage.html" />

    Link with "Preload"

    The new "rel=preload" attribute works much like the "prefetch" and "prerender" types, except "preload" forces download of individual files (often style sheets) into the cache the minute the browser is available to do so. (i.e. its not optional, unlike with the other two types). I discuss how and why these preload features are used in more detail in my recommendations below.

    Use this version to add resource preload calls below to files you hope users will access after viewing the current web page. Unlike "prefetch" and "prerender", "preload" types must be downloaded and cached. An optional JavaScript "hack" below allows you to preload files in the current page and use them, as well, using a "media=print" to "screen" trick. Note: Browser support of this feature is limited and relies on JavaScript to work.

    <link rel="stylesheet" href="style.css" media="print" type="text/css" onload="this.media='screen';this.onload=null;" />

    Use this version to add resource preload calls below to files you hope users will access after the viewing the current web page. Unlike "prefetch" and "prerender", "preload" types must be downloaded and cached. An optional JavaScript "hack" below allows you to preload files in the current page and use them, as well, using a "rel=preload" to "stylesheet" trick. Note: Browser support of this feature is limited and relies on JavaScript to work. There is a fallback "noscript" for older browsers added.

    <link rel="preload" href="styles.css" as="style" type="text/css" onload="this.onload=null;this.rel='stylesheet'" />
    <noscript><link rel="stylesheet" href="styles.css" type="text/css" /></noscript>

    Use this version to add resource preload call below to files you hope users will access after the viewing the current web page. Unlike "prefetch" and "prerender", "preload" types must be downloaded and cached. This version only caches the file, but does not trick the browser into viewing it in the current web page. Note: Browser support of this feature is very limited.

    <link rel="preload" as="style" href="style.css" />

    Link with "Content Delivery Networks" (CDN)

    If you prefer to use CDN's (Content Delivery Networks) to deliver your CSS files (Bootstrap), you can use this version of the 'link ' element below that is designed to do just that. This version also demonstrates the use of the new "integrity" attribute that some CDN's require and which prevents "cross-origin" rejection by some browsers. Without this encrypted key value, some CDN servers or browsers might not allow you to access their server or files.

    <link rel="stylesheet" href="https://cdn.com/cssfile.css" onerror="this.onerror=null;this.href='local.css';" referrerpolicy="no-referrer" crossorigin="anonymous" integrity="sha384-..." />

    Link with "Canonical" URL's

    You can help search engines know the "preferred" URL design to use for all your web pages, using the "canonical" version of the 'link' element, as shown below. Notice in the example below, I am telling the search engines I want all links into my website to use the "https://" version or secure URL version, and without the "www" subdomain added.

    <link rel="canonical" href="https://mitchellstokely.com/" />

    Link with "DNS Prefetched" URL's

    Like "canonical" links, this "DNS prefetch" link version is also a new feature and optional. There is no guarantee it will help improve anything in your website. If it does work, it just attempts to establish connections faster with external URL's and resources online and solve DNS resolutions quicker. Note the use of the "missing prefix" URL (href="//..."). This tells the external web resource to pick either "http" or "https" for the correct prefix. Also, remember to add an ending "/" slash to the end of URL's as it often means one less call to the server!

    <link rel="dns-prefetch" href="//mitchellstokely.com/" />

    Link with "Preconnect" URL's

    Like "prefetched" links, this "preconnect" version is also a new feature and optional. There is no guarantee it will help improve anything in your website. It attempts to locate available browser connections early with foreign servers and connect with those external resources before they are needed. This can make for a slightly faster web page display when you use lots of external dependencies.

    <link rel="preconnect" href="//maxcdn.bootstrapcdn.com/" crossorigin="anonymous" />
    My Recommendations:
    1. The 'link' element appears in the head of a web page and is used to connect to an external file resource. It typically is used to download external CSS style sheets, link to extra web resources, or download external material a website might need in rendering its web page in the browser. 'link' elements have been around since the 1990's and have changed very little in the past 20 years. 'link' elements really began when CSS (Cascading Style Sheets) was adopted by the first web browsers. The first CSS-supporting browsers were Internet Explorer 3 in 1996 and Netscape 4 in 1997. So the 'link' element was supported in web browsers around that time. It is a reliable element you should definitely use.
    2. Types of 'link' Elements: Below is a list of 'link' examples and how you might use linked files and URL's in your website. These again would all appear inside the 'head' element of your web page, and are not visible to users. This list is not exhaustive, but does include examples of the most important ones you should use in your website. Coded examples of these links are listed above:
      • Favicons - Always include a "favicon.ico" (icon) link in your website! The "favicon" is a special ".ico" or other graphics file that appears next to any web page or URL shortcut in the browser. Its tiny image is just a few dozen pixels across and used to represent your website when listed as a bookmark or shortcut in web browsers. To help browsers download this icon file, a special 'link' element with a "rel" value or "shortcut icon" must be added. The browser will then download the icon image file from the server using the URL in the link and assign it as a shortcut image whenever one of your pages appears in a browser listing. Note: Most modern browsers by default search in the web root of your web site for this icon now without needing the icon link. So, this element is optional. However, I like to move all my images out of the web root of my websites and into my "images" folder in order to better manage them and switch them out as needed. So, using the link above is a better way to have to make sure the "favicon" gets installed in the browser for all my websites.
      • Cascading Style Sheets (CSS) - Always use 'link' elements with external CSS style sheets! Use of external CSS files to manage the design and layout of your website is a better option than most other style conventions. Why? External CSS is far superior to "embedded" (<style>) and "inline" element styles (<span style="color:blue;">my text</span>) simply because external styles downloaded to the browser are cached for every page in your website and affect all web pages, not just one. Often inexperienced developers use inline or embedded styles and forget about externally linked CSS sheets. They assume they are slower, inferior, antiquated, or difficult to manage when the opposite is true. They then lose out on valuable, reliable, proven technology that is far superior to anything built today. Links to multiple external CSS files also download in parallel to each other in a very quick fashion in most browsers, so there are few delays. Browsers have been doing this for over 20 years. Unlike large libraries of scripts, linked CSS often has a very tiny footprint and so has very little affect on page rendering or paint delays, simply because modern browsers manage these downloads very effectively and have been for decades. Once your CSS files are downloaded, they are cached and indexed in browser folders, allowing future page views of your site to be rendered and painted in the browser very quickly.
        When using 'link' with style sheets, always add an explicit "media" type as an attribute (see code example above). "media=screen" is the best value, which is used for desktop/mobile display. If you have developed a "print" sheet for your pages, add a separate "media=print" attribute and link for those, as well. Never combine "screen" and "print" CSS rules and selectors into a single sheet, by the way. That just confuses browsers. Besides, the various @media rules are not widely supported in older browsers, so will fail. As a side fact, "media=print" sheets are always asynchronously downloaded by the browsers, so are purposely delayed. They are not needed until a user prints a web page, so browsers do not stop rendering pages waiting for these "print" pages to download (see further discussions of this in my "preloading" information below).
        There are other media types, like "all", "handheld", "projector", "braille", "speech", etc. But I do not recommend you use any of these, as again, they all have poor browser support. Do not use "media=all" in particular. Why? "all" is dangerous to use for many historical reasons. "all" did not work in some older browsers like Netscape 4 Series and some very early Internet Explorer browsers. The "all" media type caused errors in those browsers when determining screen or browser style sheets, so most developers resorted to "screen" which today is universally supported in nearly all web browsers, old and new, as the default media type for web browser style sheets. The "all" media type also caused errors in many early versions of Mozilla browsers, for example, when combined with "title" use, triggering "alternate" styles (optional style sheets by the browser). Not good, so avoid "media=all"!
        By default, all linked style sheets are a "persistent" types of sheets, meaning, they are always applied to your web page's HTML until you offer alternative sheets for users to pick inside their browser. Your basic linked CSS sheets are by default always persistent as long as you do not add a "title" attribute in the 'link' element and leave off "rel=alternate", which you should always do (see my code sample above). You can provide one of the other two style sheet 'link' types for a user to choose from. These types are called "preferred" and "alternate". But I do not recommend you use any of them, as browser support is still poor. Most users do not ever "choose" alternate style sheets anyway. Almost all web users accept the "persistent CSS" files you provide them.
        Note that you can force removal of an external CSS sheet previously called from your server by the browser and cached by changing the URL in the "href" attribute to end with a unique or random query string value ("style?v=abc"). This will force the URL to have change in the browser and enforce a new CSS file download from the server. I recommend you control caching of your 'link' CSS files this way, and ask the browsers to remove their cache of your CSS files after every website update that occurs. You can easily do this by changing the query string "v" value inside the "href" attribute and adding a version number, random number, or changed text string to the end of its URL like so: "?v=1.0.0.1" (website version number) or "?v=20210605" (date or number value). These are not "magical codes". They just alter the "href" URL to the style sheet enough that the browser does not recognize the path associated with the file any more. This trick will force the browser to then clear its cache of styles for your web domain, renew the link, and re-download a fresh copy of your CSS style sheet, refreshing the look-and-feel of your website instantly.
      • RSS News Feed - Delivering a news feed to users via RSS (XML) is not as important as it used to be online, simply because news has increased in scope and speed online, using many other sources. In addition, mobile news via phone apps has replaced a large volume of the news feeds delivered online. However, if your site delivers such feeds, in the code above is an example of how RSS links are set up using the 'link' element.
      • Prefetching, Prerendering, and Preloading Style Files: In 2022, some in the web community have "suddenly" become concerned with how CSS loads in the browser. We have never had this issue the past 20 years......so what is the concern now? I will explain. With faster and faster fiber optic lines going to houses, and super fast 5G mobile bandwidth nearly implemented in all the towers, there is little proof of a few kilobytes of extra CSS causing web page rendering delays, blocking file downloads, or rendering DOM slowdowns. But some search engines and developers persist with their concern over "blocking CSS", despite the facts to the contrary that this is not a major issue. The real concern for slower web pages today is the fact many developers are downloading HUGE JavaScript API libraries to browsers to simply render a few lines of text! Yet, some new developers have become worried that 'links' of external CSS files may be blocking their megabytes of scripting files from downloading fast enough. This is simply not the case! (You can read more about my analysis of this point in "Why Do my Web Pages Take So Long To Download?" below.) The fact is, you should rarely if ever "preload" CSS or attempt to "hijack" the browser's natural ability to download linked CSS files. For starters, most modern browsers only allow 2-6 max parallel open connections from the browser to the server. Slow web host providers and networks is another bottleneck you cannot control that could affect your external downloads. Third of all, the 1-5 megabytes in a typical JavaScript API library download in web pages today is a waste of bandwidth. Downloading dozens of script files is much more of a problem than one or two tiny 10-50 kilobyte files of CSS. CSS files downloaded over 'link' elements has never been a big problem the past 30 years or it would have come up years ago in browser groups. In addition, CSS blocking capabilities are very fleeting compared to the wait time required for shared connections to open up in the browser. With fast optic cable upload and download speeds now, establishing a connection is more of a delay than the actual download speeds for most browsers. So, you should rarely worry about links and CSS slowing down your homepage's "first paint", as they love to call it. But if you are concerned about this issue, I will discuss use of these new attributes below.
        One way authors have started to cope with this issue is to use the new HTML5 "rel" and "media" attributes on 'link' elements to trick browsers into downloading files faster and in parallel with other processing running in the browser. They sometimes have minor performance gains in terms of browser speed in rendering web page CSS and HTML. The "prefetch", "prerender", and "preload" settings can be used in 'link' elements to force the browser into loading some style sheets asynchronously (delaying download) as secondary style sheets that might not be needed until later. The "rel" attribute specifies the relationship between the current document and the linked document. The "media" attribute defines the media "type" of the file being downloaded, which helps the browser prioritize and parse certain file types. Using the new "pre" features listed above allows you to now load resources, like CSS files, in the background when the browser connections are available, and without affecting synchronously loaded resources like CSS files that often download before the HTML does.
        When browsers load CSS synchronously, they temporarily halt all page downloads, scripts, and rendering while the CSS is downloaded and parsed. When this process is done, the HTML resumes its download, parse, and rendering phase like the CSS file. The browser then applies these downloaded and parsed style rules to the "render" stage, and with the HTML and builds the final painted DOM in the browser. Most of the time you want this feature to work as is, naturally, as you don't want unstyled HTML to flash waiting for a "preloaded" or delayed CSS file. But CSS in a 'link' element is placed in the head of the document before the 'body' element and its content HTML for a reason. Page order was designed this way on purpose. That is why browsers synchronously start downloading CSS first. Delaying HTML is to be expected in this model. Without the style sheets, page rendering would be delayed, anyway. However, in rare cases, certain large unused resources or style sheets can add additional wait time to HTML rendering. Using these preloading tricks to delay certain files can mean your HTML arrives slightly faster. It thus removes a slight delay in the page rendering by the browser. This is based on the fact some CSS is just not needed in your homepage, only in later web pages a user might visit. Or maybe its CSS that renders other parts of the page that are not critical. That then gave birth to the "preloading" concept. However, I don't recommend you use these features or ever async CSS this way due to limited browser support for "prefetch", "prerender", and "preload". In fact, most older browsers do not support these new attribute values, anyway. So, these features will fail. In many modern browsers support of these features are not implemented correctly, ignored, or not yet complete. I discuss this problem below.
        Prefetch: You can download files, styles, web pages, or other resources before a browser or user needs them in another page or location in your website using this feature. This is helpful when you might want to pre-load a large batch of images or styles in your web site before a user clicks a link to visit the a web page that contains them. The browser will call such resources down and store them in cache until needed. However, its not reliable. Some browsers may wait till the browser is completely "idle" or simply ignore these calls (Firefox). By then, a user could have clicked a link to your page needing this cache and instead find an unstyled page. But, when this works it can speed up external pages a user might visit. Just realize some browser could ignore or fail to download such files. Note: No Safari desktop or iPhone, IE 10 or less, or Opera mini browser supports this feature. So use sparingly.
        Prerender: You can also choose to prerender or download a whole web page and have it rendered and ready to view before a user chooses to click a link. This has the effect of caching everything on other pages a user might access from the current page. This feature, when supported, creates the DOM, styles the page, and executes any javascript in the page, as well. When a user clicks a link, the new page is supposed to be "swapped out" for the current page. At least, that is how it is supposed to work. Be careful as this can affect the current page's connections to the server, the browsers CPU usage, and resource access should data on the other pages be very large and take up too many processes in the user's current web page. You also have to be sure a user will visit one of these prerendered links before deciding to so. How do you know? Note: No Firefox browser, Safari desktop or iPhone, or IE 10 or less browser supports this feature. Only Chrome, Opera, and the latest IE11/Edge support this. So use sparingly.
        Preload: This attribute value for "rel" is very much like its cousins, "prefetch" and "prerender", except the "preload" version cannot be ignored by web browsers, is not a low-priority call as the others, and the browser MUST download the resources called into the browser cache as soon as the opportunity becomes available. This makes this attribute a little more reliable as it forces the browser to load style sheets, images, and other files behind the scenes until needed. As with the other types, this has the effect of placing everything downloaded this way into the browser's cache (unless of course, this feature is not supported in the browser).
        Developers in 2022 have started to use "preload" to solve two main problems: The first is to force cache of resources needed in other web pages before a user visits them (traditional use for external pages only) with a much higher guarantee they will be there. But they have also started to use this technique as a "hack" to force some of their secondary style sheets in the current page to download asynchronously in the background while the HTML downloads, preventing additional "blocks" of the page render process. The web page is thus available much quicker for the rendering of the DOM in the current page. This first strategy forces the browser to cache resources for other web pages, while the second type applies them to the current one. Both types only works if "rel=preload" is supported in the browser. But I offer an alternative "media=print" strategy for the second type that works much better without "preload". In my code example below, the first type of external resource download and caching strategy is shown using a traditional "preload" call to a file:

        <link rel="preload" as="style" href="style.css" />

        Note: No pre-2018 Firefox/Safari, Internet Explorer 1-11, or Opera Mini supports this "rel=preload" feature, including a range of Android browsers. So use sparingly.
        The second type of "preload" use is now being used to affect the processes in the current page of a typical site to hide secondary media or files that might be needed but which block the main CSS style sheets and HTML from being rendered. In these next two examples, you must implement a series of JavaScript "hacks" to "trick" the web browser into preloading your style sheets in the background (a form of asynchronous download) then switching it back to its normal synchronous state so its available by the browser for rendering HTML in the current web page and all others a user might visit. When the files are complete, they are accessed immediately by the browser and available for use. They are just queued up for download or delayed. In this latter use of "preload", if you are concerned one or more of your style sheets may be "blocking" page rendering in the current page, and you do not need the style sheet immediately, you can delay the file's download by using one of these two tricks below. The first one avoids the "preload" feature (since its has poor browser support) and uses a very old "print" media trick to delay the file download much as a print sheet would do. When the file is downloaded, JavaScript switches the style sheet link back to a normal type. the second example tries to use a normal "preload" but also uses JavaScript to switch the file back to a normal style sheet accessible by the browser when its complete. This second version has less support in browsers:

        <link rel="stylesheet" href="style.css" media="print" type="text/css" onload="this.media='screen';this.onload=null;" />

        <link rel="preload" href="styles.css" as="style" type="text/css" onload="this.onload=null;this.rel='stylesheet'" />
        <noscript><link rel="stylesheet" href="styles.css" type="text/css" /></noscript>


        These bits of code trick the browser into loading the CSS files quietly in the background when the browser has an available connection. This then removes one more delay caused by these secondary CSS files that are not immediately needed in rendering the web page. The primary CSS in normal links now download slightly faster into the browser in parallel with the HTML, without these other sheets "blocking" or delaying them in some way. But this only benefits you if these secondary CSS files are so large they delay downloading before HTML downloads and renders. In most cases CSS still load in parallel with HTML just fine, even if its delivery begins before HTML starts. Unless it uses up all available connections, this should rarely occur. In the first example above, the "print" preload version asks the style sheet to perform as a delayed "secondary" print style sheet. All browser delay print sheets by placing them into a queue where they download last and only as connections become available, which is often AFTER the web page has been rendered in CSS and HTML. So, this trick would would be used more often for delivering styles not needed in the primary page render. For that reason, people often move style rules that are not critical to the rendering of the homepage out of the primary "screen" sheets and into these secondary "tricked" ones so they are not part of the DOM render and paint delay. The main idea here is to speed up viewing of your homepage web page for new visitors coming to the homepage by just delivering enough styles to display it quickly, while delaying the ones not needed right away in the main synchronous style sheets. The problem is style sheets are so tiny in size, that this trick has almost no real positive effect. In the second example above we use the true "preload" setting, but switch the "rel" to "stylesheet" after the file downloads. Like the "print" version, this secondary file now performs like a normal style sheet and is available to all web pages including the current one, after the JavaScript switch. The disadvantage here is that "rel=preload" does not have the same reliable support in browsers as "media=print" does, so is likely less effective.
        The idea in preloading all these files, then switching to using them in the current page, is to not make the browser wait for these files before rendering the HTML tree in the DOM. But that is rare. All these tricks force all such style sheets in your homepage that do not affect initial rendering and paint of the home page to download quietly in the background, asynchronously. That would have some minor advantage if you had a large number of very large style sheets loaded in your homepage. But often loading external style sheets does not delay rendering site-wide as other pages will now access these cached external sheets for the rest of the user's experience with your web site. That could be thousands of web pages that use that one set of CSS files you asked your user to wait a few milliseconds on your homepage. The trade off is more that fair!
        Again, ask yourself if preloading resources like this is worth the risks? Eventually, simply downloading the asset normally without preload overpowers the risk of this failing in non-supporting browsers or running more elaborate scripts so you can shave off a few fractions of a second of download time. Some people today try and speed parsing of linked CSS files which always must load synchronously before HTML, anyway. Using "preload" to trick the browser into loading the styles later then switching it back to synchronous status to prevent a small amount of extra CSS text seems like a convoluted way to gain minimal advantage. I don't recommend you load CSS using "preload" for that reason, and due to limited browser support in 2022 for "preload", and the fact these tricks could fail in some browsers. Again, failure is older browsers is the main point of contention, here. If you are inside a network and choose to use these tricks, you will have much better success. If you really look at what these developers claim is an issue in modern web pages using external linked CSS, it really becomes an attempt to help a narrow subclass of "special" users who get frustrated waiting on their new phones a few hundred milliseconds for anything to appear (which are generally people that have attention problems or who are adrenaline junkies). It is another reason to avoid this "preload trick" as it has zero affect on both page rendering and the majority of normal web users today. Worst of all, it runs the risk of failing and screwing up your style sheets and web pages. You might end up with NO style sheets in some older browsers! All this is just more "bloated JavaScript" shoved down the throat of the browser, anyway. If this was ever a problem long ago when we had very slow 14.4 (kbit/s) baud rate modems over crackly phone lines we would have caught this "blocking" issue, as would have numerous web browser vendors. So, trust me, its not a problem! Your linked CSS files work fine as is. Always rely on solid HTML5 first before relying in these "hacks".
        One other point must be made on this "preloading" of linked CSS files. It appears that Google's new Lightspeed page ranking system up until now encouraged web developers to fix web pages for faster download speeds in the browser to reduce wait times to milliseconds. But recently they flip-flopped from page ranking based on speed to a form of content-based ranking (the old search engine model). The fact they now have flipped back and forth from page rendering speed concerns to a more content-oriented ranking shows they are struggling to manage heavily JavaScripted websites without a solution other than to demand web site owners ignore the JavaScript download disaster and try and squeeze blood from a turnip and force us to check every little external file and image download for speed improvements, while ignoring the 1-5 Megabytes of scripts being pushing over the wire and into the browser. This is their attempt at trying to rationalize page rank away from the actual website content rewards in order to cope with the ever-increasing layers of Angular JavaScript now clogging up the search engine bots, which directly delay most of the search engine performance, anyway. So, the problem is not your tiny Cascading Style Sheet files, my friend. Demanding authors squeeze every millisecond from tiny CSS file downloads through minimization and other preprocessing, while rationalizing use of these gigantic multi-megabyte scripted frameworks, shows these corporations know they have helped "gum up" the World Wide Web with more bad web application technology, instead of making it better with simpler, faster browsers and search engines.
      • "Content Delivery Networks" (CDN) - Many new developers love to throw around the idea of using a "CDN" or external service on the Internet for all their CSS and script files rather than hosting a handful of tiny CSS text files on their own hosting platforms. If style sheets and scripts are not sitting on their own servers and are free elsewhere, the thought is, this is a great idea, right? The idea that you don't have to host anything when its free on someone else's server seems genius at first, but its not.
        The problem is this solution divides up your website's external files and creates huge dependencies that can fail, destroying the display of your website. CDN's can also be slow, hacked, down, insecure, or simply block your IP at any time, preventing your site from getting critical CSS files it needs to render properly. You might say that's never happened. But it has! And as security increases online, it will. So, I do not recommend using CDN's.
        If you can host your own giant JavaScript files and HTML, why cant you host your own CSS, I wonder? Some say CDN's are faster, but it seems pointless and lazy if you do not trust the speed and reliability of your own host provider. But if you want to try this CDN "trick" and rely on externally hosted CSS files, simply use the CDN code sample above, then replace it with links to your favorite online CSS library. I have added an extra BONUS script in the 'link' element above that maps back to your personal backup copy of the script if the "Content Delivery Service" URL fails. Also, this code sample version uses the new "integrity" attribute that some CDN's require (private encrypted key) and which prevents "cross-origin" rejection by some browsers and servers. Without this encrypted values some browsers might not allow you to use these unknown and unverified cross-domain, externally hosted files (some of which could contains viruses, by the way).
      • CDN and referrerpolicy="no-referrer" - Use this attribute and value if you want to block the external CDN sources from getting your user's referrer or source information. This blocks the origin data sent to their servers, which shows up in their logs every time a visitor of your web page uses one of the video or files imported into the iframe. Note: If this prevents you from accessing the external file, then you might have to remove it.
      • "Canonical" URL's - You can help search engines know the "preferred" URL path to use for all your web pages, using the "canonical" URL version set in a 'link' element. Some people are concerned about duplicate web pages and search engines seeing different versions of the same web pages accessed with different URL's. Search engines will punish you or lower your ranking in search engine listings if they see too many duplicate links to the same page content with different URL's. To help prevent that, you can tell search engines and the browser what the "preferred" or base URL all pages in your site should use via a special "canonical" link. This does not affect your page's actual URL or links, and is optional. Its just tells search engines the base link to use for all your pages so they do not duplicate the same content and punish you in search rankings if you use various URL formats. This is especially important if there are secure and non-secure URL's in your website links, like "http://" and "https://". In most cases, search engines figure this out naturally, so this 'link' format is not required.
      • "Prefetched" URL's - Like "canonical" links, this "prefetch" version of the 'link' element is also a new feature and optional. There is no guarantee it will help improve anything in your website. The first thing most modern browsers do as they load your HTML page is determine if there are any outside domains associated with external URL's or page resources added in your website. If so, to access each resource, the user's browser often must do several request-response calls, including a separate DNS lookup and connection for each resource before calling its actual file. An example of this problem is the CDN link and URL above. These domain lookups can delay requests of content (very slightly) as they must often resolve via foreign DNS servers first. If your site has lots of these calls, you can add these special links and list multiple domains at the top of your page in the 'head' element. Consider adding multiples of these new DNS lookup links, one for each foreign domain used, to force a preload of DNS resolutions early, which can speed up your page as it requests resources later. If your pages are chocked full of advertisers or other foreign URL's, adding these prefetch links may really help. Just remember most browsers today only have a half dozen open connections max, so you are limited anyway. Also, HTML5 support for this type is still sketchy.
      • "Preconnect" URL's - You can "preconnect" to website servers as well to set up early handshakes and connections with servers before an HTTP request is actually sent. Often these external connections to unknown servers are slow, are stalled, blocked, or broken. Adding this feature, you hope to grab any available connections in the browser that are not downloading giant scripting libraries and try and make early "preconnections" to these foreign servers. You can even add "crossorigin=anonymous" or "crossorigin=use-credentials" and send your own credentials to help connect to these domains outside your own while avoiding the blocking cross-domain CORS issues that might occur later in a user's browser. HTML5 support for this is still sketchy, however.
    3. The Importance of Links and CSS: I cannot emphasize this enough: ALWAYS USE EXTERNAL STYLE SHEETS! I always use linked style sheets in all my web pages so they get downloaded one time and cached for all the pages in my website. Linked CSS sheets are fast, download in parallel with the rest of the websites connections, and help you manage styles better using large cached sheets. My own CSS framework of files includes a rich "reset" style sheet that overrides all browser UA default style sheets and reformats all browser elements and types to a common set of base element styles before applying my main classes on top of those element styles. It allows your pages to look clean and consistent across many old versions of browsers going back 20 years with no extra styling needed for older agents. So, I rely heavily on linked sheets and always avoid embedded/internal and inline styles.
      Old Browser Bug: IE3 used to remove all linked sheets but the last one listed in the head or your web page. So, I re-order my linked style sheets so my main CSS link is the last one listed, just to cover this issue or any browser that erases linked style sheets like this from my web pages.
    4. More on the "media" type Attribute: When downloading CSS files using the 'link' element, the browser is often quite sensitive to the "media" type attribute value you provide. The "media" attribute tells browsers the type of media or device your style sheet should be applied to and how your style sheet should be used for your device and parser. Most of the time this is the browser. The default is no "media" attribute, meaning your styles affect any and all devices (this is the same as "all", which means it works for all devices). In old HTML 4.1 the default was supposed to be "screen", but it seems many older browsers ignored this and set it to "all" implicitly. For HTML5 browsers today, the default is now "all", meaning your style sheet will be read by all types of devices. However, this is not the same as explicitly setting "media=all". It is almost always best to set it to "screen", which means your styles only apply to most computer or phone browsers. In the old days most browsers supported "handheld" which was for mobile only. But since PDA's and handheld Palm devices went out of style after 2008, this type is no longer used. Explicit use of "media=all" was supposed to be supported across browsers. But its use now excludes CSS files from being used in some older browsers like Netscape 4, IE 5-6, and some older browsers who do not understand what "all" means or fail to support "screen" when used. When using "all" in "@import" style sheet CSS calls, IE 4-7 will fail to load the style sheet. Netscape 4 series only supports no media type or "media=screen", and will fail to load the sheet if "media=all" is used. Note that Netscape saw "media=screen" as used for all devices, anyway. Support of "all" in "@media" media queries was also partially supported compared to "screen". "all" could mess up "print" sheets added later ,as some browsers fail to import styles when printing using "all". Because the "all" media type causes so many errors in so many older browsers, I recommend you always use "screen" or "print", which is universally supported in nearly all web browsers, old and new, and never design style sheets for all devices. That is why I am against "all" in the "media" attribute. I am for setting an explicit media type, only. But if you want to use a linked style sheet that can be seen by all devices, I recommend you simply leave off the "media" attribute from your 'link' tag, simulating a style sheet used by "all" devices.
      In the past, 'link' tags without a "media" and "title" attribute not only defaulted to "all" media types in some older browsers (not really "all" the string value, but just that the style sheet should apply to all devices), but meant your linked style sheet were seen by all media devices as optional or themed "preferred" sheets. So, if you did not want to limit your styles to just browsers ("media=screen"), but wanted to make sure a sheet is used by all media, you would leave off the "media" attribute and your sheets would affect all devices (both "screen" and "print", for example). If you instead tried to use "media=all" explicitly, because some older browsers did not know "all", it would fail and the browser would ignore the style sheet completely. Your pages then appeared without a style! If you wanted the "all devices" effect, your only trick was to not use "media" but suffer the fact your style sheet is not "persistent" as described above, but an optional "preferred" or themed sheet a user could change in their browser now. Another bad idea.
      Never add "title" attributes, either, as their presence changes your "persistent" sheet to one of the alternative or optional types that is often removed from your pages until a user chooses it. So again in summary, make sure your linked sheets never have a "title" attribute, always use a "media" type attribute, never use "all", and set it to "media=screen" or "media=print" to avoid problems.
    5. "Persistent" versus "Alternative" Style Sheets: Again, do not get confused by this information describing types of style sheets below, as it does not really matter as you should never use alternate style sheet systems, anyway. (You can skip this section if you like). But I thought I would explain some gotcha's when using 'link' element attributes, which you want to avoid.
      There's three different types of stylesheets that may be included on a page: "Persistent stylesheets" are the default and applied no matter which theme a user might choose for styles. "Preferred" stylesheets are themes stylesheets optionally applied. And "alternate" stylesheets are not applied by default unless explicitly chosen by the user. The latter two are user choices, so do not use them. Just use the default. You always want to use "persistent" (the default) and ignore the rest as support is spotty for anything other than the default. The only reason to use the others is if you decide to use an internal company website and offer users a rich set of CSS interface themes they can switch out to improve performance and usability in your web application. In that case I would use CSS "skins", not alternative browser style sheets you deliver, though. Users rarely if ever change style sheets in web pages, anyway.
      Use of the 'title' attribute on 'link' elements and "persistent" style sheets is what triggers your sheets to use the other two types as a "preferred" style sheet in many older browsers (not persistent, as normal sheets). So avoid it! Sheets with the "title" attribute added plus the "rel=alternate stylesheet" attribute triggers the "alternate" style sheet setting for your sheet that users can optionally choose when wanting to replace the "preferred" sheets. That is just one more reason to avoid those two attribute settings. To support this idea, older Mozilla browsers in the past always saw styles with just "title" as "alternate" styles, confusing things a bit more. So, my recommendation is always remove "title" attributes for all link tags and avoid the "rel=alternate stylesheet" setting. Removing "title" will make sure your links styles are always flagged as "persistent" types (default) in older browsers. Just use "rel=stylesheet" to make sure browsers identify your style sheet correctly.
    6. Cascade Order and Linked CSS: Does the order of linked style sheets in the <head> of your web page affect the cascade order of similar style rules on elements? It is an important question. It turns out it DOES in modern HTML5 browsers, but did NOT in many older browsers (pre-2010)! Why? Older browsers used to have a very good rule the W3C used to require they follow. It basically said that no matter where external <link> styles appear in the <head> of your web page, "embedded" or <style> CSS was always last in the order set inside the browsers cascade memory, not in your web page. In other words, embedded styles always cascaded over linked styles using the same selectors, even if you placed external linked CSS AFTER embedded CSS in your web pages. Linked external CSS elements always came before embedded CSS in the memory of the browser, no matter what physical order your code used. This is NOT the case in newer HTML5 browsers, I found out. This might be a subtle issue to you, but if you stack lots of "element" style rules in your external and internal style sections of your web page 'head' element, rules that use the exact same selectors, if you do not order your linked external CSS elements correctly then you might see some cascade over others, unexpectedly in newer HTML5 browsers! Order of styles now matters in your pages, where in the past it did not. The reason newer HTML5 browsers now strictly honor specific style sheet "source order" in the "head" of your page, regardless of linked vs embedded types, is because HTML5 has gotten lazier and looser in defining such things. In other words, be careful in the order you place linked and embedded styles, as they do matter today. Embedded sheets no longer have higher source order over linked sheets, as they did in the past. To match old and new browsers so they both work the same using external and embedded sheets, ALWAYS add your linked sheets (<link>) above your embedded ones (<style>) in the head of your page.
      Unfortunately, newer browsers today using HTML5 decided to ignore W3C and Web Standards, so now order matters. This is counter-intuitive, so I recommend you follow the rule above and you will have no issues with CSS cascade order going forward in any of the browsers you support.
    7. Avoid All Internet Explorer "Conditional Statements": In the long and troubled history of Internet Explorer and its support/non-support of HTML and CSS, many developers over the past few decades solved those cross-browser issues by hiding specific style sheets from all browsers but IE using special "Conditional Statements". In the past, many authors tried to address the numerous CSS bugs in Internet Explorer by using special code that hid certain linked style sheets from other browsers, but which were only specific to a version of Internet Explorer. Without going into the long history of this type of trick, I can say today this technique no longer works for newer IE browsers (version 10, 11, or the new Edge browsers). So, it is time to retire them completely. An example of such code is shown below so you know to avoid this code trick when trying to design CSS for older IE versions. This code below hides two linked CSS files that have special CSS hidden from all browsers but two older, specific Internet Explorer browser versions):

      <!--[if IE 8 ]>
      <link media="screen" rel="stylesheet" type="text/css" href="/styles/ie8only.css" />
      <![endif]-->

      <!--[if IE 9 ]>
      <link media="screen" rel="stylesheet" type="text/css" href="/styles/ie9only.css" />
      <![endif]-->

      * DO NOT USE THIS CODE! Because IE is nearly dead, plus IE 10-11 no longer supports these conditional statements. I do not recommend you use these IE coding tricks going forward, but instead cope with older IE versions using other techniques (I use a new CSS framework I built which uses "@import" rules IE 1-7 cannot understand and which hides my CSS style sheets from all IE 1-7 versions, giving these older browsers plain white HTML pages). Avoiding these custom page-by-page IE hacks means one less customization you now have to worry about in your web pages when dealing with the complexity of styling for older browsers using 'link' elements. (The ONE EXCEPTION to this rule is in my "Best Practices" section below called "How to Force New HTML5 Elements to Work in Old Browsers" where I encourage the use of IE Conditional Comments for forcefully adding missing HTML5 elements to non-HTML5 IE versions 1-8 browsers using a script.)
    8. The Myth of CSS @Import Render Blocking: The CSS rule "@Import" is often used to make additional calls to external CSS inside linked CSS files. A 'link' with @import calls to other external files is a very common practice and fully supported by all CSS recommendations today and 20 years ago. But sadly, some developers have started to demonize the practice unfairly, as a technique that causes "blocking" delays of other linked CSS style sheets. The fact is, this is completely false.
      When using the CSS rule "@import", the idea is to break up reusable CSS into files that can be delivered in pieces as needed. Often these CSS styles are placed into a single, parent linked CSS file so all the import calls are managed in one file. Once this parent CSS file downloads, any import style sheet calls inside are then made from the parent file. Some claim these calls then add additional download time as they are "render-blockers", meaning they cause some CSS to no longer download in parallel with the other synchronous sheets, like other linked sheets are designed to do. It turns out all that is completely false!
      In fact, multiple imported style sheets inside a linked style sheet all download in parallel relative to each other, with no blocking issues ever, and use shared connections for added speed in most browsers. The "@import" style rule only adds one extra call when combined with CSS styles inside the same parent sheet as the importing of other sheets must make one call in addition to the parent sheet call that holds them. Any delay here is on that one extra connection, not the import call. Thats it! The parent sheet that holds imports starts the new required connection then downloads all internal import sheets together as long as there is no other delays in receiving its own CSS. My sheets never have any additional CSS, only more imports. Only old Internet Explorer browsers had some inability to download imported files in parallel with other linked sheets. The main way to reduce render blocking is NOT avoiding use of "@import" CSS rules, but by using fewer external files and smaller files, like smaller images and less JavaScript. Most modern browsers have a default connection limit of 6 connections anyway, as I have mentioned, so parallel downloads of numerous imported CSS files does not speed up CSS if scripts or images are being downloaded in parallel via those few connections. "@import" isn't affecting parallel downloads of files as long as you avoid combining them with other raw CSS in the same file. I never do this, so using @import is a viable CSS strategy to use in connecting to multiple CSS files in your web page and to hide cutting-edge CSS3 from older browsers. The "myth" of these "blocking" claims has been exposed and should now be ignored. It is 100% safe to use @import in CSS linked files to download more CSS you might need without any worry of page render delays or blocking of other linked CSS files.
    9. Browser Support: 'link' elements have wide support in nearly all browsers, old and new. So, they are fully supported.
    <listing> listing

    Listing

    <listing>This element shows content that used to act like preformatted text.</listing>

    This element showed content that used to act like preformatted text.
    My Recommendations:
    1. The 'listing' element is a deprecated element once suppported in old HTML2. Because 'listing' is no longer supported in HTML5, do not use 'listing' but use the <pre> element instead.
    <main> main

    Main

    See also <header>, <nav>, <footer>, <section>, <article>, and <aside>
    <main id="main" aria-label="Main Content" >Main</main>
    Header
    Main
    Footer
    * A typical web page structure is shown above.
    My Recommendations:
    1. The 'main' element is new in HTML5 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 'main' element contains the text or primary content area of a web page. In HTML5, 'main' is part of a set of new structural page elements that define the overall layout of most HTML5 website pages designed today (<header>, <main>, and <footer>, etc.).
    2. The New HTML5 Structural Elements include: header, nav, main, footer, section, article, and aside.
    3. The New HTML5 Page Structural Elements: In the old days of the Web, the 'div' element was typically used in HTML to wrap around larger web page structures that defined major content sections in millions of web pages. To assist that feature, we often gave these 'divs' an 'id' attribute value of "main" or "content". These new 'header', 'main', 'footer', and other HTML5 layout elements have now replaced 'div' as the top level containers of your web content and structure. The 'main' element has no special attributes or design other than this new structural or layout semantic, and should perform like a 'div' or any block-level container element. However, like 'div', it can also be styled.
      Always use the 'main' element to hold all your main page content. Use 'header' for top-of-the-page logos and page navigation. Use 'footer' for secondary navigation, copyright, privacy statements, and other supplemental content listed at the bottom of your page. You no longer need to use the 'div' element for these layout sections, as before. Because 'main' and the others are universal structural elements in modern HTML5 pages now, you will see them appear in grids, flex boxes, and other CSS design and formatting structures. So, understanding their purpose and using them across all these different page frameworks is crucial to using HTML5's newest layout elements and thus fulfilling HTML5 "best practices".
    4. I like to always use a unique 'id' attribute with a value of "main" on my 'main' element so they can be recognized and manipulated by other designers using JavaScript. In the old days we used a 'div' with "id=main" to help us identify this these 'div' section from others sections quickly in a layout. So, this idea is simply a carry-over from that design concept.
    5. ARIA: The 'main' element is a top-level, "self-describing" structure recognized by most modern screen readers without additional assistance. In the case of 'main', it is recommended you add an ARIA label of "aria-label=Main Content".
    6. Cross-Browser Support: Older, non-HTML5 supporting web browsers (pre-2010) will not know what these structural HTML5 elements represent or how it should look. They have no design format by default, other than performing as a simple block-level 'div'. However, in older browsers, this element usually needs a CSS style so it does not float to the left or right of your other content blocks in non-HTML5 compliant browsers. Remember, most browsers that find an unknown element will set their CSS 'display' property to "inline", thus destroying the design of these new HTML5 layout elements. For this reason, in my "reset" style sheets, I always assign it a style of "display:block" and "float:none" to make sure these elements perform as a traditional 'div' in older browsers that do not support HTML5. But, I fully support the use of these new HTML5 elements in your web pages, despite their larger non-support in older browsers.
    <map> map, image map

    Map

    see <area> <p>(rollover the image map below)</p>

    <img src="images/www.jpg" width="255" height="200" usemap="#mymap" loading="lazy" alt="World Wide Web Image" title="World Wide Web Image" />

    <map id="mymap" name="mymap" title="World Wide Web Image Map">
        <area shape="circle" coords="80,130,40" alt="What is the World Wide Web?" title="What is the World Wide Web?" href="https://en.wikipedia.org/wiki/World_Wide_Web" target="_blank" rel="noreferrer nofollow noopener">
    </map>

    <ol>
        <li><a href="https://en.wikipedia.org/wiki/World_Wide_Web" title="What is the World Wide Web?" target="_blank" rel="noreferrer nofollow noopener">What is the World Wide Web?</a></li>
    </ol>

    (rollover the image map below)

    World Wide Web Image What is the World Wide Web?
    1. What is the World Wide Web?
    My Recommendations:
    1. The 'map' element defines an image map. It consists of 3 major pieces: An image, a map which defines click-able coordinates in the image, and a list of alternative hyperlinks for users that cannot interact with the image map.
    2. A matching 'img' element is associated with a 'map' element to create a click-able "image map" that allows users to click visual points in the image that link to other web pages with more detailed information. It is essentially a non-textual, visualized menu concept.
    3. In the 'map' element you can define specific "click-able shapes" as invisible rectangles and circles connected to visual elements in an image using the 'area' element inside 'map'. The 'map' element may contain a number of different area tags with shapes that defines different click-able areas in the image map.
    4. The 'usemap' attribute value of the 'img' element connects the image to the 'name' attribute value of the 'map' element. This creates a relationship between the image and the map.
    5. The 'id' is optional. But as with forms, 'id' and 'name' should both be defined here and with the same value in case one or the other is not supported in the browser.
    6. The 'coords' element defines boundaries in the 'area' element that control click-able dimensions in image map. Rectangular values use a pair of (x,y) coordinates for the top-left begin and bottom-right end points of a rectangular inside the image boundary. For a circle, the (x,y) coordinate defines the location of the center of the circle in the image boundary, with the 'y' being the radius of the click-able circle defined.
    7. Other attributes that are useful include the 'href' attribute which defines the URL location to visit when an area defined by coordinates is clicked. The 'target=_blank' attribute in 'area' forces a new browser window when clicked. I like to add informational text descriptions on rollover events using 'title' and 'alt' attributes on the 'img', 'map', and 'area' elements, as well.
    8. I have added an additional accessibility text link list under the map which can be hidden with CSS 'visibility:hidden' or 'display:none'. It is recommended by the w3c accessibility guidelines to add these links in some form as alternative hyperlinks for non-visual people or screen readers.
    <mark> mark, highlight

    Mark

    <p>Make sure you <mark>highlight every important topic</mark> listed in the document.</p>

    Make sure you highlight every important topic listed in the document.

    My Recommendations:
    1. The 'mark' element defines a piece of inline text that must be "highlighted" for importance, special interest, or reference. This element is new in HTML5 and represents text that is significant enough to the page or paragraph that it must have a colored background and stand out. This is often text taken from an original document where the author did not indicate the text was important, but the user did. This is different from 'big', 'strong', or 'emphasized' text which affect manuscripts where the original author has indicated text that is important. The highlighted color is often yellow, like a typical highlight marker would have.
    2. Most HTML5-supporting browsers will highlight the background of "marked" text with a bright yellow background color. You can modify this value in CSS as needed. Remember, all non-HTML5 browsers will not understand this element nor color it. That is one more reason to apply your own CSS custom rules to these elements to make sure the marked text has semantic as well as visual meaning in all browsers, old and new. A CSS example you can use to style the 'mark' element for old and new browsers is shown below. This is what most HTML5 browsers use, anyway:
      
      mark {
          display: inline;
          background-color: yellow;
          color: black;
      }
      
      
    <marquee> marquee

    Marquee

    <marquee behavior="scroll" direction="right" scrolldelay="85" style="color:red;">This is some text that should scroll across the page</marquee>
    This is some text that should scroll across the page
    My Recommendations:
    1. The 'marquee' element is deprecated now and was a non-standard member of old HTML4. 'marquee' used to create a section of inline text which scrolled across the page, slowly. 'marquee' could still work in modern browsers, but I do not recommend you use the 'marquee' element.
    <menu> menu

    Menu

    <button type="menu" menu="contextmenu" title="Click to Show a Context Menu">Show Context Menu</button>
    <br /><br />
    <menu type="context" id="contextmenu">
      <menuitem>Menu Item 1</menuitem>
      <menuitem>Menu Item 1</menuitem>
      <menuitem>Menu Item 1</menuitem>
    </menu>

    Below is a button that when "clicked" would normally trigger a context menu to appear. Instead, in most browsers, nothing will happen. You may just see a "box of text" which my style sheet system has tried to style on the 'menu' element so it looks presentable. But its not the toggled "context menu" you expect, as 'menu' elements are not currently supported in most browsers.



    Menu Item 1 Menu Item 1 Menu Item 1
    My Recommendations:
    1. The 'menu' element is a new HTML5 element representing a list of navigation elements a user can click or activate. It usually describes a collection of menus items grouped together, an unordered list of links or buttons, or a context menu that might appear on focus of button-click. Avoid use of this element as it is not supported in most browsers.
    2. Menu Features: Because the 'menu' element (and its child elements) are not supported by most browsers, I will not go over its features and attributes. Just know that the 'menu' element as designed today would support multiple 'menuitem' child elements inside it, as well as other HTML elements like unordered lists, etc. When fully implemented, it should also have attributes for controlling button-activated items, context menu displays, and other features.
      Most developers avoid this HTML5 element and use a 'nav' element to group HTML items together that look like menus when styled. They often use unordered lists ('ul') combined with anchors and CSS styling to create visually appealing "menu" tabs or buttons in their web pages. These types of menus now carry semantic meaning in screen readers, simply because they use HTML lists rather than just plain anchor links to order menu items. Additional JavaScript would then be added, or CSS pseudo-class events, to trigger dropdown "menu-like" effects. The 'menu' element had promise, as I think the original idea was to enable the browser to create menus for you that would replace all of the technologies listed above. But sadly, the 'menu' element has not matured enough to be usable.
    3. Do not use the 'menu' element, as it is experimental and was only supported in a small group of Firefox browsers in 2022. I think it has been fully deprecated in all browsers now. Use the <nav> element with lists, anchor links, and CSS styling, instead.
    <meta> meta

    Meta

    see <html>
    My Recommendations:
    1. The 'meta' element defines the various meta data found in the head area of a web page. See the <html> element for a full description.
    <meter> meter

    Meter

    also see <progress> <p>
      <meter id="meter1" min="0" max="10" value="2" title="Car Fuel Left as a Number" aria-label="Car Fuel">2 out of 10</meter>
      <label for="meter1" title="Car Fuel Meter">Car Fuel Left (number)</label>
    </p>
    <p>
      <meter id="meter2" value="0.8" title="Truck Fuel Left as a Percent" aria-label="Truck Fuel">80%</meter>
      <label for="meter2" title="Truck Fuel Meter">Truck Fuel Left (percentage)</label>
    </p>

    2 out of 10

    80%

    My Recommendations:
    1. The 'meter' element is new in HTML5 and defines a range of fractional values represented visually as a colored image bar. Note: Each browser displays this "bar" differently. Some may change the color of the bar based on low or high values. This element was designed as a simple way to graphically represent numeric data without complex scripting or 3rd party plugins.
    2. Because this new HTML5 element is not supported in any older browsers, Internet Explorer, or even Trident Edge, I cannot recommend it nor go into detail on its attributes. It does fall back nicely to text inside the 'meter' tags (as shown in the code examples above) when the visual element collapses. But many older browsers, IE, and Edge users will not benefit from that text without the supporting graphic display, which is its hallmark. When supported, the color changes by value vary by browser, or simply do not change at all. So, I would avoid use of this element as it's not widely supported. And when it is, it's implemented inconsistently. Therefore, it doesn't add much value.
    <multicol> multicol

    Multicol

    <multicol col="3">
      <p>Text column one</p>
      <p>Text column two</p>
      <p>Text column three</p>
    </multicol>

    Text column one

    Text column two

    Text column three

    My Recommendations:
    1. The 'multicol' element is deprecated but was a non-standard element used by Netscape browsers to create a multi-column, newspaper-styled text page. 'multicol' is no longer supported by HTML5 and is replaced with flex boxes and grids in CSS. So, do not use the 'multicol' element.
    <nav> navigation

    Navigation

    See also <header>, <main>, <footer>, <section>, <article>, and <aside>

    I have included a styled menu using an "unordered" list to demonstrate how you might use the 'nav' element in your website. 'nav' elements do not create menus or any sort of navigation. They are just placeholders for those things. Keep in mind its best to place the 'nav' inside the 'header' element (as shown below) so everything is managed in a clean, manageable, semantic HTML structure.

    <style>
    /* Here is a very basic menu style I created to show you what is possible inside a "nav" element. */
    .nav_menu {
    display: block;
    width: auto;
    height: auto;
    padding: .5em 1em;
    border: 1px solid #ccc;
    margin: .1em;
    text-align: center;
    min-width: 20em;
    color: #000;
    background:#fff;
    }
    .nav_ul {
    display: block;
    width: 100%;
    height: auto;
    margin: 0;
    padding: 0;
    border: none;
    background-color: #bbb !important;
    text-align: left;
    list-style: none;
    }
    .nav_li {
    display: inline-block;
    width: 8em;
    height: auto;
    margin: 0 2px 0 0;
    padding: 0;
    border: none;
    background: none !important;
    list-style: none;
    text-align: center;
    vertical-align: middle;
    }
    .nav_a,
    .nav_a:link,
    .nav_a:visited {
    display: inline-block;
    width: 100%;
    height: auto;
    margin: 0;
    padding: .25em 0em;
    background-color: #999 !important;
    border: none;
    text-decoration: none;
    text-align: center;
    vertical-align: middle;
    color: white;
    }
    .nav_a:hover,
    .nav_a:focus,
    .nav_a:active {
    background-color: #666 !important;
    }
    .nav_div {
    display:block;
    width:auto;
    height:auto;
    padding:.5em 1em;
    border:1px solid #ccc;
    margin:.1em;
    text-align:center;
    min-width:20em;
    color:#999;
    background:#eee;
    }
    </style>
    <div class="nav_div">
    Header
    <nav id="nav" aria-label="Navigation" class="nav_menu">
    Nav
    <ul id="menu" role="menu" aria-label="Main Menu" class="nav_ul"><!--removes space between inline-block elements
    --><li role="menuitem" class="nav_li"><a href="#" aria-selected="true" class="nav_a">Home</a></li><!--
    --><li role="menuitem" class="nav_li"><a href="#" class="nav_a">Page 1</a></li><!--
    --><li role="menuitem" class="nav_li"><a href="#" class="nav_a">Page 2</a></li><!--
    --><li role="menuitem" class="nav_li"><a href="#" class="nav_a">Page 2</a></li><!--
    --></ul>
    </nav>
    </div>
    <div class="nav_div">Main</div>
    <div class="nav_div">Footer</div>
    * A typical web page structure is shown above.
    My Recommendations:
    1. The 'nav' element is new in HTML5 and defines a navigational region of content, most often within the <header> element. Typically, the 'nav' element contains "navigational" elements or menu items that define the main links to other web pages located within a typical web application. Note: The 'nav' element does NOT create actual navigation or menus, it just holds such elements you create. In HTML5, the 'nav' element is part of a set of new structural page elements that define the overall layout of most HTML5 website pages designed today (<header>, <main>, and <footer>, etc.).
    2. The New HTML5 Structural Elements include: header, nav, main, footer, section, article, and aside.
    3. The New HTML5 Navigational Element: In the old days of the Web, the 'div' element was typically used in HTML to wrap around larger web page structures that defined major content sections, like navigation or menus. To assist that feature, we often gave these 'divs' an 'id' attribute value of "navigation" or "menu" in areas where we had buttons and links to areas inside our websites. The new top-level structural elements, like 'header', 'main', 'footer', and other HTML5 layout elements, have now replaced 'div' as the top level containers of your web content and structure. The 'nav' element is no different. It has no special attributes or design other than its structural semantic, and should perform like a 'div' or any other block-level container element. However, like 'div', it can also be styled.
      Always use the 'nav' element to hold all your menus, links, buttons, or other navigational elements in your page. It is best to place the 'nav' element inside a 'header' element at the top of the page, however, where most major navigational structures often appear. Note that the 'nav' element does not create navigational links, tabs, buttons, or menus. It is simply an "empty container" for those features you must create using other elements, styles, and scripts.
    4. I like to always use a unique 'id' attribute with a value of "nav" or "navigation" on my 'nav' element so it can be recognized and manipulated by other designers using JavaScript. It may seem redundant but it is quite helpful when you are accessing these elements using unique id's. In the old days, we used a 'div' with "id=navigation" to help us identify this 'div' section from other sections quickly in a layout, and describe its purpose in the code. So, this idea is simply a carry-over from that design concept.
    5. ARIA: When used the 'nav' element is a "self-describing" structure recognized by most modern screen readers without additional assistance. In the case of 'nav', it is recommended you only add an ARIA label of "aria-label=Navigation" to spell out clearly to screen readers this element holds the website's navigational elements.
    6. Good Navigation Practices: The 'nav' element is not a top-level element and so is optional. "nav" is a new HTML5 element and using it to contain and control your menus in the page layout is "good HTML practice". But when used, most designers typically add it to the 'header' element so it is contained inside the header at the top of most web pages. However, you can have multiple "nav" elements with different navigational functions in each. Because screen reader may get overwhelmed or confused by this, I do not recommend it. You should stick with one "nav" element.
      When designing navigation inside the header, most designers add "unordered" lists inside the "nav" element for their menus, then use CSS and pseudo-classes in CSS to control their design and any rollover dropdown menu effects, sub-menu displays, etc. These lists combined with the 'nav' element creates good semantic HTML. Search engines will index these unordered lists with anchor elements quite well. Besides providing a central location for users and search bots to access web pages, the 'nav' element also has structural meaning. All users and browsers will read and parse your parent 'nav' and its structured hyperlinks, creating meaningful connections between the navigation element and links to the interior of your website. Creating this navigational structure will thus enrich your HTML and its meaning.
    7. Cross-Browser Support: Older, non-HTML5 supporting web browsers (pre-2010) will not know what these structural HTML5 elements represent or how it should look. They have no design format by default, other than performing as a simple block-level 'div'. However, in older browsers, this element usually needs a CSS style so it does not float to the left or right of your other content blocks in non-HTML5 compliant browsers. Remember, most browsers that find an unknown element will set their CSS 'display' property to "inline", thus destroying the design of these new HTML5 layout elements. For this reason, in my "reset" style sheets, I always assign it a style of "display:block" and "float:none" to make sure these elements perform as a traditional 'div' in older browsers that do not support HTML5. But, I fully support the use of these new HTML5 elements in your web pages, despite their larger non-support in older browsers.
    <nobr> nobr, no break

    No Break

    <nobr>This text should not wrap</nobr>
    This text should not wrap
    My Recommendations:
    1. The 'nobr' element is deprecated but was a non-standard HTML element invented by older browsers like Netscape 1.1 to create text that does not create a line break like normal text. This tag is redundant as you can now control non-breaking text using CSS ("white-space: nowrap") and was also never a part of HTML5. So, do not use the 'nobr' element.
    <noembed> noembed

    No Embed

    see <embed>
    My Recommendations:
    1. The 'noembed' element defines a non-standard HTML element that offers a text message alternative to the <embed> element. This tag was mainly supported by old Netscape 4 Series browsers and was used to display a text alert message if a Netscape user's browser did not support the multimedia displayed in the 'embed' element. It is not supported by HTML5. See the <embed> element for a full description.
    <noframes> noframes

    Noframes

    see <frameset> and <frame>
    <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.

    <p>This frameset includes two page views of the W3C websites on frames.</p>
    My Recommendations:
    1. The 'noframes' element is deprecated now and was a member of old HTML4. A 'noframes' element was often used inside a 'frameset' parent element and would be displayed if frames were not supported in the browser, which may appear above. A simple text description of each 'frame' was often listed in an unordered list. In the past, framesets were a common way to combine, manage, and display many different web pages within a single web page. 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.
    2. Do not use the 'noframes' element now, as it is deprecated and was a member of old HTML4. HTML5 browsers will no longer support noframes much less framesets and frames. You might try the 'iframe' instead (see below):

      <iframe src="https://www.w3.org/"></iframe>
    <noscript> noscript

    Noscript

    Many people use 'noscript' to provide alternative content when JavaScript is turned off or unavailable in a web browser. But I like to use it as an "alert box" with a message for users to turn on JavaScript or upgrade their browsers. I like to use these message box at the top of every web page I build. Again, the 'noscript' element and its content is completely hidden in most JavaScript-supporting browsers but shown when they do not support scripting. As a BONUS, I also like to use a matching hidden 'div' alert box for browsers that do not support CSS style sheets, as well. Below is an example of both alert boxes. The style sheet version doesn't have a special element like 'noscript', but uses a simple style with "display:none" on it. Any old browser, like Internet Explorer 1-2 or Netscape 1-3, that does not support style sheets ignores the "display:none" that hides the 'div' content box and shows the full message, alerting them to get a new web browser. For testing purposes, I'm revealing the messages below without the 'noscript' element so you can see what it looks like. But the code snippet below has all the right code. You can cut-and-paste it into your project. Both boxes will be hidden permanently from all other browsers, until triggered and viewable in the non-supporting ones.

    Alert Box : No JavaScript Support

    
    <noscript>
        <div style="border:1px solid red;margin:.5em;padding:1em;background:white;" role="alert" aria-label="Alert Message: No JavaScript Support">
            <strong>Alert! You may have turned off JavaScript in your web browser, or it does not support scripting.</strong> As a result, some features in this website may not function correctly. Our website works best using one of the following modern web browsers: <strong><a href='https://www.google.com/chrome/' title="Download Google's Chrome Web Browser" target="_blank" rel="noreferrer nofollow noopener">Chrome</a>, <a href='https://www.mozilla.org/en-US/firefox/new/' title="Download Mozilla's Firefox Web Browser" target="_blank" rel="noreferrer nofollow noopener">Firefox</a>, <a href='https://www.microsoft.com/en-us/edge' title="Download Microsoft's Edge Web Browser" target="_blank" rel="noreferrer nofollow noopener">Edge</a>.</strong>
        </div>
    </noscript>
    
    Alert! You may have turned off JavaScript in your web browser, or it does not support scripting. As a result, some features in this website may not function correctly. Our website works best using using one of the following modern web browsers: Chrome, Firefox, Edge.

    Alert Box : No CSS Support

    
    <div style="border:1px solid red;margin:.5em;padding:1em;background:white;" role="alert" aria-label="Alert Message: No CSS Support">
    <strong>Alert! Your web browser does not fully support Cascading Style Sheets!</strong> Our website works best using one of the following modern web browsers: <strong><a href='https://www.google.com/chrome/' title="Download Google's Chrome Web Browser" target="_blank" rel="noreferrer nofollow noopener">Chrome</a>, <a href='https://www.mozilla.org/en-US/firefox/new/' title="Download Mozilla's Firefox Web Browser" target="_blank" rel="noreferrer nofollow noopener">Firefox</a>, <a href='https://www.microsoft.com/en-us/edge' title="Download Microsoft's Edge Web Browser" target="_blank" rel="noreferrer nofollow noopener">Edge</a>.</strong>
    </div>
    
    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.
    My Recommendations:
    1. The 'noscript' element represents an alternative block of content or alert message when JavaScript or other scripting is unavailable in the browser. A user agent or browser might have JavaScript disabled, turned off, or might not support scripting at all. In all those cases this HTML black would appear. Support for this element has been around since HTML and the birth of JavaScript in 1996. However, it was rarely used by most developers until the recent trend in using heavy client-side JavaScript API's.
    2. How to Use the 'noscript' Element: As mentioned, since the late 1990's, 'noscript' has been a powerful way to offer many browsers and user agents an alternative to JavaScript. The original idea was to allow browsers that chose to turn "off" JavaScript the ability to see alternative content or media inside the 'noscript' element. That was its original function. Back in the 1990's that was how I started using it. After 2001, we started noticing that on average 10-12% of visitors globally actually has JavaScript turning OFF in their browsers! That is a lot of people! So, that is when I started using 'noscript' for alert boxes. These 'noscript' alert boxes would be activated at the top of the home page of websites that had some level of JavaScript dependency. Visitors with JavaScript turned off would then see a white or red alert box telling them of this potential issue. They could then proceed into the website if they chose, or simply turn JavaScript on. It was a very nice feature to assist another subset of users that might struggle in your website without JavaScript enabled.
      Today, in 2022, we have an even worse problem! With the heavy, heavy use of JavaScript in websites today, there has been an up-tick in interest in the 'noscript' element. As a result, HTML5 has again implemented this very old element. Note that its assumed today everyone supports JavaScript but regular statistics posted online show a range of global percentages (most under 10%) showing a significant number of users regularly turn off JavaScript. If you are building web applications solely from JavaScript today, you must think again about that strategy if 5-10% of users globally cannot use your web product because JavaScript has been disabled in their web browsers. At least you have the powerful 'noscript' element to help you!
      In HTML5, you can now add the 'noscript' element in either the 'head' or the 'body' of your web page, allowing you to reveal large blocks of alternative styles or content for browsers that do not support JavaScript, hiding them from browsers that do. In the 'head' version, you can reveal custom styles that hide and show content for non-supporting browsers. In the 'body' version, you can reveal custom content or use it as an alert box with a message to users that your web page requires a JavaScript-enabled browser. I like to use the latter. An example of that is shown above. Note that all browsers, even very old ones, will support 'noscript' and HIDE the 'noscript' element and its content from browsers as long as ANY JavaScript is enabled in the browser. Remember to always add either a 'p' or 'div' tag around all content inside the 'noscript' element, as it has no style as is and is a hollow element.
    3. Some additional facts include: XHTML and XHTML5 polyglot does not support the 'noscript' tag, but HTML4 and HTML5, do support its use. So, be aware of that fact. Also, the 'noscript' element can be used in both the 'head' and 'body' elements. When used inside the 'head' element 'script' must contain only link, style, and meta elements. You can then use it to completely load new web page features or styles when JavaScript is not supported. In that way, if JavaScript disabled, one can style the page to show or hide all elements and reveal hidden messaging or information that do not require scripting.
    <object> object

    Object

    also see <param>

    <object id="object1" alt="object: Psychedelic Video" data="video1.mp4" type="video/mp4" style="width: 320px;height: 240px;outline: none;border:1px solid #bbb;" loop="false" title="Psychedelic Video" aria-label="Object File: Psychedelic Video">
    <!-- "params" are optional but supported by some older browsers -->
      <param name="movie" value="video1.mp4" />
      <param name="type" value="video/mp4" />
      <param name="play" value="false" />
      <param name="loop" value="false" />
      <param name="quality" value="high" />
      <param name="autoplay" value="false" />
      Sorry, your browser does not support this video.
    </object>

    Below is an example using the 'object' tag to play a movie file. Depending on your browser and the plug-in or player supported, you should see a "MPEG-4" file play. If you do not, it is because this video format or codec is not supported by your browser or its player. Note: Internet Explorer browser may not play this specific video codec, or may have ActiveX disabled.

    Sorry, your browser does not support this video.
    My Recommendations:
    1. The 'object' element is used to display a multimedia file in a web page, including an image, iframe, Adobe Flash, Java Applet, online document, audio, or video file. This element is supported in HTML5 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 'object' for specialized multimedia types only. Keep in mind 'object' relies on plug-ins and players to play its media unlike the other HTML5 media types. More details below.
    2. The History of the 'object Element: In the "good old days" of the World Wide Web (pre-2010), in order to display multimedia in web pages, play video games in browsers, run complex applications, play animations, show documents, and display other features online, you had to rely on 3rd party "players" in the browser: Java Applets, Adobe Flash, plug-ins, ActiveX objects (in Internet Explorer only), images, video, audio, Windows documents, and older 3rd party applications. 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. The browser would download these special applications then play or display these application files for you in a user's web page. JavaScript was unable to provide these features, nor the browser. Relying on 3rd party applications to deliver multimedia in the browsers was a great idea at the time, as HTML was never designed to do that. And security was yet a problem in most browsers. For over a decade, web browsers viewed millions of multimedia objects this way using plug-ins and players of many types. The problem was it later became a special channel for hackers, malware, viruses, and advertising to sneak in and infect a user's browser, or worse, the user's computer. That is one reason 'object' tags are decreasing in use and replaced by newer elements in HTML5 and scripted features. Security has simply become too big of a concern. 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 HTML5, 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' and 'embed' elements are dying too, even in modern desktop browsers. 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 (c. 2017) in all browsers, though it was once hugely popular as a choice for highly interactive solutions in thousands of desktop websites, at one time. (I actually used to write Adobe Flash animations and applications in Actionscipt.) This change has not stopped video, audio, or other applications from being embedded in web pages, however. HTML5 has simply come up with alternate elements where the players are built into the browsers that parse them. Keep that in mind. Yet the 'object' tag has remained behind to support the continuing growth of various multimedias online, which HTML5 has still not addressed. So, if you see these older elements, 'object' or 'embed', and are deciding to remove them or update them with HTML5, use the newer HTML5 elements and media types available instead ('img', 'picture, 'iframe', 'video', and 'audio' using MPEG4, WebM, etc.).
    3. So, why use 'object' in modern HTML5 pages? The 'object' element, unlike the 'embed' element, was a part of the HTML4 spec's. In fact, the 'object' tag has been around since the birth of HTML and the 1990's (it was used by Internet Explorer because IE did not support the 'embed' element, like old Netscape 4). Because 'object' became a universal element for IE browsers over the years, while 'embed' became a player element for all other browsers, 'object' often contained 'embed' elements which were used as a fallback to Microsoft's ActiveX 'object' version. (Internet Explorer 6-11 had limited support of the 'embed' element and always looked for an ActiveX 'object' element.)
      But 'object' is now strangely still a part of HTML5. Why? It was adopted early on mostly by Microsoft and Internet Explorer as a popular alternative to Netscape's 'embed' element, and to support their ActiveX control player. But over time, it went on to become the standard tool to add other types of specialized content into browsers, including Java controls and Acrobat documents, that no other element could offer. This is still the case today for specialized media. ActiveX and Java are now nearly dead as far as "player technology" used online.
      The 'object' element is still required to add instances of special media into web pages. Some types, like Adobe Acrobat document players, have built in browser support. So those files are readable without downloading a player in many cases. In other browsers, however, they may not be. So you need the 'object' element to show them inside a web page. As such, the 'object' element is designed to provide an infinitely extensible means of inserting specialized content into pages using HTML, where 'video' and other new HTML5 elements are not suitable. Know that you can still play many types of media using the 'object' 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, then attempt to load a player to display it or play the media with its own tools. Because of these crazy cross-browser issues using 'object', the deprecated ActiveX support, deprecated Java and Flash support, and the fact images, video, and audio can now be displayed in newer HTML5-friendly elements, there really is no reason to use 'object' EXCEPT to support specialized or older multimedia types. In addition, older browsers that still do not know the HTML media elements, like 'video', will still require 'object'. If you want to play movies in browsers created, say prior to say 2012, you will always need the 'object' tag. Most of the "other" media the 'object' element once supported have gone anyway and were driven away by deprecated multimedia players that have been discontinued years ago due to security concerns. Because 'object' requires download and activation in most cases of an outside "player" (or ActiveX control in IE's case) to display any media contained inside it, it's not recommended for video or audio in newer browsers. However, you may find a use case in newer browsers. One case for using the 'object' element is support of video in older browsers while using the 'video' element in newer HTML5 browsers. I wrote an example of some sample code for this in my article in this page called "How to Create a Cross-Browser Video in HTML5".
    4. Types of Media You Can Use in the 'object' Element: Besides video, you can use the object tag to insert all kinds of media into your web page, including images, iframes, audio, Flash, PDF, Word Docs, and more. Think of the 'object' element as the "workhorse" element, one used to display any non-typical media or files no other element will support. 'object' itself was supported in HTML5 in order to allow you the flexibility to do just that. But, there is no guarantee it will display, as 'object' uses players and plugins to render most of these files. If the browser or version does not have the software to do that, it will fail. If you do use it, be sure to add the "data" attribute with a path to the file on the server, and add the "width" and "height" to give your embedded file dimensions.
    5. The 'object' element supports a number of attributes, including 'width', 'height', 'data', and media 'type'. The 'width' and 'height' are used to set the dimensions of your file. The 'data' attribute is the primary means of connecting your object element to a path that connects to the location of your multimedia file on the server. The 'type' should have the generic MIME type of your media object and is a hint to the browser of how to interpret it (example, type="image/jpeg").
    6. Deprecated Attributes: There are many old attributes used by 'object' by browsers of the past that may not work. I have listed the ones below I recommend you avoid: bgcolor, hspace, palette, pluginspage, pluginspace, quality, salign, scale, vspace. Note: I have added the "loop=false" attribute to the code above, though it is likely not supported in modern HTML5 browsers today. But it prevents some older browsers from repeating video playback in a loop forever.
    7. As usual, always include an 'id' and a 'title' on these click-able multimedia objects.
    8. The 'alt' attribute in 'object' elements helps screen readers and the blind identify the meaning of embedded video elements, just like images provide. For that reason, always add the "alt" attribute.
    9. The Optional Child 'param' Element: Since 2000, the 'param' child element of the 'object' element has been used to help define its various parameters. Today, the 'param' element is optional as 'object' has assigned most of these values to its own attributes. But many older browsers may not know them and benefit from the old 'param' element. I would therefore still us it. The 'param' element adds name-value pairs associated with your media file using "name" and "value" attributes. A common use for 'param' was to add "movie" for its name and value the URL path. Another would be "width" or "height". It also comes with an optional "type" or MIME type attribute and an optional "valuetype". Because the 'object' element is often used for playing media that requires a 3rd party plug-in or player, the 'param' element is often used by these special players. Old Adobe Flash and shockwave files often needed these name-value parameters that controlled its numerous objects properties.
    10. Fallback alert text is often used between 'object' tags to alert users of non-support if media playback fails In the old days of the Internet, 'object' was often part of a block of elements designed with fallback tags if a browser did not support 'object', like 'embed'. In the example above, you will see how I have added a fallback text message if a browser or screen reader does not understand the 'object' parent element. (See my sections called "How to Create a Cross-Browser Video in HTML5" for examples of this.)
      In older web pages still online today you may see 'object' elements used with many strange attributes no longer supported in HTML5. Almost all of these were added to support a variety of custom 3rd party player/plugin/ActiveX features. Many plug-in vendors typically made available a 'classid', 'codebase', 'codetype', and various other attributes and URL's needed to download and install plug-ins. 'classid' was the most popular and used in the old days to specify the location of the object's player implementation via a URL. Object implementations included things like Java Applets or Flash player downloads. These usually pointed to 3rd party implementation for the data subject or file. 'codebase' gave a base URL for a class ID, player download on the Internet, or some base path to resolve the 'data' path. 'codetype' specified the media type of the code referred to by the 'classid'. Some implementations of object 'data' elements, like images, could be done by the browser, so 'classid' and 'codebase' would not be needed. Flash and the Adobe Flash plug-in download was a common use for these attributes and extra 'param' elements. When a user displayed the page and did not have the player a popup would fire up asking them to install it. Use of these old attributes is less common today. Note: Because the 'object' element and its players/plugin/ActiveX are a security risk in modern browsers, I do not recommend you use them.
    11. Warning: Most versions of older non-IE browsers (pre-2010) have never supported 'object' and prefer the 'embed' element instead, as it supports their older players. Also note that IE version 9-11 have adopted support of HTML5's 'video' and 'audio' elements instead of 'object'. This is another reason to avoid the 'object' element when possible and move to the newer HTML5 'video' or 'audio' element instead when supporting multimedia in your web pages. 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 HTML5".
    12. 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, it 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.
    13. Warning: Use CSS to set custom 'width' and 'height' using 'object' in supporting newer HTML5 browsers, as the attribute version may not honor the dimensions you set. (see my example above)
    14. As mentioned, I recommend you NOT use 'object' for playing audio and video in web pages, but use the 'img', 'picture', 'video', or 'audio' elements instead. Even though HTML5 still supports 'object', because it is an element that is more reliant on the older "plug-in" player model, its better to avoid its use going forward unless you MUST support specialized media that is not video, audio, or images. Again, DO NOT use 'object' for displaying video, audio, images, pictures, or iframes. Use the new HTML tags whenever possible and reserve use of object for SPECIAL multimedia objects, like Adobe Flash, Java Applets, or documents like PDF which require the 'object' element to display them. HTML5 has no other elements available but 'object' or 'embed' in those special cases. Just keep in mind that in IE 5-8, because they do not support HTML5 elements, they will use ActiveX inside 'object' to try and resolve those types of specialized files. Again, if you must support IE or older browsers with special multimedia, you may need to use a fallback HTML design with 'object' and 'embed' combined together to support these older browsers with special players installed.
    15. As mentioned above, see my article below called "How to Create a Cross-Browser Video in HTML5" below in "best practices" for a newer, more modern example of how to combine 'video', 'object', and 'embed' elements together and to enable wider video playback support across many older browsers at once in your web pages.
    <ol> ol, ordered list

    Ordered List

    see <li>
    My Recommendations:
    1. The 'ol' element defines an ordered list. See the <li> element for a full description.
    <option>, <optgroup> option, option group

    Option / Option Group

    see <select>

    The 'option' and 'optgroup' elements are children of the 'select' element. Shown below is an example of these elements when using the 'select' element form control.


    <form id="formoption" name="formoption" method="post" action="#" title="Option and Option Group Example" aria-label="Option and Option Group Example" autocomplete="off" autocapitalize="off" spellcheck="false">
    <fieldset id="formoption_fieldset1" name="formoption_fieldset1" form="formoption" style="background-color:#fff;">
    <legend style="background-color:#aaa;color:#fff;">Option and Option Group</legend>
    <div>
    <select id="formoption_select1" name="formoption_select1" size="1" title="Select a Fruit" aria-label="Fruit" tabindex="0">
    <option value="" selected="selected">-- select a fruit --</option>
    <option value="strawberry">Strawberry</option>
    <option value="banana">Banana</option>
    <option value="grape">Grape</option>
    <optgroup label="Apple" role="group">
    <option value="apple_reddelicious">Red Delicious</option>
    <option value="apple_macintosh">Macintosh</option>
    <option value="apple_green">Green</option>
    </optgroup>
    </select>
    </div>
    </fieldset>
    </form>
    Option and Option Group

    A select form field contains multiple child 'option' elements. If you need sub-grouped options with a group name, use the 'optgroup' element, as shown below.

    My Recommendations:
    1. The 'option' and 'optgroup' elements define child elements of a 'select' element that support additional choices within the listing. Like 'select', the 'option' element has been around since the 1990's and in the earliest of HTML recommendations by the W3C. 'optgroup' was added later and not supported in browsers, like Internet Explorer till version 5.5. Like most form controls, the 'select' element and its children are considered a "replaced" elements, as their design and actions are controlled by the browser and operating system. This applies to styling 'option' and 'optgroup', which is still difficult.
    2. Always Assign a 'value' Attribute in 'option': When a user choose one or more items from your 'select' element then submits the form, the 'select' elements "values" are sent to the web server along with the "name" of the 'select' element, when the form is submitted. For that reason, always add a "value" attribute inside each 'option' element, even if empty, with its text or data attached. Example: <option value="{my option value}">My Option Text</option>.
      Often the text name inside the 'option' element is the same as "value" (like "yes"/"no", "on"/"off", etc.). But it can also be different from the "value". But the "value" is what is sent to the server as data, and part of the "name-value" attribute pair sent to the server from your form control when the 'select' is submitted. In the case of a 'select' element set as "multiple=multiple", each selected "option" will always send the same 'select' element "name" value for all the 'option' "values" selected. So make sure each 'option' "value" is unique, as you have to loop through the same array of names to get each value selected. The data for multiple select choices sent to the server will appear like this: myselect=1&myselect=2&myselect=3. IMPORTANT: If the "value" attribute in 'option' is omitted, the value is taken from the text content of the option element! Some older browsers will always do this. This is why, as a rule I try and match my text string to the value, unless its multiple words, a non-unique value, or the value is in another non-friendly format, like an abstract number, id, or value a user will not recognize.
    3. Use the 'selected' Attribute: If you have a preselected item you want selected in a 'select' element, use the "selected" attribute inside the 'option' element. If no item has this attribute, the select will pick the first 'option' in your list and select it. That is why many designed add an empty "value" in the first 'option' element with instructions, like "-- select an item --". If the field is not required and sent to the server, a blank value will be sent indicating an explicit non-choice was made (which is better that not knowing). Note: Always use the XML-friendly version, or "selected=selected".
    4. Do Not Use the 'disabled' Attribute: If you have an 'option' item in your 'select' element you do not want selected, you can set it to "disabled" to prevent users from selecting it from the listing. This confuses users who might not understand why an option cannot be selected. Some browsers may ignore this feature, enabling selection and messing up your data. Others could disable the whole form when this is set. So, I do not recommend use of the "disabled" attribute on 'option', and instead disable the whole form or remove the option item completely. Note: Always use the XML-friendly version, or "disabled=disabled".
    5. Always Use the 'label' Attribute in 'optgroup': Always add the "label" attribute inside your 'optgroup' tag, which gives it a group text name for the subgroup of options inside the 'select' listing. It provides for no other feature but as a label for a group of sub-options in the listing.
    6. Do Not Use the 'label' Attribute in 'option': The "label" attribute is required in 'optgroup', but not 'option'. In 'option' it is not used often and gets confused with the "value" attribute and the text inside the 'option' element itself. Two uses of "label" in 'option' were to display a shorter text version of what is in the option element text, in which case the browser was supposed to pick the "shorter" text version. This no longer works this way in many browsers. The second use case was to use "label" to define the "meaning" of an option's text. Today, this is rarely used or needed. So, avoid use of "label" in 'option' elements.
    7. When 'select' Elements use the 'multiple' Attribute: If you need users to select more than one item from your 'select' element, add the "multiple=multiple" attribute. The box will then be resized to show multiple items by default rather than one. This shows users that multiple items can be chosen. I like to set the first 'option' element in the list with an empty "value" attribute and to say, "-- choose multiple items --". This instructs them on what to do with the multiple-select listing. Remember, in multi-selects, you can either hold the control key on your keyboard and select multiple, one at a time, or hold the shift key and select large blocks of items at once.
    8. Trouble Styling Replaced Controls with CSS: "Replaced" elements like 'select', 'textarea', and others are notoriously difficult to style using CSS and have been for years. So is the 'option' and 'optgroup' elements. See the <select> element section for more details about this issue and the 'select element in general.
    <output> output

    Output

    In the example below, I have added the new HTML5 'output' element (last box) in combination with the new "range" and "number" HTML5 form controls. This allows a user to change the "range" and "numeric" input types, have a JavaScript event ("oninput") on the 'form' element add the values together, then have it post the mathematical result to the 'output' element box. Browser support for this feature is still weak.

    <form id="formoutput" name="formoutput" method="post" action="#" title="Input Example" aria-label="Input Example" autocomplete="off" autocapitalize="off" spellcheck="false" oninput="formoutput_output1.value=
    parseInt(formoutput_range.value)+
    parseInt(formoutput_number1.value)">
    <fieldset id="formoutput_fieldset1" name="formoutput_fieldset1" form="formoutput">
    <legend style="background-color:#aaa;color:#fff;">Output Example</legend>
    <div>
    <input type="range" id="formoutput_range" name="formoutput_range" value="50" min="0" max="100" minlength="1" maxlength="3" tabindex="0" autocomplete="off" title="Slide the Range Indicator" aria-label="Slide the Range Indicator" /> +
    </div>
    <div>
    <input type="number" id="formoutput_number1" name="formoutput_number1" value="0" min="0" max="100" minlength="1" maxlength="3" tabindex="0" title="Number" aria-label="Number" /> =
    </div>
    <div>
    <output id="formoutput_output1" name="formoutput_output1" for="formoutput_range formoutput_number1" tabindex="0" value="0" title="Number Output" aria-label="Number Output"></output>
    <label for="formoutput_output1" title="Output">Output</label> </div>
    <hr />
    </fieldset>
    </form>
    Output Example
     +
     =

    My Recommendations:
    1. The 'output' element is a new HTML5 element that represents a new form field "output" box which can receive the results of mathematical calculations or other output. It was originally designed to provide output from operations based on input made by an end-user. However, it relies heavily on JavaScript and is not widely supported in current browsers, old and new. Therefore, it should not be used.
    2. 'output' Element Attributes and JavaScript: This new HTML5 form field should have the same features and attributes as a typical form field control (see the <input> for all the details). As such, it should reside inside a typical 'form' control and perform like any other input, except the unique property that a user cannot enter data into it by default. It must rely on some outside script or source to add values to it, which makes it a non-typical HTML form field element.
      There are many ways to run calculations from other form fields and insert the results into 'output'. Note the added JavaScript on the 'form' element in my sample code above. But my demonstration might not work in older browsers, simply because they do not support the 'output' element. In addition, I do not like the fact this element depends on JavaScript to be functional (Why not just use a plain "text" input box instead?).
      Note: Internet Explorer has no real support for the "number" input type, the "range" type is partially supported in IE, and IE 1-11 and Edge 12 have no support for 'output' at all! Add up my list of issues above with the non-browser support (plus buggy CSS design below) and you see why I cannot recommend the use of the 'output' element in modern HTML5 web pages today.
    3. 'output' Element and CSS Style Sheets: This new HTML5 form field should have the same design as a typical form field control (see the <input> element design). But it does not. This control should be visible, but by default, most browsers do not show any marker or visible features for 'output' until an output value appears via a JavaScript event. So, it will appear as an invisible control with no form field dimensions until some script inserts a value into it, triggering its display. In the example above, I have tried to style the 'output' to match my 'input' textbox elements, so you will see it has a border, padding and other features. But the styling turned out to be more difficult that I planned in some browsers. In most cases, you want 'output' to be simply an empty white box ready to receive values. But it's invisible with no dimensions in some browsers, initially. To address this I found you had to change the display to "block" and give it width and height. This of course defies the default "inline-block" dimensions of other form fields, which can also slide next to each other, if needed. Setting the control to block allows us to give it an appearance, but no ability to float alongside other form fields, now. But that is fine. It must act like a block-level element and drop down below any neighboring 'input' or other elements if it has to be seen. Its a fair trade-off. Again, I do not recommend this element's use, but if you do, below is a style that at least gives it an appearance in the browser:
      
      body output,
      body output:visited,
      body output:hover,
      body output:focus,
      body output:active {
          display: block;/* Defines its dimensions and thus forces its appearance. */
          width: 12em;/* Defines its dimensions and thus forces its appearance. */
          max-width:12em;/* Defines its dimensions and thus forces its appearance. */
          height: 1.8em;/* Defines its dimensions and thus forces its appearance. */
          cursor: pointer;
          width: auto;
          padding: .2em .2em;
          padding: .2rem .2rem;
          margin: 0;
          border-radius: .2em;
          border-radius: .2rem;
          border: 2px solid #bbb;
          background: #fff;
          line-height: normal;
      }
      
    4. Sadly, the "range" type and 'output' element in this example above have poor support in mobile Safari browsers (iPhone versions included, until after 2018). "number" and 'output' do not work in Internet Explorer 1-11 or even Edge 12! Even if this 'output' calculation works in your browser, it does not have wide enough browser support in most browsers to be usable. And, it requires custom JavaScript to work when it does. Therefore, do not use the 'output' element as it is does not have any support in older browsers (pre-2010), nor much support in many HTML5 browsers.
    <p> paragraph

    Paragraph

    <p>Lorem ipsum dolor sit amet, mea enim erat id, regione iudicabit consetetur ius ex. Qui vide errem ut, ius id movet atomorum. Sit pericula definiebas ei, ex eam essent maluisset. Duis ceteros pro ut. Mei eius labore ut. Iusto facete facilisi vel id, nonumy omnium constituto ad pro. Mei in sale option.</p>
    <p>Vim ei latine intellegat. Mei ea ferri suavitate. Scaevola comprehensam necessitatibus mel ad, at liberavisse signiferumque duo. Aeque tation nec ad, no sea mucius epicuri comprehensam.</p>
    <p>Invenire contentiones cum cu. Nullam timeam ceteros sed ne. Et usu case eleifend, atqui malorum civibus sed ea. At eruditi inimicus repudiandae qui, quo quaeque alterum gloriatur in.</p>

    Lorem ipsum dolor sit amet, mea enim erat id, regione iudicabit consetetur ius ex. Qui vide errem ut, ius id movet atomorum. Sit pericula definiebas ei, ex eam essent maluisset. Duis ceteros pro ut. Mei eius labore ut. Iusto facete facilisi vel id, nonumy omnium constituto ad pro. Mei in sale option.

    Vim ei latine intellegat. Mei ea ferri suavitate. Scaevola comprehensam necessitatibus mel ad, at liberavisse signiferumque duo. Aeque tation nec ad, no sea mucius epicuri comprehensam.

    Invenire contentiones cum cu. Nullam timeam ceteros sed ne. Et usu case eleifend, atqui malorum civibus sed ea. At eruditi inimicus repudiandae qui, quo quaeque alterum gloriatur in.

    My Recommendations:
    1. The 'p' element represents a block-level paragraph of text. Unlike the <br /> element between lines of text, the 'p' element wraps around a paragraph of text, creating both a new line break before and margins of spacing before and after that is collapsed into one between paragraphs. The paragraph patterns paragraph designs with text in old books. So its design comes from that original source, not the World Wide Web. Because paragraphs and the 'p' element has been around since the birth of HTML in the 1990's, this element has not changed in any of the browsers (except when it comes to how collapsing margins might work in a few) and so is very reliable.
    2. Collapsing Margins Between Paragraphs: Paragraphs act like block-level elements with dimensions, margins, and breaks. But they also often come styled with collapsible margins that often confuse developers or fail to act as expected in a few older browsers. I explain this in depth in my article in this web page entitled, "The Mystery of Collapsing Margins in HTML".
    3. Elements inside Paragraphs: I would wrap all paragraphs around text in your web page so its contained and managed safely with the right breaks and margins. Inside paragraphs, however, you should avoid any block or inline-block elements. It is safe to put many inline elements, like 'a', 'span', 'del', 'ins', 's', 'strong', 'em', and others. You can then add style classes to these elements to style pieces of text.
    4. Styling Paragraphs with CSS: Paragraphs often are styled appropriately by the user's browser and its built-in default UA style sheet. It is usually best to use the styles that come with 'p' elements. But I like to style my 'p' elements using my "reset" element style sheet so they look and act the same across a wide range of browsers. It is good to control your elements and their many styles this way so you understand how they work, have more control, and they look the same across lots of browsers, old and new. 'p' elements are almost always styled with "display:block", as block-level elements like 'div'. I like to set "padding:0" but also set "margin: 1rem 0rem;". This removes any left and right margins, but makes sure the top and bottom margins are equal to the text's default or starting font-size (or 1rem). When margins between two paragraphs meet, they merge into one, following a few rules. (see my margin article mentioned above for details). This provides some solid spacing between paragrAphs, even in older browsers, so text can breath yet without doubling the space between paragraphs. Finally, I make sure "line-height" is set to either "normal", "1.2" (which is close to normal), or "1" (same height as medium or default font-size, which is usually 16px). This latter style usually flattens paragraph text to the height of the font-size. These line-height styles allow your lines of text inside the paragraph to expand and breathe, though again, the default is likely good enough and close to the three values above. Often, paragraphs should reside inside a parent container, like a 'section' or 'div' element, which allows you to constrain multiple paragraphs of text and add extra padding or borders around the block, if you like. Do not try and style paragraphs with design beyond these few properties. They are really just empty "shell" elements meant to hold text only. Use its parent block-level container if you want to add colors, borders, and other visual design features.
    <param> parameters

    Parameters

    also see <object>

    The 'param' element is used inside a parent 'object' tag to control its multimedia parameters. An example of these parameters using a video object is shown below.

    <object id="object2" alt="object: Fireplace Video" data="video1.mov" type="video/quicktime" loop="false" style="width: 320px;height: 240px;outline: none;border:1px solid #bbb;" title="Fireplace Video" aria-label="Object File: Fireplace Video">
    <param name="movie" value="video1.mov" />
    <param name="type" value="video/quicktime" />
    <param name="play" value="true" />
    <param name="loop" value="false" />
    <param name="quality" value="high" />
    Sorry, your browser does not support this video.
    </object>
    Sorry, your browser does not support this video.

    (Above is an example using the 'object' tag. Depending on your browser and the plug-in supported, you should see a "MOV" (Apple Quicktime) video file. If you do not it is because this video format or codec is not supported by your browser.)

    My Recommendations:
    1. The 'param' element is used to define multimedia parameters for the 'object' element. It provides control over various properties for media objects used in a web page object using name-value pairs, and which various players and plugins use to control the media object. This element has been around since Netscape 4 Series which used it because of non-support of the 'object' element attributes. It was later used in HTML4 and early versions of Internet Explorer, which usually implemented 'object' parameters for support of Microsoft's ActiveX controls. Note that this element and its parent 'object' element is still supported in HTML5, 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 <object> for specialized multimedia types only. Keep in mind 'object' relies on plug-ins and players to play its media, unlike the other HTML5 media types. More details below.
    2. The Optional Child 'param' Element: Since 2000, the 'param' child element of the 'object' element has been used to help define its various parameters. Today, the 'param' element is optional and rarely used as 'object' has assigned most of these values to its own attributes. Beside, most now use the 'video' and 'audio' elements in HTML5. But many older browsers may not know the newer HTML5 elements and benefit from the old 'object' element, instead. I would therefore still use 'param' with 'object', when needed. The 'param' element adds name-value pairs associated with your media file using "name" and "value" attributes. A common use for 'param' was to add "movie" for name and the URL path for its value. Another would be "width" or "height" values for name-value pairs, or to turn movie auto "loop" on or off. If the player does not recognize these optional parameters, they are simply ignored. It also comes with an optional "type" or MIME type attribute and an optional "valuetype". Because the 'object' element is often used for playing specialized media that requires a 3rd party plug-in or player, the 'param' element is often used by these special players to receive the parameters they need to play or display the multimedia object. For example, Old Adobe Flash and its shockwave files often needed specialized name-value parameters to control its numerous properties.
    3. ALWAYS use the XML-friendly version of 'param' with the " /" at the end as so: <param />. Do not let others convince you this is a "void" element or that this format is not compatible with HTML5, because it is.
    4. See my article below called "How to Create a Cross-Browser Video in HTML5" below in "best practices" for a newer, more modern example of how to combine video playback support across many older browsers with the 'object' element using multiple 'param' elements.
    <picture> picture

    Picture

    also see <img>

    Using Picture with the New HTML5 <figure> Element

    Below I have wrapped the 'img' element in a 'figure' element, then a 'picture' element. The 'figure' element provides a 'figcaption' or text caption for the image (not picture), assisting non-visual readers.

    The 'img' element below also has a set CSS "style" attribute with variable width and height added to support the possible variable dimensions of the alternate image types assigned by the 'source' elements. It does have "width" and "height" attributes whose values are based on its default image, which the browser should only use if it defaults to its first image. But those will be ignored as each source image with different dimensions is applied.

    If you see a "flowering tree" image ("webp" type) below, your browser supports one of the new alternate HTML5 image formats that the picture's 'source' element has assigned your 'img' element. If you see the "weather map" image it means your browser does not understand the WebP image type or failed the "media" viewport check in the previous 'source' element. Finally, if you see the default 'img' element's "World Wide Web" globe image ("jpg" type), the previous two image types failed and your browser only supports "jpegs".

    <figure aria-labelledby="picturecaption1" style="padding: .5rem;border: 1px solid #bbb;background: #f0f0f0;width: auto;height: auto;display: inline-block;">
    <picture id="picture1">
    <source srcset="image.webp" type="image/webp" />
    <source srcset="weather.gif" media="(min-width: 800px)" type="image/gif" />
    <img id="picture1_img" style="width: auto;height: auto;max-width: 100%;" src="www.jpg" width="255" height="200" alt="image: World Wide Web" title="The World Wide Web" aria-label="Image of the World Wide Web" loading="lazy" onerror="this.onerror=null;" />
    </picture>
    <figcaption id="picturecaption1" style="display:block;">
    "Which Image Appears?"
    </figcaption>
    </figure>


    image: World Wide Web
    "Which Image Appears?"

    * Note: My host provider does not support "WebP" images I found out, so if no "flowering tree" WebP image appears, it is not the code but my host provider. :(

    My Recommendations:
    1. The 'picture' element is a new inline HTML5 media element that allows for the display of new, alternate image formats in a web page. The 'picture' element enables the 'img' element to utilize more advanced image "choices" using 'source' element child tags and media queries, as well as newer image formats like WebP and others. In addition, 'picture' can now be contained within a 'figure' and 'picture' parent element to enhance the image with captions.
    2. The 'picture' versus 'image' Element: In the 'img' section in this page, you can get a more in-depth view of the older 'img' element and its history. The HTML5 'picture' element contains zero or more 'source' elements and an 'img' element. But, the main thing you need to know about the relationship between the 'picture' element and 'img' element is the fact that 'picture' always wraps around the older 'img' element, but that the 'picture' is nothing but a "shell" element, only providing alternative images to 'img'. 'picture' does not hold images or photos of anything, nor does it or should it have any styling or formatting. All the 'picture' element does is allow modern HTML5 browsers to provide alternate sources for the final photo that will appear inside the 'img' element. Understand that 'picture', like 'figure', is just an empty, invisible element and does not do anything other than to group images with captions and give the 'img' tag alternate image choices. It simply injects alternative image formats into the 'img' element, if the user's browser supports them. So keep in mind, the 'img' element remains the PRIMARY container of the image inside all these other elements. Because the 'img' element still contains and holds the final image, it was designed as a nice fallback for older browsers that ignore the 'picture' wrapper element and its 'source' children, but still recognize 'img'. Most of the HTML5 elements were poorly designed and do not have this nice fallback feature, so do not work gracefully with older browsers like 'picture' does. That is why I am highly supportive of 'picture' in HTML5, unlike the rest of HTML5 which fail quite badly in older browsers with very little support.
    3. The Picture Element and its Children: In HTML5, the new 'picture' element has the power to completely alter and improve how images are used in modern web pages. The idea is to save megabytes of download time by using smaller, better compressed images tailored for each screen and device. It provides this new ability via a new child element called 'source'. (See my article below called "The New Picture Element". I cover all the basics of using 'picture' and 'img' together in HTML.) As mentioned before, the 'picture' element only provides alternative image formats to the 'img' element based on browser support, viewport size, or other checks in the 'source' attributes. The browser first checks these 'source' elements one at a time. The browser examines each 'source' elements "srcset", "media", "size", and "type" attributes to select an image that best matches those criteria. If the image "type" is supported and/or viewport dimensions match, then the alternate "srcset" image URL is passed into the 'img' element below. If none are supported, then the default 'img' tag's image "src" URL is used.
      The 'picture' element itself does not do much. Its 'source' child elements do most of the work in controlling images. Multiple child 'source' elements can be added inside the 'picture' element, along with the 'img' element, to give newer HTML5 browsers the ability to choose from among numerous images in deciding which image to show inside the 'img' element.
      As mentioned, the 'img' element works exactly the same as before in older browsers, so that if 'picture' and its 'source' elements fail, the 'img' element can still deliver its default 'src' path and image, the same as it has done the past 20+ years. But if a newer HTML-supporting browser is present, it can choose from a much richer array of source image based on support for different image "types" supported by a user's device, the ratio of CSS pixels to "device pixels" on the user's device, or the dimensions of the user's viewport using media queries.And so, the picture element works like the new HTML5 'video' and 'audio' elements in that the 'source' elements control its various features. Multiple source tags are often added under 'picture' with each one having a different image choice for the browser. The browser will then look for the first 'source' element from the list and check both 'media' attribute its "query", then the 'type' attribute to see if the encoded image type is supported in the user's browser. When the media query value matches the current viewport width and the image type is supported, then the browser will use the 'srcset' path to the image and display it inside the 'img' element inside 'picture. Below are the four main <source> tag attributes supported and their role in controlling alternative images:
      • srcset - This works like "srcset" in the 'img' tag. It simply contains a path to an alternate image to use in the 'img' tag, plus a space then a place to add either the width of the alternate image ("320w") or the "device pixel" dimensions ("3x") the image should support. The latter means that the image may be saved at twice the standard PPI or resolutions of the default image, so would look better on say an iPhone or other high definition screen. Like the "srcset" attribute for the 'img' element, this last value is the "expected width" of the alternate image (actual width, not styled) or its resolution, which tell the browser its expected value and help the browser decide when to use the image based on the available width of the user's screen. Example: "srcset=image.webp 320w" means only use this image with actual width "320 pixels" if it can fit into the screen. Again, the 'picture' and 'source' elements do not do anything as far as design. They simply support the original 'img' element.
      • type - The "type" attribute or 'source' contains an image type in a media type format that matches the "media-type" section of "Content-type" format sent by web servers in HTTP headers: type/subtype. Example: "image/jpg" is often used for an image type, and matches the media or MIME type often sent to the browser from a web server as a hint along with the image. Each image type and its format or encoding may or may not be supported by modern browsers, however. Often, the 'source' element is only used to offer very advanced or newer image types, like "WebP", "AVIF", Base64 images, etc. But there is still problems with support of these new formats. For example, the new "AVIF" image format is currently only supported by Chrome Webkit browsers, so would fail for every browser except the newest Chrome versions. "WebP" is another promising alternative "type", but is not supported in any Internet Explorer browsers and many others, like iPhone Safari, which did not support "WebP" until 2020! So, types like this are offered as alternatives only, until browsers in the coming decades support them. But you could add these types of images using your "type" attribute in 'source' elements and thereby offer browsers reading your 'source' tags checks to see if they support them.
      • media - The new media "query" attribute allows you to set both when an image type should be considered by the browser, and any additional scaling (or stretching) of the image from its default value. It allows you to tell browsers when to scale these alternative images larger or smaller. Note that this only works in HTML5 browsers that support these types of media queries. There are two main media type formats to use: "Media Conditions", like "max-width" or "min-width", which relate to a devices viewport width, and "Media Intrinsic Width", which is the width the alternative image should resize or scale (based on a devices screen or viewport, not the image's actual size or styled size). Example: "media=(max-width:800px) 50vw" in a 'source' element means to only use this image alternative if the device or screen is less than 800 pixels, and when triggered scale the image to 50% of the viewport. This might trigger a user on an iPhone or tablet to pull down a higher resolution image thats designed for smaller screens but which is then scaled down an additional 50% to fit into the smaller space. Personally, I would not use the "scale" feature as its wasteful and redundant to scale or distort images. You should have them simply use their original size and resize them and their resolution or PPI in Photoshop.
      • sizes - If you want to rescale or "stretch" you image relative to the screen or viewport, you will want to use this attribute. I do not recommend it as "stretching" images is an old technique thats rarely if ever needed. But you could use this attribute to set a viewport value. An example of all this would be "100vw" which says, stretch the image in width 100% of the viewport. Again, not a good idea. I would rarely use the "sizes" feature unless you are ok stretching your images to fill the screen. Instead, use the "srcset" image width feature, like "500w", or the device pixel check, as in "2x". The first would tell the browser to fit a 500 pixel width image into any screen that is wide enough to hold it. The "2x" if used would says use this image in any screen device that has a "device pixel" value of 2 or higher. This means that the screens pixels are so tiny and can hold so many more than a desktop or laptop that you have created a high resolution image for these types of devices. Most iPhone screens now support 400+ PPI resolutions screen with tiny pixels, which translates into a 2-3x increased pixel density.
    4. Picture with Figures and Captions - In HTML5, the 'figure' and 'figcaption' elements are now used by modern browsers to wrap around 'picture' elements and add captions beneath then in HTML5. The 'figure' element wraps around both 'picture' and 'img' elements, with the "figcaption" appearing under the 'img' element with text describing it. Most photographic websites, online magazines, or article images carry more visual information in the 'img' element than normal, so require a text caption to connect the image with the article text. So, be sure to add captions when using images in HTML5.
    5. Picture and CSS - NEVER style the 'picture' element as its an empty, inline element. Instead, style the 'figure', 'figcaption', and 'img' elements.
    6. For more advanced examples using the new 'picture element, see my two articles below: "How to Display Images in HTML" and "The New Picture Element".
    <plaintext> plaintext

    Plaintext

    <plaintext>
    All content after this element would show text and HTML elements as is.
    My Recommendations:
    1. The 'plaintext' element is a deprecated HTML2 element used by older browsers to create text that ignores all HTML formatting below it and displays content and HTML elements as is. This tag is redundant as you can now control text formatting using CSS and was also never a part of HTML5. Do not use the 'plaintext' element.
    <pre> preformatted text

    Preformatted Text

    <pre>
      &lt;p&gt;Here is my sample paragraph using 'pre'.&lt;/p&gt;
    </pre>
        <p>Here is my sample paragraph using 'pre'.</p>
    
    My Recommendations:
    1. The 'pre' element defines a block-level piece of text in which the spacing, fixed-width fonts, line breaks, and layout are preserved as preformatted text. 'pre' is ideal for displaying computer code. For this reason it is commonly used with the 'code' element, to wrap around HTML, CSS, and JavaScript code that is shared online by developers. The 'pre' element has been around since early versions of HTML, so fully supported.
    2. Facts about the 'pre' Element: 'pre' text is usually in a monospace font by default to differentiate its purpose to the viewer. Because the CSS has supported the "white-space:pre" declaration for years (same look-and-feel as 'pre'), you can now assign the same formatting to any element as the 'pre' tag does using CSS. Therefore, the 'pre' element is not required to create preformatted text in many cases. However, some browsers (pre-IE 5.5 browsers or Firefox on Android) may not recognize this "white-space" value or allow such formatting, except when using the 'pre' element. So, its use is still recommended. WARNING: All sample HTML must be escaped in order to display markup examples inside the 'pre' elements. 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 "&lt;") to show you how that is done.
    <progress> progress bar or indicator

    Progress Bar

    also see <meter>
    <p>
      <progress id="progress1" max="100" value="40" title="Loading Bar in Minutes" aria-label="Loading Bar">40 minutes left</progress>
      <label for="progress1" title="Loading Bar 1">Loading (min)</label>
    </p>
    <p>
      <progress id="progress2" max="1" value="0.8" title="Loading Bar in Percent" aria-label="Loading Bar">80%</progress>
      <label for="progress2" title="Loading Bar 2">Loading (%)</label>
    </p>

    40 minutes left

    80%

    My Recommendations:
    1. The 'progress' element is new in HTML5 and defines a range of fractional values represented visually as a colored image bar. 'progress', unlike 'meter', generally presents a bar showing "progress towards completion", like in a typical "loading bar". Note: Each browser displays this "bar" differently. Some may change the color of the bar based on low or high values. This element was designed as a simple way to graphically represent progression without complex scripting or 3rd party plugins.
    2. 'progress' Attributes: In general, always add a unique 'id' and a 'title' or tooltip to this visual element, so scripts can manipulate or update its attributes, and viewers can get more rollover descriptive information. Remember that visual elements also can fail, or not even be seen by screen readers. So, add an ARIA label.
      The main attributes used are "max" and "value". Unlike the 'meter' element, where you can customize ranges, 'progress' elements always start their minimum range at "0", so have no "min" attribute. "max" must be greater than "0", but defaults to "1" if left off. It can be any integer or a floating number 0-1. I recommend you set it to "1" or "100", this being the value at which an "activity" progresses to 100% completion. The "value" attribute is the current value in the range from "0" to the "max" value, but defaults to an "indeterminate" or unknown value if left off. This means that activity, like "loading", is ongoing and will continue. I do not recommend you do this unless you want to indicate some process is continuing indefinitely or stuck in progress. The "value" is best set at a known integer, or a floating point number of 0-1 in fractions if "max" is left off or "1". The idea with value is it could be reset by JavaScript on a page refresh, or with a new value from the server, to show progress towards 100% of completion. Let the user know its either ongoing, stuck, or soon to be completed using the progress bar and its "max" and "value" attributes.
    3. Sketchy Browser Support: This new HTML5 element is not supported in any older browsers, including Internet Explorer 1-9. But it does have much better support than its cousin, <meter>. It also falls back nicely to text inside the 'progress' tags (as shown in the code examples above) when the visual element collapses. And it supports labels. But many older browsers, IE, will not benefit from that text without the supporting graphic display, which is its hallmark. The graphics will change based on the browser and operating system of the user. The progress bar appears smaller or thinner than 'meter', in many cases. But, I recommend this element over 'meter' if you need a progress graphic element, though it's not widely supported.
    <q> quote, short quotation

    Quote

    Benjamin Franklin is known to have said <q cite="https://www.fi.edu/benjamin-franklin/famous-quotes" title="Famous Ben Franklin Quote">Well done is better than well said</q>.

    Benjamin Franklin is known to have said, Well done is better than well said.
    My Recommendations:
    1. The 'q' element defines a short inline text quotation in HTML5. Unlike 'blockquote', it adds quotation marks around its inner text.
    2. The 'cite' attribute is used to define an online URL source for the quoted text and its web page.
    3. The 'title' attribute is used as a tooltip quotation description and is optional.
    4. Always use 'q' for smaller inline quoted text and 'blockquote' for larger separate blocks of non-quoted text.
    <ruby>,
    <rt>,
    <rp>

    <rb>,
    <rbc>,
    <rtc>
    ruby elements

    Ruby Elements

    Only half of the ruby elements listed here have enough support by browsers today and in the past to be useful. These three ruby elements are the ones I currently recommend you use: <ruby>, <rt>, <rp>. These ruby elements are supported in many older Internet Explorer browsers and in all of the HTML5 browsers, so have the widest support in browsers today. The others are deprecated from current HTML5 browsers and never were supported in older ones. Below are some examples of how to use ruby the right way with the three ruby elements mentioned.


    Here is a basic use of the ruby structure to show you how it is laid out with the 'ruby', 'rt', and 'rp' elements. I have added a few inline styles to "bold" the ruby text. If your browser supports the 'ruby' element it should place the "ruby annotation" text above the "ruby base text". The 'rp' or ruby parenthesis element below is not seen by ruby-supporting browsers, but only appears for browsers that do not support ruby. The 'rp' tags can contain any text you like, but parenthesis are common. If ruby elements are not understood in a user agent, the 'rt' text drops to the right of the foreign language text with the 'rp' text around it.

    
    <p>
        <ruby style="font-weight:bolder;">
            ruby base text
            <rp style="font-weight:normal;"> (</rp>
            <rt style="font-weight:normal;">ruby annotation</rt>
            <rp style="font-weight:normal;">) </rp>
        </ruby>
    </p>
    

    ruby base text ( ruby annotation )


    In this example, I am doing a translation type of ruby annotation. Notice the 'ruby' element wraps around everything and is an inline element, so part of the sentence flow. I have added the "xml:lang" for Japanese to help the browser render the right characters, though it is not required.

    
    <p>This is how we say 
        <ruby xml:lang="ja">
            ようこそ
            <rp> (</rp>
            <rt>welcome</rt>
            <rp>) </rp>
        </ruby>
    in Japanese.
    </p>
    

    This is how we say ようこそ ( welcome ) in Japanese.


    In this example, I am translating text with ruby again, but translating a full sentence this time. In this ruby design, it might be better to drop the text translation below the Japanese text, which you can do with plain CSS styles. In the second example, I have used plain CSS styling to do change positioning of the ruby annotation to the bottom of the language text. Many use the "ruby CSS properties" to do this. The problem is, these special ruby properties have almost no support in older IE browsers and are sketchy in others.

    
    <p>
        <ruby xml:lang="ja">
            東京 に 行き たい。
            <rp> (</rp>
            <rt>I want to go to Tokyo</rt>
            <rp>) </rp>
        </ruby>
        <br />
    </p>
    

    東京 に 行き たい。 ( I want to go to Tokyo )

    
    <p>
        <ruby xml:lang="ja" style="position:relative;">
            東京 に 行き たい。
            <rp style="position:relative;top:2em;"> (</rp>
            <rt style="position:relative;top:2em;">I want to go to Tokyo</rt>
            <rp style="position:relative;top:2em;">) </rp>
        </ruby>
        <br />
    </p>
    

    東京 に 行き たい。 ( I want to go to Tokyo )


    In this example, I am combining "pronunciation" of the Chinese symbol(s) with an added ruby "translation", as well. To manage all this code block, I am also nesting two 'ruby' elements together, plus the added translation after it, so I can separate out the two languages better. Notice that "Welcome" sits above the nested 'ruby' pronunciation set. That is because I used two 'rt' elements. In many cases, the browser will stack the second 'rt' above the previous ruby set that it relates to. As bad as that may look, try and use the browsers "default ruby positioning" and avoid changing it. In older browsers that do not support ruby, the text will appear to the right with parenthesis.

    
    <p>
        <ruby xml:lang="cn">
            <ruby xml:lang="cn">
                欢迎<rp> (</rp>
                <rt>Huānyíng</rt>
                <rp>) </rp>
            </ruby>
            <rp> (</rp>
            <rt>Welcome</rt>
            <rp>) </rp>
        </ruby>
    </p>
    

    欢迎 ( Huānyíng ) ( Welcome )


    Here is an example of the above ruby code but using the new HTML5 ruby elements (<rb>, <rbc>, <rtc>) and a newer ruby CSS property, both of which are now deprecated according to HTML5 groups online. Again, you should avoid these elements as they have almost no browser support. Even if they work ok for your browser, remember no other browsers prior to 2010 or even later will support them, much less many newer ones.

    
    <p>
        <ruby xml:lang="cn">
            <ruby xml:lang="cn">
            <rbc>
                <rb>欢迎</rb>
                <rp> (</rp>
                <rt>Huānyíng</rt>
                <rp>) </rp>
            </rbc>
            </ruby>
            <rtc xml:lang="en" style="ruby-position: under;">
            <rp> (</rp>
            <rt>Welcome</rt>
            <rp>) </rp>
            </rtc>
        </ruby>
    </p>
    

    欢迎 ( Huānyíng ) ( Welcome )


    My Recommendations:
    1. The 'ruby' element represents a set of inline text annotations that are added above, below, or beside base foreign language text. This element is used to help provide translation or pronunciation to foreign language text in web pages by adding a small piece of guide text next to it. 'ruby' has been around since 2003 when the first W3C recommendations were completed for XHTML. Note that HTML4 never supported ruby, so it was not fully adopted until HTML5 (post-2010), though some browsers like Internet Explorer have supported ruby since the late 1990's. HTML5 added support for the XHTML ruby elements, plus added new elements to ruby that are no longer supported by most browsers.
    2. All the Supporting Elements of Ruby: The parent 'ruby' element controls the complete annotation set for a given ruby text. But it includes many other supporting elements. The main 'ruby' element design was never supported in HTML4 but was introduced into XHTML in 2003. It consisted of the 'ruby' parent element which held the foreign Unicode text and an 'rt' or "translation" element that contained the translation or pronunciation of the annotated text. An optional 'rp' or "parenthesis" element was added to wrap translation text in parenthesis and give additional information for browsers that did not support ruby at the time (2003). Those that do will hide whatever is wrapped by the 'rp' tags.
      Internet Explorer 5.5 early on supported ruby annotations, years before XHTML was adopted and supported ruby. But the other browsers did not support ruby for almost a decade! Chrome (2010) and Firefox (2015) were late in support of ruby until HTML5 adoption. But, the above three ruby elements continued to work in IE5 and 6 reliably, thought rarely used.
      In HTML5, ruby was officially adopted in most modern browsers. It also added a few new ruby elements: 'rb', 'rbc', and 'rtc'. However, I am told these have been deprecated since 2016 and no longer supported by most browsers (there may still be support in Asia). For now I do not recommend these new HTML5 attributes due to lack of browser support, and that you stay with the original XHTML ones now supported in HTML5 ('ruby', 'rt', 'rp').
      As mentioned, the 'ruby' element is the parent element for a range of smaller elements that help define the full ruby annotation set. I have included the supported ones and the non-supported ones below. So, if you see these deprecated ones in a web page, you will understand what they were supposed to do:
      • <ruby> or "ruby" (HTML4/XHTML/HTML5) - This is the main wrapper ruby element which creates the association between foreign text and its ruby annotations.
      • <rt> or "ruby translation" (HTML4/XHTML/HTML5) - Used for the purpose of displaying the markup, translation, explanation, meaning, or pronunciation of foreign text.
      • <rp> or "ruby parenthesis" (HTML4/XHTML/HTML5) - Provides fallback parenthesis ("(...)") for browsers which do not support ruby annotations but which need to see translation text inside parenthesis. You can put anything you like here, however, to support translations of text by non-supporting ruby browsers. Note that the text between these tags is hidden from supporting rub browsers.
      • <rb> or "ruby base" (HTML5) - New in HTML5, this element marks the foreign text to be annotated. This element I am told is now deprecated and no longer supported.
      • <rbc> or "ruby base container" (HTML5) - New in HTML5, this element serves as wrapper around 'rb' elements in more complex ruby annotations. This element I am told is now deprecated and no longer supported.
      • <rtc> or "ruby translation container" (HTML5) - New in HTML5, this element serves as wrapper around 'rt' elements in more complex ruby annotations. This element I am told is now deprecated and no longer supported.
    3. Additional Ruby Features: First, realize you can combine translation with pronunciation in ruby. (I demonstrate that in the code above). If your web page is delivered in one language (say English or "en"), but you are using foreign languages inside your 'ruby' element (often in Unicode), it is good to add the "xml:lang={code}" attribute to the 'ruby' element with the language encoding used. Example: <ruby xml:lang="ja"> for Japanese. You can also style ruby 'rt' text to float left, right, above, or below foreign text, though CSS support for special properties for ruby do not have wide support (example: "ruby-position: under"). Internet Explorer has almost no support for these properties. If you must position or style ruby child elements, I recommend you stay with the default browser formats or use a CSS class and say CSS "position:relative" and other traditional CSS properties to align the text as you need. Finally, there were some old properties on 'rt' (like "RBSPAN=3", etc.) and other element attributes no longer supported. So, stay with CSS when changing the design of ruby elements.
    4. I recommend you only use the original 2003 ruby elements (<ruby>, <rt>, <rp>) and avoid the ruby elements, as well as avoid the special ruby CSS properties, due to lack of browser support.
    <s> strikethrough

    Strikethrough

    The store will be closed on <s>9/19/2021</s>. <strong>Now we are open for another month!!</strong>
    The store will be closed on 9/19/2021. Now we are open for another month!!!
    My Recommendations:
    1. The 's' element represents inline quick "strikethrough" text that is no longer valid in meaning, but which is not a textual error or replaced with any correction. Often, browsers will style this text with a "strikethrough" line, which in this case indicates text that no longer has any meaning or validity in the web page.
    2. Strikethrough Confusion: This element is often confused with the <strike> element, which has been fully deprecated in HTML5 and was a design element only, much like <small> and <big> elements. But the 's' element is more often confused with the <del> element, which is supported and also uses a "strikethrough" on text. What is the difference then?
      In the latter case, you only use the 'del' with the 'ins' element, indicating a deleted text string and its text replacement. In the case of the 's' element, it indicates no text replacement, only the meaning of the struck text being invalid.
    3. The New Meaning of the Strikethrough Element: The 's' element has been around since HTML4, and was used in the past for styling any type of text needing the "strikethrough" format. There was no true semantic meaning associated with the element. This implied it could be "deleted text" and replaced with something else, invalid, misspelled, etc.
      But now, the 's' element strictly represents text whose meaning has changed and is no longer valid in the web page, but which has not been replaced. It is not a text error, but a change in meaning. So, you might use this element when posting changes in "facts" that you want to alert users to, like a product's price change comparison, items going on sale, or past events that have changed from previous text. These are not "text errors", like the 'del' element attempts to correct, but alerts to changes in meaning.
    <samp> sample output

    Sample Output

    <p>When I pressed the <kbd>Ctrl</kbd> key, my computer said <samp>"Hello World"</samp>.</p>

    When I pressed the Ctrl key, my computer said "Hello World".

    My Recommendations:
    1. The 'samp' element is a piece of inline text representing sample output from a computer program or script. This inline element is used to wrap around text strings that represent computer text returned to a user. As such, 'samp' is often combined with input values using the 'kbd' element. 'samp' has been around since HTML4 and is still supported in HTML5. This element is similar to <code>, <kbd>, and <pre> in that 'samp' formats text to represent abstract computer values.
    <script> script

    Script

    A 'script' element is a non-visual (invisible) element that is used to download and run JavaScript in your website. Below I have listed a rich set of <script> code examples and the many ways you can use this element to enhance your website with scripts. Note that I have added the right mix of attributes to the code examples below, so you can cut-and-paste my code and get up and running fast knowing that my 'script' examples will work well in most browsers. You just need to replace the "src" URL values with your own values, in most cases.


    Link with External JavaScript Files

    This example below demonstrates one of the two main use cases for the 'script' element in websites today: "External" JavaScript Files and "Embedded" JavaScript Code (or "internal"). I prefer you use this "external" file version of the 'script' element. Why? External style sheets are globally cached for days, weeks, or months by the browser and control the scripting needs of thousands of pages in your websites, unlike their less efficient cousin, the "embedded" script tag which loads script code for just a single web page. The latter type is wasteful and increases the bandwidth needed to support millions of downloads of JavaScript code from your server over years and years. Note: You typically add these links to external JavaScript files inside the <body> element at the bottom of your web page. This forces the browser to delay importing in the JavaScript file until after the main HTML markup in the web page is downloaded and parsed. Note the use of "defer" which helps preload then pause the script until the HTML is rendered.

    
    <script src="myscript.js" type="text/javascript" defer="defer"></script>
    
    

    Script with "Content Delivery Networks" (CDN)

    If you prefer to use CDN's (Content Delivery Networks) to deliver your script files, you can use this version of the 'script' element below that is designed to pull down JavaScript libraries from a 3rd party content provider. This one is free and available to anonymous users. Note: You typically add script downloads like this in the <body> of your web page at the bottom. This forces the browser to load the script last after downloading and rendering the HTML content. Note that I have added "defer" to force the script to pause until all HTML is rendered. I have also added a preprocessing 'link' for the external CDN URL, reducing the time needed to connect to the CDN's domain (see my section on <link>).

    
    <link rel="preconnect" href="//code.jquery.com/" crossorigin="anonymous" />
    
    <script 
        src="https://code.jquery.com/jquery-3.6.0.js" 
        integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" 
        crossorigin="anonymous" 
        type="text/javascript" 
        referrerpolicy="no-referrer" 
        defer="defer">
        </script>
    
    

    Avoid the "Embedded" version of the 'script' Element

    I do not recommend you use this "embedded" script element, as it only allows your scripts to affect a single web page. Unless you truly need a script that only affects a single page in your website, I recommend you use the "external" script version above, instead.

    Note: If you must use these single-page script blocks, I have added an XML-friendly, "no JavaScript support" friendly "CDATA" version to the "embedded" code example below, which is superior to any embedded 'script' coding block you will find online. It supports your page scripts in XHTML 1.1, XHTML5, XML parsers, browsers with no JavaScript support, JavaScript disabled for security reasons, or browsers with full support for JavaScript. Use this version below if you have to use "embedded" scripting. Note: You typically add script blocks in the <head> of your web page. This forces the browser to load the scripts first before downloading HTML content and should only contain scripts that need to be fully preloaded first and which directly affect or control HTML right after it is rendered. Note: The "strange" CDATA code that wraps around the scripts is "extra" code designed to hide/support JavaScript code in the tags from XHTML, XML parsers, and older non-supporting JavaScript browsers (see my recommendations below for a full explanation).

    
    <script type="text/javascript">
        <!--//--><![CDATA[//><!--
    
        alert('hello world!');
    
        //--><!]]>
    </script>
    
    

    My Recommendations:
    1. The 'script' element is used to download or execute scripts in a website. It is typically used to download JavaScript files ("external" version) or run a single block of JavaScript directly in a web page ("embedded version). 'script' elements have been around since the 1990's and have changed very little in the past 20 years. 'script' elements were first used after JavaScript was fully adopted by Netscape and other browsers in the late 1990's.
    2. The Two Types of 'script' Elements: Shown in the code above are the two types of 'script' elements you can use. Both types of 'script' element are used to run scripts (usually JavaScript code) directly in your website. They usually reside inside the <head> section of your web page or at the bottom of the <body> element. Each version of the 'script' element uses different strategies, however, as each type has a different purpose.
      For starters, I recommend you stay with the "external" version (first one above) and avoid the "embedded" one used for smaller script blocks. The reason is, the first type will allow you to use a single line of code for the 'script' element with a "src" attribute that points to a JavaScript file on the server to download. This allows it to download a complete set of JavaScript code one time in the browser and have everything your website needs fully cached for the JavaScript runtime engine to use when it is called. This element may be placed in the 'head' element of your website or at the bottom of the page inside the 'body' element. These 'script' tags often link to a single script file or library of scripts on the server. The browser must parse the 'script' element immediately when encountered in the page and download the script file to your browser. Often the script file is downloaded synchronously or in sequence before other processes in the browser, which means all HTML rendering and processes before the script is encountered are stopped until the script file is downloaded, parsed, and executed. When used, these script "links" allow your user's browsers to download all your JavaScript libraries one time and have their web browsers cache them for weeks or months, saving huge amounts of bandwidth. The browser will then call these cached JavaScript files from your device when running various scripts rather than downloading them over and over from the server each visit by a user. This saves huge amounts of bandwidth, processing, and time.
      The second type of 'script' element allows you to place raw JavaScript or other scripts directly in the browser using 'script' tags. It downloads this block of code each visit to the web page and is not cached unless the page is actively being used or is cached offline. It downloads its JavaScript code one time when the web page loads. However, on each refresh it will be downloaded again, just like HTML. If you have a unique page that needs a small amount of JavaScript specific ONLY to that one page, then removing this script from your larger "external" sheet and adding it to the "embedded" one might be beneficial. However, over time use of this strategy is wasteful and adds lots of bandwidth and redundant code. Note that the format of the "embedded" 'script' element with code inside should always include "HTML Comment" tags, or a full CDATA section wrapped around the inner JavaScript. This allows your 'script' tags to support scenarios where your web page is parsed as XML (as in an XHTML or XHTML5 polyglot page) but will not blow up as invalid XML. It also accounts for rare cases where JavaScript is not supported or even turned off in the browser. The scripts will then not be interpreted as HTML, text, or some other code that gets displayed in the web browser. The version of CDATA and HTML comments I have added to this 'script' example below demonstrates "best practices" when using JavaScript in a web page using the 'script' element. This CDATA code below inside the 'script' element supports HTML5 parsing, XHTML, XHTML5, and very old browsers that do not support the script tag or even JavaScript. In all cases, using the code below will not blow up in any of the browsers or allow your scripts to get rendered accidentally as markup or even text:
      
      <script type="text/javascript">
          <!--//--><![CDATA[//><!--
      
          // put your scripts here
      
          //--><!]]>
      </script>
      
      
      Some History on this Strange Code Above: Going back to the 1990's, you were allowed to place these HTML comments "<!--" and "-->" inside the 'script' element to hide JavaScript text from non-script supporting browsers, which would recognize the HTML comments and hide the scripts. Supporting JavaScript browsers back then would ignore them and execute the scripts. Why? These 'script' and 'style' elements read anything inside the tags as character data or CDATA, which means no HTML is recognized inside the tags. HTML comments are still HTML so ignored by them. So, most browsers that supported JavaScript back then ignored these HTML comments, as anything in these elements was considered CDATA, allowing JavaScript to execute safely for them. By the way, these now defunct older non-JavaScript supporting browsers included IE 1-3.01 and Netscape 1-1.4. For them, the HTML comments meant the script code was safely commented out. These same comment markers above, however, had to be redesigned to support even more scenarios of non-JavaScript supporting agents over time beyond just these older HTML4 browsers. Added to this problem has been XHTML and XML parsers, which do not know the code between these tags is just CDATA. Such parsers would blow up if they parsed JavaScript that contained any XML entities or markers. Many of these XML-friendly parsers did not run JavaScript or scripting parsers at all. To fix the code for them, I had to expand the comments above to force those parsers to ignore the scripting code, as well. And so that is how I came to develop the solution above. In the HTML5 browser world today, nearly all browsers known now support JavaScript. But adding the comments and safety code above allows you to still support a range of very old non-JavaScript supporting browsers, XHTML, and XML parsers combined, should you need to share your code or web pages with any of these parsers or browsers. They will not blow up now when encountering your JavaScript code using the comments above. The code above is completely safe to use now in newer, more modern HTML5 browsers. But when used, it will make sure your JavaScript blocks are ignored in XML parsers and non-JavaScript supporting older browsers alike.
    3. The "src" Attribute: Use the "src" attribute in "external" script tags to link to a URL path to a JavaScript file on the server. The path can be an absolute path, a relative path, or an external CDN or Content Delivery Network script on a remote server (see code examples above). Note that the "src" attribute only applies to the "external" script file download version of the 'script' element.
    4. The "type" Attribute: By default, every 'script' element defaults to a media type of "text/javascript". So you really do not need to add the "type" attribute. But many older browsers used other languages so did not default to javascript types. So I recommend you still add it for now. In HTML5, they recommend you do not add attributes to the 'script' element for that reason. But again because of older browsers, I still recommend you add "type". See below.
      The "type" attribute defines the media or MIME type of the file. This matches what web servers will often deliver to the browser using HTTP headers when sending JavaScript file type "hints". Since the 1990's the most common and most reliable JavaScript media "type" has been the text string, "type=text/javascript". This is still the type I recommend you use. But there are a few wrinkles in this as HTML5 has brought new changes. New recommendations in HTML5 says the MIME type for JavaScript should now be "application/javascript", not the old "text/javascript". It turns out, however, these new changes really don't matter much until you start using higher "planes" of unicode characters and languages in your JavaScript. The problem using the new type is that old Browsers will not know what that new type is and will possibly fail to parse your script file as a result. So, you need use the old type for now. The browsers that fail the most using this new HTML5 script type include Internet Explorer versions 1-8. If you leave off the "type" attribute in many new modern browsers the "default" script tag value is still "text/javascript". To solve this and let browsers decide, HTML5 recommends you just leave OFF type="text/javascript" from the 'script' tag. But again, I recommend you still use "type=text/javascript" on the 'script' element as I like supporting older browsers, who by default might not know its still the old type or have a default type. This media "type" attribute, however is still a "hint". Keep in mind, the "type" of javascript used in HTML pages as in 'script' tags is determined by the "Content-type:" value sent by the server first via HTTP, which also includes the charset, which you can also add to the 'script' element. (I do not recommend you use "charset" in the 'script' element though, as it is almost always utf-8 anyway, though script rendering engines in browsers usually ignore this and sniff the file encoding type themselves). But the script media "type", browsers almost always look at the script tags "type" AFTER looking at the HTTP "Content-type" value from the server. The server type most often delivered remains "text/javascript". So just to be safe, use the attribute "type=text/javascript" to match what most servers still use and not cause confusion or risk breaking script executions in older browsers like Internet Explorer, which in older versions allowed use of VBScript instead of JavaScript.
    5. Use of Legacy Attribute, "language=javascript" - For now you do not need to use this old attribute in 'script' tags. In the old days, many browsers like Netscape 3-4 supported various versions of early JavaScript. Often there was no way to tell Netscape what version of JavaScript to use. Remember, Internet Explorer 3-5 used JScript, its own form of ECMAScript/JavaScript. But in the old days, Netscape supported many versions of JavaScript.To help with this type of scripting support, many web pages with 'script' elements for Netscape 4 Series (c.2000) had the attribute "language=javascript" or "language=javascript1.2" or "language=javascript1.4" added with the version of JavaScript used. "javascript" defaulted to "javascript1.0", but you could choose later versions. All these versions were very 1990's versions of early ECMAScript/JavaScript no longer used. At this time, only in rare cases, it would not hurt to add this attribute to support old Netscape users. But because this browsers is so rarely found in the wild, I do not recommend it, unless you have a unique user base with this old browser.
    6. CDN and referrerpolicy="no-referrer" - Use this attribute and value if you want to block the external CDN sources from getting your user's referrer or source information. This blocks the origin data sent to their servers, which shows up in their logs every time a visitor of your web page uses one of their external scripts. Note: If this prevents you from accessing the external file, then you might have to remove it.
    7. The 'script' element and JavaScript: I will not be covering JavaScript and its history, as that is a separate and very large topic. Know that Javascript was not supported until Netscape 1.5 in 1995, but not fully implemented until Netscape 3.0. Support for the 'script' element pointing to external JavaScript files in web browsers was not supported until Internet Explorer 3.02 and Netscape 4.0 series in 1996. After that, use of the 'script' element became widely used as the various flavors of JavaScript in Netscape and Internet Explorer evolved after 1998. So, the 'script' element has been around a long time and still works the same as it did over 20+ years ago. As always, very little changes in the HTML world despite lots of people trying to wreck its elegant simplicity!
    8. The External 'script' element and Preloading - This discussion below only applies to the first "external" 'script' type, the one that links to a JavaScript file on the server.
      Trying to "preload" or enhance the performance of scripts downloaded from a web server is the act of a browser trying to load scripts as early as possible, yet without interrupting the downloading, parsing, and rendering of HTML. But this idea of speeding up script performance through some magical "preloading" or lazy loading of JavaScript code by tricking the browser is a dream as old as JavaScript and HTML. Yet, this act of speeding up file downloads or prevention of blocking of HTML rendering is often taken care for you by modern browsers in a very efficient way. Often there is nothing you need to do or change. But, note that this concept that you can somehow radically improve what browsers have been doing naturally for over 20 years changed radically with the use of heavy JavaScript use in websites the past few years.
      The main focus of many new developers and search engines in 2022 is how much faster web pages need to load, despite the advent of faster and faster optical cable lines and lightning speed 5G mobile networks. The irony is too sweet. Their idea now is that, as HTML gets parsed and the DOM is rendered, any external files or media that delay (or "render block" as they say) that process can slow down this web page process. In the majority of cases, plain HTML never causes problems, nor does external CSS style sheets, or much else. Yes, video on-demand and giant images can slow down some things. But often browsers over high speed networks download these files very quickly, now. Any real delays are more likely caused by slow connections and slow servers...not minimized "render blocking" CSS or HTML. Despite these concerns, developers have recently started using these heavy JavaScript API's that are very large in size. They have now moved from a server-side web model to a thick client-side model. As a result, this change has radically increased the megabytes of JavaScript loaded into the browser since 2010. Because of these JavaScript API's, the average volume of JavaScript shoved down the throat of most browsers in 2020 according to resources online is over 1.5 Megabytes!!! Sorry, but that is the problem. And that is the real cause of the bottleneck in slow web page rendering and search engine performance today.
      To address this issue, many JavaScript developers have not reduced their volumes of client-side scripting but instead tried to minimize and squeeze as many extra bits and bytes of code as possible from these gigantic libraries using minimizers, async'ing all external files, lazy loading scripts, using modular JavaScript components, and compressing or delaying CSS style sheet downloads. It is a real mess, as it's distorted the true nature of HTML and moved websites from simple markup displays to huge complex JavaScript applications that drive CPU's and download delay times up on mobile phone and desktop browsers alike. They have then added large preprocessing to files that add more and more dependencies, with very little performance gains to show for it. The solution to all this mess is not to strip out more spaces from code, minimize CSS, or delay external file downloads, but to stop downloading so much JavaScript!! It is just unnecessary and proves the collapse of thick client-side technologies will someday happen as they grow larger and larger. A return to simpler HTML and older server-based solutions is coming as a result, now.
      In the mean time, I have simplified a long list of these "preload tricks" used today when using the 'script' tag and its attributes. The idea is to attempt to reduce the delays caused by downloading these huge JavaScript files into the user's browser. In reality, these tricks are not that effective and might shave off a few hundred milliseconds from JavaScript download times. There just are very few tricks available for controlling JavaScript use, parsing, or downloading times in most browsers, beyond simply reducing the size of these giant libraries. But why is that, you ask? The reason is, many modern browsers now have very sophisticated solutions for managing these files and their connections and downloads, often without any help from your or I. There are also only 2-6 open and available connections by default in most browsers today when downloading images, code, scripts, and external media found in most modern websites. Many of these will be used by CSS files or images, so your scripts may be delayed by these very limited available connections. Your server also controls how fast it responds to those connections and download streams. In other words, it's rarely the code but the server and the browser that delays rendering of web pages in 2022. And like I said, most website HTML and CSS is not that large a download, anyway. The fact is, when it comes to JavaScript, you can only "trick" the browser so much until you just have to change how you use and manage your web application models using these gigantic JavaScript libraries.

      Below are a few things I recommend in trying to preload 'script' files and which I have added in my code examples above to help you squeeze the most performance from your 'script' tags using JavaScript. In the code above, I have added the attributes and code that will work best, so you can cut-and-paste the code as is, knowing I have added just what you need in your HTML5 code to improve a little on download times. But, below are all the dirty details of why I elected to use the code above:

      Tricks to Improve JavaScript Downloads

      • ALWAYS put your "embedded" script blocks in the 'head' element of your web page and with as little JavaScript content as possible. Never put this element in the 'body' element as that may delay its parsing. When placing scripts in the 'head' element of your page, ONLY add scripts into the 'script' element that are required to help render the HTML for display purposes in the DOM or trigger events that affect the page's final design. Placing these scripts in the 'head' area means they load events instantly and run right away as soon as events like "onload" or other page loading events fire. This allows these early scripts to execute as soon as the HTML is complete, as these types of embedded scripts usually need to control some aspect of the final HTML markup in the DOM. Remember: "embedded" scripts only affect one page, and are not used or cached for other pages in your website like "external" 'script' files do. So use them sparingly, if at all!
      • ALWAYS put your "external" script links, or any globally cached JavaScript files needed by the whole website, at the BOTTOM of all your HTML content inside the 'body' element. They will start downloading after the browser has downloaded the HTML above them and has parsed and rendered everything else. However, this order of processing is not guaranteed (see "defer" and "async" attributes below to fix that) because browsers will pause all processing when they encounter a 'script' element and must download, parse, and run the script, possibly delaying rendering of HTML. Note that, if you have critical JavaScript files which affect the rendering of the browser's DOM, then you DO want scripts to delay such parsing, stop all processes, and load their JavaScript files immediately. An example of this are the new Single Page Applications (SAP's) using these new JavaScript API's. Their 'script' tags will often need to appear at the top of the page in the 'head' element along with your 'link' CSS files. They will then download first or possibly in parallel with HTML, as they often control and manage the final DOM in the page. The rest, like JQuery scripts that manage animations or form validation, can be delayed. So, they should be placed at the bottom of your HTML page after all your HTML markup. Some scripts can fail even if loaded first or last and so still delay HTML parsing and rendering. Placing those dependent scripts last in your web page location guarantees that the page source order of any processing markup prior to running scripts is followed first in the page. Also, unless all the HTML markup is downloaded and available in memory, many scripts will also fail if they cannot find certain elements or events fire too early. This can also happen if they are not listed last in page order or run before all html is fully loaded. As a rule, you shouldn't rely or trust on any script order or prior parsing of any markup in any browser and add checks in your script to make sure elements even exist before running the script and add "onload" or other events which must fire first. But it still improves page performance to have all scripts but required ones run last in the web page.
      • ALWAYS put your "external" script links in a logical order of most important to least important at the bottom of your web page as browsers start downloading files initially in a sequential order. This may change based on the size of the files, using "defer" or "async" attributes (see below), or as connections open up. But, this is generally how browsers work. Some unusual properties of web pages include the fact that the browser will intelligently try and load some items in parallel into memory, as well, if enough connections are available. But source order of markup and scripts is still often strictly followed. This little order rule could save your page's overall performance as larger, less reliable scripts are downloaded last.
      • ALWAYS try and use the attribute "defer=defer" in your "external" script links to delay their use as long as possible until the DOM is fully rendered in the browser. This new "defer" attribute allows scripts to load in parallel with each other and with the downloading and rendering of HTML without delaying it. Deferred scripts once downloaded though, will not begin running until the complete HTML markup and page DOM is fully loaded, parsed, and rendered. Otherwise, by default, when browsers see 'script' elements, they will starting downloading and running script immediately, halting or delaying HTML rendering in the process. "defer" in the past told browsers the 'script' element will not generate any content and could be skipped by the HTML parser until all other content is downloaded. Therefore, the browser can continue rendering the body without considering the script element contents.
        Most browsers today, however, run the deferred script download in a parallel thread to all other downloads and processes as fast as possible, but do not delay HTML processing and delay running the script until the HTML is done and the DOM is ready. "defer" thus allows the elimination of parser-blocking JavaScript, where the browser would have to load and evaluate scripts in encounters in the page before continuing to download and parse HTML, causing a small page delay for the viewer. Deferring "non-essential scripts" is preferable and should always be used in pages with JavaScript linked via external files, especially those placed in the 'head' element where most of the delays can occur, UNLESS the script is critical in rendering the page. Otherwise, this attribute defers execution of JavaScript until all HTML downloading and parsing is completed. Note that multiple deferred scripts with the "defer" attribute all download in parallel, do not run their script files until the page is rendered, and honor script link order executed, whereas script tags with the "async" attribute (below) each run independently of each other and the order so they could arrive first or in any order at any time, and even delay other scripts by consuming connections. In practice, "defer" is used for scripts that need the HTML completed and the whole DOM rendered first before they can manipulate HTML and where their relative execution order is important. That is why I like to add "defer=defer" to all or most of my 'script' elements, including JQuery or validation scripts that do not need to run until after the page loads. In general, this attribute benefits most situations, except the heavy JavaScript API type files, like Facebook React and Google Angular, that do not need to be delayed for any reason and must get up and running as quickly as possible to build out the DOM themselves. Note that moving 'script' elements to the bottom of the web page is a form of "defer", but not guaranteed as using the attribute, as any script that downloads before HTML could stop its parsing and rendering. Note that IE 10 and later support "defer". In the past, there was a "fallback" strategy to help older IE browsers by using "async" and "defer" both as attributes. But that's no longer needed. Use "defer" in most cases.
        You can test when your scripts run by running this JavaScript code below. Deferred scripts will only fire after both the page is loaded and the DOM is built. You can test when that happens in your page using this script:
        
        document.addEventListener('DOMContentLoaded',
            () => alert("DOM ready after defer!"));
        
      • ONLY USE use the "async" attribute for JavaScript files that can be downloaded in parallel with HTML like "defer" but which must execute immediately or as soon as possible, pausing HTML or other parsing if needed. If you use the "async" attribute, understand it's used to fire up scripts as soon as possible. These types of script downloads might be best used with advertising displays, counters, or items that can appear immediately in a page, even if it means a short delay in page rendering. "async" works like "defer" in that both attribute types download without delaying HTML rendering, initially. But "async" will stop rendering and start running its code the minute its done. While the JavaScript is executing, it will stop all HTML processing until its completed. For this reason, I rarely use "async" in 'script' elements. Remember, unlike "defer" which downloads in order, "async" tells the file to start downloading in any order, as soon as an open connection is available. Take note, that not using either attribute means the browser synchronously downloads, parses, compiles, and executes JavaScript first, delaying HTML processing until its all done executing. Note that moving 'script' elements to the bottom of the web page is a form of "async", but not guaranteed as using the attribute, as any script at the bottom of the page that starts downloading could stop HTML parsing and rendering. IE 10 and later support "defer", where as IE 8-9 supports "async". In the past there was a "fallback" strategy to help older IE by using both "async" and "defer" as attributes. But thats no longer needed.
    9. Browser Support: 'script' elements have wide support in nearly all modern browsers and many older ones. So, they are fully supported.
    <section> section

    Section

    See also <header>, <nav>, <main>, <section>, <article>, and <aside>
    <section id="content" aria-labelledby="mainheading1">
      <h1 id="mainheading1">Section</h1>
      <p>Web page content goes here...</p>
    </section>
    Main

    Section

    Web page content goes here...

    Footer
    * A typical web page structure is shown above.
    My Recommendations:
    1. The 'section' element is new in HTML5 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 'section' element is a child of the 'main' element and houses all of the text content found in the web page. There may be multiple sections, sections holding multiple 'article' elements, or multiple sections inside an 'article' element. Unlike its twin, 'article' which contains text content, 'section can contain almost anything. In HTML5, the 'section' is part of a set of new structural page elements that define the overall layout of most HTML5 website pages designed today (<header>, <main>, and <footer>, etc.).
    2. The New HTML5 Structural Elements include: header, nav, main, footer, section, article, and aside.
    3. ARIA: The 'section' element is a top-level, "self-describing" structure recognized by most modern screen readers without additional assistance. In the case of 'section', it is recommended you add an ARIA "aria-labelledby="mainheading", then inside 'section' add your top header element with an 'id' value that matches. This then allows screen readers to associate the web page's main top heading (h1) and title with the main content section of the web page.
    4. See the <main> element section for more details about this new HTML5 element.
    <select> select

    Select

    see <option> and <optgroup>
    see <form> for more details using <select> in forms

    Shown below is a complete code sample of the <select> element, which you can copy-and-paste into your web project. It has a rich set of attributes I recommend you use for each scenario. The visual design for this form is shown below the code. With these examples you have a complete set of code you can use in your web forms.


    <form id="formselect" name="formselect" method="post" action="#" title="Select Example" aria-label="Select Example" autocomplete="off" autocapitalize="off" spellcheck="false">
    <fieldset id="formselect_fieldset1" name="formselect_fieldset1" form="formselect" style="background-color:#fff;">
    <legend style="background-color:#aaa;color:#fff;">Select</legend>
    <div>
    <label for="formselect_select1" title="Single Select">Single Select Label:</label><br />
    <select id="formselect_select1" name="formselect_select1" size="1" title="Select an Item" aria-label="Single Select" tabindex="0">
    <option selected="selected" value="">-- select a fruit --</option>
    <option value="strawberry">Strawberry</option>
    <option value="banana">Banana</option>
    <option value="grape">Grape</option>
    <optgroup label="Apple" role="group">
    <option value="apple_reddelicious">Red Delicious</option>
    <option value="apple_macintosh">Macintosh</option>
    <option value="apple_green">Green</option>
    </optgroup>
    </select>
    </div>
    <hr />
    <div>
    <label for="formselect_select2" title="Multiple Select">Multiple Select Label:</label><br />
    <select id="formselect_select2" name="formselect_select2" size="6" title="Select One or More Items" aria-label="Multiple Select" multiple="multiple" aria-multiselectable="true" tabindex="0">
    <option value="" selected="selected">-- select multiple numbers --</option>
    <option value="1">one</option>
    <option value="2">two</option>
    <option value="3">three</option>
    <option value="4">four</option>
    <option value="5">five</option>
    <option value="6">six</option>
    <option value="7">seven</option>
    <option value="8">eight</option>
    <option value="9">nine</option>
    <optgroup label="ten to twenty" role="group">
    <option value="10">ten</option>
    <option value="20">eleven</option>
    </optgroup>
    </select>
    </div>
    </fieldset>
    </form>
    Select

    Single Select Example

    A select form field is also called a "dropdown" or "list" by some. Below is a standard single 'select' element. I am also using "optgroup" in the 'select' element below to show how items can be grouped.



    Multiple Select Example

    You can add the "multiple=multiple" attribute to support multiple choices, as I've done below. Hold the Shift key, then select multiple rows of options. Or, hold the Ctrl key to select multiple options one at a time from the 'select' element.


    My Recommendations:
    1. The 'select' element defines a type of form field control used for showing a group or list of items in a box that one can choose and submit to the server. The 'select' element has been around since the 1990's and in the earliest of HTML recommendations by the W3C. Like most form controls, the 'select' element is considered a "replaced" element, as its design and actions are controlled by the browser and operating system. It has changed very little in the past 20 years, so is a bedrock form field element supported in all browsers and versions. As such, it can be safely used in all your web forms.
    2. What is a Dropdown?: Since 1996, there have been many names given to "select" that confuse developers and users alike. The main reason for the confusion was that old Windows desktop software engineers refused to embrace HTML and the web as something unique unto itself. It has its own design and use limitations in browsers. But early engineers tried to layer over Windows application design concepts onto the Web, and over time they failed to change or define it. (That is why ASP.NET has gone through so many redesigns at Microsoft and failed the last two decades.....software people refused to respect, much less understand, the true simplicity and power of HTML!). Often we were stuck with desktop software terms for "select", like "list", "listbox", "dropdown", "multiselect controls", and many other confusing OS or API terms and definitions, all of which ended up spitting out the same "select" element into the web page, at the end of the day. They used these terms as they helped them remember the good 'ol days of Windows desktop applications from years ago when they built their various types panels and modal windows of dropdown boxes and lists that often filled grayscale panels in screens. But all this ended up confusing everyone on the Web using new tools and standards! ("dropdown"?....you mean "select"?) Why didn't they just call it what it was, "select"? lol. After decades of confusion, I encourage all new web developers to stick with the term "select" rather than "dropdown", "listbox", etc.. Besides, the "select" term happens to be the name given to the actual HTML element! That way we are all talking the same language, which is HTML - the Language of the Web!
    3. Always Wrap a <form>: Element Around Your 'select' Elements: When you wrap a form tag around a 'select' control, it tells the browser your 'select' is associated with a specific form "id" value and will only submit the field elements associated with that control. If you have multiple selects and form fields to submit to a web page, it is crucial you know what select belongs with which form. You can still place the element outside a form if you give it a 'form={id}' attribute with a value associated with a specific form "id". In that case, it will be submitted with all the fields inside that specific form, though it might lie outside the form. However, I do not recommend you move form controls outside of a form, as some older browsers may fail to send the right data when submitted.
    4. Always Use the <label> Element with Your 'select' Element: Try and use the 'label' element before your 'select' tag, then add the "for" attribute with a value that matches the select's 'id' value to associate the two together. This links the label to the form field and allows the browser, search engines, and screen readers to connect the two, adding semantic meaning. Often, the browsers will float the label text above the select control. But I have added a break after it as select boxes tends to float right as an inline-block element (see my code samples above for examples of labels and select controls). "clicking" on the label's text auto-selects most form fields, but not in the case of select. However, giving your 'select' element a label is still important. Be sure to add a descriptive 'title' attribute to your label, as well.
    5. Collecting Form Field Data Using Select: The process of using 'select' elements and other form fields to collect and process data is way beyond the scope of this tutorial. The single most important aspect of good form field design (beyond HTML) is validation. That is discussed in-depth in the 'form' element section. The main thing to understand about forms and form fields is that data collection is the single most complicated aspect of web design, simply because it requires so many levels of exchange, validation, processing, analysis, and storage. Data collection and processing of form field element data is way beyond the scope of this tutorial. Just know, I have built dozens and dozens of large data collection applications in my life-time, and I can tell you good data collection always begins with solid HTML design, not fancy JavaScript, not fast REST API's, not secure server processes, not relational databases, and not fancy business applications. HTML is always King simply because HTML is the gateway between your users, your server, and your database.
    6. Always Use the 'id' and 'name' Attributes: Always use 'id' and a matching 'name' attribute with the same value when possible on all form field elements. The 'id' affects client-side scripts that must access a unique 'id' on the form field in order to access the control and its data. But 'id' is never sent to the server, unlike 'name'. If there are multiple select controls provided to the user, it is critical each have an 'id' and matching name. These value pairs must be unique for each element in the current web page. As mentioned, I like to always match the 'id' value to the 'name' attribute, as I do in all my other form fields. Why? The 'name' attribute is what is always sent to the server, along with the input's "value" attribute. Assigning both 'id' and 'name' to the same value helps your server-side processes identify which form field you are processing and align the field's 'name' on the server or in the HTML with any client-side scripted validation or pre-processing that uses the 'id' value. If the two attribute values match, it's very easy to locate and sort client-side from server-side processes. Also, in form fields the 'name' attribute is often parsed first as it is used when building name-value form field key-value pair data system sent to the server on submit. So, be sure to give each 'name' a unique value, match the unique name to the 'id' element, and be sure to put both first in the element!
    7. Always Assign a 'value' Attribute on all 'option' Elements: When a user choose one or more items from your 'select' element then submits the form, the 'select' element's "values" are sent to the web server along with the "name" of the 'select' element, when the form is submitted. For that reason, always add a "value" attribute inside each 'option' element, even if empty, with its text or data attached. Example: <option value="{value}">>My Option</option>. Often the text name inside the 'option' element is the same as "value" (like "yes"/"no", "on"/"off", etc.). But it can also be different from the "value". This is what is sent to the server as data, and part of the "name-value" attribute pair sent to the server from your form control when the 'select' is submitted. In the case of a 'select' element set as "multiple=multiple", each selected "option" will always send the same 'select' element "name" value for all the 'option' "values" selected. So make sure each 'option' "value" is unique, as you have to loop through the same array of names to get each value selected. The data for multiple select choices sent to the server will appear like this: myselect=1&myselect=2&myselect=3. IMPORTANT: If the "value" attribute in 'option' is omitted, the value is taken from the text content of the option element! Some older browsers will always do this. This is why, as a rule I try and match my text string to the value, unless its multiple words, a non-unique value, or the value is in another non-friendly format, like an abstract number, id, or value a user will not recognize.
    8. Use the 'size' Attribute: Use the 'size' attribute to change how many selections are shown in the listing. The default is "1", but changes to a larger value when the "multiple" select attribute is added. I like to always set this to "1" for plain 'select' listings, and then set it to four or more for my multi-selects. You can also set it to the number of items in the 'select' element so every one is immediately shown and available to be selected.
    9. Use the 'multiple' Attribute: If you need users to select more than one item from your 'select' element, add the "multiple=multiple" attribute. The box will then be resized to show multiple items by default rather than just one. This shows users that multiple items can be chosen. I like to set the first 'option' element in the list with an empty "value" attribute and to say, "-- choose multiple items --". This instructs them on what to do with the multiple-select listing. Remember, in multi-selects, you can either hold the control key on your keyboard and select multiple, one at a time, or hold the shift key and select large blocks of items at once.
    10. Always Assign a 'tabindex' Attribute Number: Almost all browsers, old and new, add form field elements to a "tabindex" list. This means that all interactive elements are available for tabbing through by a user in the browser as they fill out larger forms. You really do not have to add this extra attribute to your form field elements or worry about this feature as it's built into all modern browsers. Most of the old ones, as well new ones will logically add all your form fields and buttons to a tab list. Nearly all form fields, links, and buttons are added to the tabindex, by default. However, you can manipulate this to change the tab order of your form fields in the index, remove a form field control from the tabindex, or add one that was missed by using the "tabindex" attribute. I always add the "tabindex=0" attribute to all my form fields to enforce addition of each control to browser's tabindex, which also lets the browser reorder everything, naturally. I add "tabindex=-1" to remove fields from the tabindex I do not want included. "hidden" types fields are never added to the tab index anyway, but I add the "-1" value to all other interactive form controls I don't want users stumbling across (including disabled fields, read-only fields, etc.). You can also granularly control tabindex by setting each of your controls to a specific number in an order, like "tabindex=2", and set the specific order you want your users to use. You can also set "autofocus=autofocus" to force focus immediately to a specific select field after the page renders. This overrides the natural tabindex, however. You don't have to override these features in browsers unless you want to change tab indexing. "tabindex" and "autofocus" can help enrich your forms and add more control over how you intend users to use them. See my code samples above which use "tabindex", and read my section in this page called "TabIndex and Autofocus in HTML" for more details on "tabindex".
    11. Title, Required, Disabled, Read-only, and Hidden Attributes - Always add a "title" tooltip attribute as it provides a nice rollover description of your form field control. For any form field that must be filled out or selected, you must use the "required=required" attribute. Required text means the form field must be filled out with some data by the user or an error will be generated and the submission will fail. This attribute can be overridden by add the "novalidate=novalidate" on the form or form field. Be sure to set any 'select element' you do not want sent to the server as "disabled=disabled" in your inputs. Data you do want sent to the server, but not changed by the user, should be set using the "readonly=readonly" attribute. Also set "tabindex=-1" on these "disabled" and "readonly" controls so the user does not tab through them. In modern HTML5 browsers, a form field element with the added "hidden" attribute will not be seen by the viewer but remain an active form field. But, if the browser does not supports HTML5 your form control will not be hidden! The new "hidden" attribute is redundant, however, as there is a "hidden" 'input' type you can use instead which is always hidden and always submitted. But, there may be rare cases where you just need to hide it. In those situations, I recommend you use CSS "visibility" instead to hide things, as it will work more reliably in older browsers. If you use "display:none" to hide controls, remember the input will not be seen AND will not be sent to the server on submission, unlike the CSS "visibility" property or the "hidden" element attribute. See my section called "How to Hide HTML5 Elements and Content using CSS" for more information on hiding elements in HTML correctly.
      Note: Always use the "XML-friendly" version of these attributes so your tags are always cross-compatible with both XHTML and XML. Do not use "readonly", but type "readonly=readonly".
    12. Optional 'novalidate': I discuss this attribute in more detail under the 'form' section (see <form>), as the form really controls this setting over all its child fields. But often you will have a 'form' with default settings and want to override them in each form field. A difficult one to manage is "novalidate". In general, the code samples above showcase my "best practices" and recommendations for how each field should use this attributes.
      The good news is "novalidate" is removed by default, meaning validation is enabled for the select control, which in my opinion is a good thing as HTML5 browsers now come with a new array of validation checks and features. Again, see my 'form' section for more details on how these work and some additional tricks to force them to do what you expect. But if you want to turn off validation on a field and override the 'form' element's default value, you can add the "novalidate=novalidate" attribute to your element.
    13. Do Not Use "accesskey": I do not recommend use of this attribute. Long ago, it was designed to allow keyboard presses to access form fields. But it is not reliable and requires various additional combinations of keys to work that are specific per device or just not accessible. It also conflicts with operating system shortcuts and could trigger other features on a laptop or phone by accident.
    14. Do Not Use New "inputmode": This new attribute is gaining in popularity, but still poorly supported in browsers. "inputmode" is now used as a "hint" to tell browsers the type of data to expect, like "email", "search", "url", etc. Because its not supported in IE, Safari, or Firefox browsers prior to version 24, it is not helpful or reliable.
    15. The Optional "data-" Attribute: As mentioned below in my "Best Practices" article called "The New 'data-' HTML5 Attribute", you can now safely use the new "data-" attribute in any HTML form element to store extra data values. Know that this is an extra attribute, and that "data-" values are not submitted to the web server anyway, so pretty useless. Its mainly an add-on for JavaScripted frameworks on the client-side.
    16. ARIA Attributes: The 'select' element is another "self-describing" structure recognized by most modern screen readers. Most screen readers can read each select box quite well, and understand what each one does. So, they do not need the ARIA "role" attribute. But they do need help knowing what type of data is being selected so they can identify its semantic meaning. For that reason, it is recommended you add an ARIA "aria-label={Name of Item}" on each 'select' element to give screen readers more details about your 'select' does and its meaning within the form. You should also use the "aria-multiselectable=true" on multiple 'select' types. You do not need the ARIA "live" attributes telling screen readers the "state" of your controls as they change unless you are manipulating the DOM using JavaScript. Use my code samples above to see "best practice" uses of ARIA attributes when designing select controls that assist screen readers.
    17. See the <option> and <optgroup> elements for a list of recommended attributes (I have tried to include those in the 'select' code examples above).
    18. Form Field Validation: As mentioned above, and in the <form> section, it is not enough to drop form fields like 'select' onto web pages and then hope the data coming into the server works. I have found too many cases where poor data processing ends up destroying a website! Even with fancy JavaScript, you cannot ignore the HTML design and server processing. That also includes heavy database scrubbing and processing. You need to always validate your form fields, no matter what the type, in ALL layers of your application. Do it, not just to improve data collection, but for security reasons as well! Data validation is not part of the scope of this tutorial but is native to the specific language, framework, network, and database architecture you are using. Don't rely on a single product like JQuery (JavaScript), either. Rely on good server-side validation, always, but good HTML design, too. It will help the user get the data right on their end without waiting on elaborate scripts to warn them later. Getting the HTML design right helps them navigate your forms faster, and makes it much easier for them to enter good data. Good HTML means it's one less layer you have to wrestle with. And it frees up control of data entry to your users, not your script libraries or your server.
    19. Trouble Styling Replaced Controls with CSS: "Replaced" elements like 'select', 'textarea', and others are notoriously difficult to style using CSS and have been for years. The reason is, they are not part of HTML but controls generated and dropped into the viewport by the browser. This is why these controls look so different between Macs, Windows PC's, and mobile phones. The browsers on these devices call the OS which helps determine their designs. Without getting into all the "hacks" and fixes out there to try and override these OS controls, I highly recommend you use plain HTML then stay with plain CSS code to style what you can and avoid all JavaScript, Modernizr, Polyfills, or "scripted hacks" to try and change their native designs. There are some clever CSS styles you can apply that alter the look-and-feel of these controls enough using just a few lines of CSS text that they are "presentable" and look close to the same across old and new browsers alike. There are also "prefixed" CSS rules (browser-specific styles like "-moz", etc.) that also can safely be used and which avoid JavaScript completely. If you start using scripts that hide or replace the HTML with a new form of control, you not only add complexity and unnecessary "hacks" that will likely cause form submission issues, but often it will fail completely in certain older browsers. In addition, your HTML will now be too complex for others to customize and likely erased when the next developer comes behind you.

      Below, I have added a very clean, widely supported piece of CSS code you can use to give your 'select' element a nice clean style that looks the same across many browsers and versions. This is the basic style I use for the 'select' example above:

      
      select,
      select:visited,
      select:hover,
      select:focus,
      select:active {
      	display: inline-block;
      	width: auto;
      	height: auto;
      	min-width: 0;
      	max-width: none;
      	padding: .17em .17em;
      	padding: .17rem .17rem;
      	margin: 0;
      	text-transform: none;
      	border-radius: .2em;
      	border-radius: .2rem;
      	border: 2px solid #bbb;
      	background: #fff;
      	cursor: pointer;
      	-webkit-appearance: listbox;
      	-moz-appearance: listbox;
          line-height: normal;
      }
      
      select:visited,
      select:hover,
      select:focus,
      select:active {
      	background: #f9f9ff;
      	border: 2px solid #999;
      }
      
      select:focus {
      	background: #fff;
      	border: 2px solid #999;
      }
      
      
    20. See the <form> element section for more details about this element within a form.
    <small> small, smaller

    Small

    This is some <small>small</small> text.
    This is some small text.
    My Recommendations:
    1. The 'small' element was used to show smaller text in an inline block of text.
    2. Do not use the 'small' element as it is deprecated now and was a member of old HTML4. Use CSS and 'font-size:smaller' 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:smaller;">smaller</span> text.

      This is some smaller text.
    <spacer> spacer

    Spacer

    <p>Some text<spacer type="horizontal" size="20"></spacer>some text</p>

    Some textsome text

    My Recommendations:
    1. The 'spacer' element is deprecated but was a non-standard HTML element used by older browsers to create white space. This tag is redundant as you can now control spacing using CSS and was also never a part of HTML5. Do not use the 'spacer' element.
    <span> span

    Span

    <p>Lorem ipsum dolor sit amet, mea enim erat id, regione iudicabit consetetur ius ex. Qui vide errem ut, ius id movet atomorum. <span style="color:blue;font-weight:bolder;">Sit pericula definiebas ei</span>, ex eam essent maluisset. <span style="color:red;font-weight:bolder;">Duis ceteros pro ut.</span> Mei eius labore ut. Iusto facete facilisi vel id, nonumy omnium constituto ad pro. Mei in sale option.</p>

    Lorem ipsum dolor sit amet, mea enim erat id, regione iudicabit consetetur ius ex. Qui vide errem ut, ius id movet atomorum. Sit pericula definiebas ei, ex eam essent maluisset. Duis ceteros pro ut. Mei eius labore ut. Iusto facete facilisi vel id, nonumy omnium constituto ad pro. Mei in sale option.

    My Recommendations:
    1. The 'span' element represents a small inline piece of text. Unlike the <p> element, the 'span' element wraps around smaller pieces of text within a larger paragraph, allow for styling or other CSS customizations of text. For this reason, it most often is used inside the 'p' element. Because the 'span' element has been around since the birth of HTML in the 1990's, this element has not changed in any of the browsers, and so is very reliable.
    2. CSS and the 'span' Element: The 'span' element's primary function is as a means to mark up or customize text. Changing spanned text with CSS is quite common. Avoid "inline" styles (as I am using) in spans and instead use CSS "class" attributes with a class selector in your style sheets when styling spanned text.
    <source> source

    Source

    also see <audio>, <picture>, and <video>

    The 'source' element is only used as a child element for a 'audio', 'picture', or 'video parent elements in HTML5. It defines alternative "sources" of media for all three tags. Shown below is an example of how to use the 'source' element with the 'picture' element. In this example, the 'source' tags provide alternative images for the 'img' element.

    <figure aria-labelledby="source1_caption" style="padding:.5rem;border:1px solid #bbb;background: #f0f0f0;width: auto;height: auto;display: inline-block;">
      <picture id="source1">
        <source srcset="image.webp" type="image/webp" />
        <source srcset="weather.gif" media="(min-width: 800px)" type="image/gif" />
        <img id="source1_img" style="width: auto;height: auto;max-width: 100%;" src="www.jpg" width="255" height="200" alt="image: World Wide Web" title="The World Wide Web" aria-label="Image of the World Wide Web" loading="lazy" onerror="this.onerror=null;" />
      </picture>
      <figcaption id="source1_caption" style="display:block;">
        "Which Image Appears?"
      </figcaption>
    </figure>


    image: World Wide Web
    "Which Image Appears?"

    * Note: My host provider does not support "WebP" images I found out, so if no "flowering tree" WebP image appears, it is not the code but my host provider. :(

    My Recommendations:
    1. The 'source' element is a new inline HTML5 media element that allows for the display of alternate media formats for the 'audio', 'picture', and 'video' elements. The 'source' element enables these media element to utilize more advanced media "choices" and media queries, as well as newer media formats.
    2. The 'source' Element: The 'source' element provides alternative formats for the 'audio', 'picture', and 'video' elements based on browser support, viewport size, or other criteria using four main attributes (see below). The browser first checks these 'source' elements one at a time. The browser examines each 'source' element's "srcset", "media", "size", and "type" attributes to select a media file that best matches those criteria. If the media "type" is supported, media dimensions or device resolutions match, and viewport dimension requirements are met, then the alternate "srcset" URL value is passed into the media element and used for display. If the criteria are not met then the default media tag's "src" URL or fallback text message is used.
      Multiple child 'source' elements can be added inside the media element to give newer HTML5 browsers the ability to choose from among numerous media types in deciding which one to show inside the main media element. In the case of 'picture', the 'img' element receives the 'source' element's "srcset" url and image file. In the case of 'audio' and 'video', the 'source' element itself holds the media file. Multiple 'source' element options can allow browsers the ability choose from a much richer array of media files based on support for different media "types" supported by a user's device, the ratio of CSS pixels to "device pixels" on the user's device, actual width of the media file, or the dimensions of the user's viewport using media queries. For this reason multiple source tags (usually 2-3) are often added under the main media element, with each one having a different media choice for the browser. The browser will then look for the first 'source' element from the list and check its 'media' "query" value, if any, then the 'type' attribute to see if the encoded image type is supported in the user's browser. When the media query value matches the current viewport width and the media type is supported, then the browser will use the 'srcset' path to the media file and display it inside the media element (audio, video, picture). Below are the four main <source> tag attributes supported and their role in controlling alternative media:
      • srcset - It simply contains a path to an alternate media file to use, plus a space then a place to add either the width of the alternate file in the case of images ("320w") or the "device pixel" dimensions ("3x") the file should support. The latter means that the media file may be saved at twice the standard PPI or resolutions of the other files, so would look better on say an iPhone or other high definition screen. Like the "srcset" attribute for the 'img' element in 'picture', this last value is the "expected width" of the alternate file (actual width, not styled) or its resolution, which tells the browser its expected value and helps the browser decide when to use the file based on the available width of the user's screen. Example: "srcset=image.webp 320w" means only use this image that has an actual width "320 pixels" if it can fit into the screen. The browser will decide this. Instead of using the supported image width, you can use the device pixel check, as in "2x". The "2x" value if used would says use this image in any screen device that has a higher "device pixel" value of 2 or higher. This means that the screens pixels are so tiny and can hold so many more than a desktop or laptop that you have created a high resolution file twice as dense in resolution (same width as other images, though) to support these types of devices. Most iPhone screens now support 400+ PPI resolutions screen with tiny pixels, which translates into a 2-3x increased pixel density for images. In those cases, say using the value "srcset=mynormalfile,jpg 1px, my2xfile.jpg 2x", you would prepare the first image with a normal PPI resolution for desktop browsers, then the same image for the second with the same width as the other, but with twice the resolution or PPI density of pixels for say iPhone HD displays. In the case of the 'picture' and its 'source' elements, they do not do anything other than support the 'img' tag with a new "src" URL and file. For 'audio' and 'video' media elements, the 'source' elements "srcset" sets the chosen file directly so are the supporting media elements.
      • type - The "type" attribute on the 'source' element contains a media type in a given format. Example: "image/jpg", "video/mpg4", etc. It is usually a common media or MIME type often sent to the browser from a web server as a hint along with the file. Each media type and its format or encoding may or may not be supported by modern browsers, however. Often, the 'source' element is only used to offer very advanced or newer media types, like "WebP" for images, etc. Know that there are still problems with support of these newer formats in browsers today. For example, the new "AVIF" image format is currently only supported by Chrome Webkit browsers, so would fail for every browser except the newest Chrome versions. "WebP" is another promising alternative "type", but is not supported in any Internet Explorer browsers and many others, like iPhone Safari, which did not support "WebP" until 2020! So, types like this are offered as alternatives only, until browsers in the coming decades support them. But you could add these types of media files using your "type" attribute in 'source' elements and thereby offer browsers reading your 'source' tags checks to see if they support them.
      • media - The new media "query" attribute allows you to set when any given media type should be considered by the browser, and if any additional scaling (or stretching) of the media from its default value should occur. It allows you to tell browsers when to scale these alternative files larger or smaller in dimensions relative to the viewport. Note that this only works in HTML5 browsers that support these types of media queries. There are two main media query formats to use: "Media Conditions", like "max-width" or "min-width", which relate to a devices viewport width or supporting characteristics, and "Media Intrinsic Width", which is the width the alternative file should resize or scale to (based on a devices screen or viewport, not the file's actual size or styled size). Example: "media=(max-width:800px) 50vw" in a 'source' element means to only use this media file alternative if the device's viewport or screen is less than 800 pixels. Second of all, it says, when triggered, scale the image to 50% of the viewport or "50vw". This might trigger a user on an iPhone or tablet to pull down a higher resolution file that's designed for smaller screens, but which is then scaled down an additional 50% to fit into the smaller space. Personally, I would not use the "scale" feature as its wasteful and redundant to scale or distort images and media files. You should have them simply use their original size and resize them and their resolution or PPI as needed to fit the viewport.
      • sizes - If you want to rescale or "stretch" you media file relative to the screen or viewport, you will want to use this attribute. I do not recommend it as "stretching" files is an old technique that's rarely if ever needed. But you could use this attribute to set a viewport value. An example of all this would be "100vw" which says, stretch a media file in width 100% of the viewport. Again, not a good idea. I would rarely use the "sizes" feature unless you are ok stretching and distorting your media files to fill the screen. Instead, use the "srcset" feature to decide what dimension or resolution of image to use.
    3. 'source' and CSS - NEVER style the 'source' element as its an empty element. Instead, style and resize the 'img' (inside 'picture), 'audio', or 'video' elements directly.
    4. ALWAYS use the XML-friendly version of 'source' with the " /" at the end as so: <source />. Do not let others convince you this is a "void" element or that this format is not compatible with HTML5, because it is.
    5. For more advanced examples using the new 'source' element, see my articles below: "The New Picture Element" and "How to Create a Cross-Browser Video in HTML5".
    <strike> strike, strikethrough

    Strike

    This is some <strike>struck through</strike> text.
    This is some struck through text.
    My Recommendations:
    1. The 'strike' element was used to represent text with a "strikethrough" line. The struck text could represent text that was deleted, changed, bad, misspelled, or replaced in a sentence. Because the context was lost and this was a purely visual element, it was removed from HTML5.
    2. Do not use the 'strike' element as it is deprecated now and was a member of old HTML4. Use the new <s> or "strikethrough" element which represents text whose meaning has changed, or the <del> and <ins> elements to indicate deleted text that has been replaced.
    <strong> strong

    Strong

    <p>This text has <strong>strong</strong> importance and should stand out.</p>

    This text has strong importance and should stand out.

    My Recommendations:
    1. The 'strong' element is a piece of inline text representing very important text that needs to be stressed. It is usually represented visually by bold or bolder text.
    2. Note: Use 'strong', not 'b' 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 'b' were used to only format or style text, not stress its importance. And so the meaning of the text was lost using 'b'. Today in HTML5, importance has shifted to semantic tags that carry meaning as well as style, like 'strong', which tells search engines and readers this piece of content has weight and should stand out. When you have text in a paragraph that has strong importance use the 'strong' element rather than the 'b' element.
    3. 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 'em' for its sibling type)
    <style> style

    Style

    also see <link>


    A 'style' element is a non-visual (invisible) element that resides inside the <head> element of a typical web page. This element contains "embedded" style sheets that only apply to a single web page. Below I have listed a code example you can use to enhance your website with styles. Note: I do not recommend you use the 'style' element for styling websites, however, as it only applies to a single page and therefore wastes bandwidth delivering the same code over and over on every single page view. Instead, use the <link> or "external" CSS style sheet strategy which applies a single downloaded style sheet to an unlimited number of web pages at once. It is also fully cached for weeks or months in the web browser. Note: The "strange" CDATA code that wraps around the CSS in 'style'. This is "extra" code designed to hide CSS styles in the tags from XHTML/XML parsers and older non-supporting CSS browsers (see my recommendations below for a full explanation). This code, however, works fine in all HTML5 browsers going forward.


    
    <style type="text/css">
        <!--/*--><![CDATA[/*><!--*/
    
        p {
    	    display: block;
    	    clear: none;
    	    padding: 0;
    	    margin: 1em 0em;
        }
    
        /*]]>*/-->
    </style>
    
    
    My Recommendations:
    1. The 'style' element appears in the head of a web page and is used to apply "embedded" CSS styles within a single web page. An alternative to the 'style' element is the 'link' element or "external" style sheet system that can download larger style sheets pages for all web pages. The 'style' element has been around since the 1990's and has changed very little in the past 20 years. 'style' elements really began when CSS (Cascading Style Sheets) was adopted by the first web browsers. The first CSS-supporting browsers were Internet Explorer 3 in 1996 and Netscape 4 in 1997. So the 'style' element was supported in web browsers around that time. Unless you truly need "embedded" styles that only affect a single page in your website, I recommend you use the "external" 'link' version, instead.
    2. Cascading Style Sheets (CSS) - I recommend you avoid 'style' elements with "embedded" CSS style sheets. Use of "external" CSS files using the 'link' element is superior to 'style' when managing the design and layout of your website. Why? External CSS is far superior to "embedded" (<style>) and "inline" element styles (<span style="color:blue;">my text</span>) simply because external styles downloaded to the browser are cached for every page in your website and affect all web pages, not just one. Often inexperienced developers use inline or embedded styles and forget about externally linked CSS sheets. They assume they are slower, inferior, antiquated, or difficult to manage when the opposite is true. They then lose out on valuable, reliable, proven technology that is far superior to anything built today. Links to multiple external CSS files also download in parallel to each other in a very quick fashion in most browsers, so there are few delays. Browsers have been doing this for over 20 years. Unlike large libraries of scripts, linked CSS often has a very tiny footprint and so has very little affect on page rendering or paint delays, simply because modern browsers manage these downloads very effectively and have been for decades. Once your CSS files are downloaded, they are cached and indexed in browser folders, allowing future page views of your site to be rendered and painted in the browser very quickly. Note that these "embedded" styles are only really useful for "offline" styling of pages. The only real benefit to using these "embedded" style blocks was for caching of offline styles for devices like old handhelds, which reallu benefited from using cached pages with associated styles attached to them. Today, that is rarely needed.
    3. The "type" and "media" Attributes: When using CSS in 'style' elements, the browser will recognize the 'style' element as used for CSS and default to a "type" of "text/css". But it is a good idea to go ahead and explicitly set its attribute as so: "type=text/css". Note: Some HTML5 validation tools online may not validate with this "type" setting as many recommend you remove the attribute altogether, for some strange reason. The assumption may be 'style' elements are exclusive to CSS, now, so the attribute isn't necessary. But older browsers may not assume that is true. So, I recommend you ignore the validators in this situation and keep the attribute in place, as described above, for wider cross-browser support.
      The "media" attribute is widely used to determine the type of device the styles should be applied to, much like the 'link' element (see the <link> element recommendations for more details). If you leave off, say "media=screen", the styles will generally apply to "media=screen" by default in many older browsers using the HTML 4.1 spec. Note that this is the opposite for 'link' elements, which default to "media=all" today in HTML5. As with 'link', never use "all" explicitly due to lack of browsers support, but use "screen", "print", and specific types. For now, I recommend you do not use a media type setting on the 'style' element based on HTML5 recommendations. Instead, just leave it off and assume your styles affect all devices.
    4. The "style" Element with CDATA Comments: If you must use these the 'style' element for delivering CSS, I have added an XML-friendly, "no CSS support" friendly "CDATA" version to the "embedded" code example below, which is superior to any embedded 'style' coding block you will find online. It supports your page scripts in XHTML 1.1, XHTML5, XML parsers, browsers with no CSS support, and more modern browsers with full support for CSS. Use this version below if you have to use "embedded" style sheets. Note: You typically add style blocks in the <head> of your web page. This forces the browser to parse and load the styles first into memory before downloading HTML content and should only contain styles that need to be fully preloaded first and which directly affect or control HTML right after before it is rendered and painted. This CDATA code below inside the 'style' element supports HTML5 parsing, XHTML, XHTML5, and very old browsers that do not support the style tag or even CSS. In all cases, using the code below will not blow up in any of the browsers or allow your styles to get rendered accidentally as markup or even text:
      
      <style type="text/css">
          <!--/*--><![CDATA[/*><!--*/
      
          /* put your styles here */
      
          /*]]>*/-->
      </style>
      
      
      Some History on this Strange Code Above: Going back to the 1990's, you were allowed to place these HTML comments "<!--" and "-->" inside the 'script' element to hide CSS and style code text from non-CSS supporting browsers, which would recognize the HTML comments and hide the style text. Supporting CSS browsers back then would ignore them and execute the styles. Why? These 'script' and 'style' elements read anything inside the tags as character data or CDATA, which means no HTML is recognized inside the tags. HTML comments are still HTML so ignored by them. So, most browsers that supported CSS back then ignored these HTML comments, as anything in these elements was considered CDATA, allowing CSS to execute safely for them. By the way, these now defunct older non-CSS supporting browsers included IE 1-2 and Netscape 1-3. For them, the HTML comments meant the style code was safely commented out. Added to this problem has been XHTML and XML parsers, which do not know the code between these tags is just CDATA. Such parsers would blow up if they parsed CSS that contained any XML entities or markers. Many of these XML-friendly parsers did not need CSS at all. To fix the code for them, I had to expand the comments above to force those parsers to ignore the CSS code, as well. And so that is how I came to develop the solution above. In the HTML5 browser world today, nearly all browsers known now support CSS. But adding the comments and safety code above allows you to still support a range of very old non-CSS supporting browsers, XHTML, and XML parsers combined, should you need to share your code or web pages with any of these parsers or browsers. They will not blow up now when encountering your CSS code using the comments above. The code above is completely safe to use now in newer, more modern HTML5 browsers. But when used, it will make sure your JavaScript blocks are ignored in XML parsers and non-CSS supporting older browsers alike.
    5. Cascade Order and the 'style' Element: Does the order of "embedded" (<style>) and "external" (<link>) style sheets in the <head> of your web page affect the cascade order of similar style rules on elements? It is an important question. It turns out it DOES in modern HTML5 browsers, but did NOT in many older browsers (pre-2010)! Why? Older browsers used to have a very good rule the W3C used to require they follow. It basically said that no matter where external <link> styles appear in the <head> of your web page, "embedded" or <style> CSS was always last in the order set inside the browsers cascade memory, not in your web page. In other words, embedded styles always cascaded over linked styles using the same selectors, even if you placed external linked CSS AFTER embedded CSS in your web pages. Linked external CSS elements always came before embedded CSS in the memory of the browser, no matter what physical order your code used. This is NOT the case in newer HTML5 browsers, I found out. This might be a subtle issue to you, but if you stack lots of "element" style rules in your external and internal style sections of your web page 'head' element, rules that use the exact same selectors, if you do not order your linked external CSS elements correctly then you might see some cascade over others, unexpectedly in newer HTML5 browsers! Order of styles now matters in your pages, where in the past it did not. The reason newer HTML5 browsers now strictly honor specific style sheet "source order" in the "head" of your page, regardless of linked vs embedded types, is because HTML5 has gotten lazier and looser in defining such things. In other words, be careful in the order you place linked and embedded styles, as they do matter today. Embedded sheets no longer have higher source order over linked sheets, as they did in the past. To match old and new browsers so they both work the same using external and embedded sheets, ALWAYS add your linked sheets (<link>) above your embedded ones (<style>) in the head of your page.
      Unfortunately, newer browsers today using HTML5 decided to ignore W3C and Web Standards, so now order matters. This is counter-intuitive, so I recommend you follow the rule above and you will have no issues with CSS cascade order going forward in any of the browsers you support.
    6. Avoid All Internet Explorer "Conditional Statements": In the long and troubled history of Internet Explorer and its support/non-support of HTML and CSS, many developers over the past few decades solved those cross-browser issues by hiding specific style sheets from all browsers but IE using special "Conditional Statements". In the past, many authors tried to address the numerous CSS bugs in Internet Explorer by using special code that hid certain linked style sheets from other browsers, but which were only specific to a version of Internet Explorer. Without going into the long history of this type of trick, I can say today this technique no longer works for newer IE browsers (version 10, 11, or the new Edge browsers). So, it is time to retire them completely. An example of such code is shown below so you know to avoid this code trick when trying to design CSS for older IE versions. This code below hides two linked CSS files that have special CSS hidden from all browsers but two older, specific Internet Explorer browser versions):

      <!--[if IE 8 ]>
      <link media="screen" rel="stylesheet" type="text/css" href="/styles/ie8only.css" />
      <![endif]-->

      <!--[if IE 9 ]>
      <link media="screen" rel="stylesheet" type="text/css" href="/styles/ie9only.css" />
      <![endif]-->

      * DO NOT USE THIS CODE! Because IE is nearly dead, plus IE 10-11 no longer supports these conditional statements. I do not recommend you use these IE coding tricks going forward, but instead cope with older IE versions using other techniques (I use a new CSS framework I built which uses "@import" rules IE 1-7 cannot understand and which hides my CSS style sheets from all IE 1-7 versions, giving these older browsers plain white HTML pages). Avoiding these custom page-by-page IE hacks means one less customization you now have to worry about in your web pages when dealing with the complexity of styling for older browsers using 'link' elements. (The ONE EXCEPTION to this rule is in my "Best Practices" section below called "How to Force New HTML5 Elements to Work in Old Browsers" where I encourage the use of IE Conditional Comments for forcefully adding missing HTML5 elements to non-HTML5 IE versions 1-8 browsers using a script.)
    7. The Myth of CSS @Import Render Blocking: I recommend you also use the 'style' element to directly import in external CSS files if you like. To do that you can use the "@import" CSS declaration. Because this tutorial only covers HTML I cannot go into style sheets. But it is an option I encourage you to use. And no, @import will not "render bock". Let's talk about that concept now.
      The CSS rule "@Import" is often used to make additional calls to external CSS inside embedded CSS files. A 'style' with @import calls to other external files is a very common practice and fully supported by all CSS recommendations today and 20 years ago. But sadly, some developers have started to demonize the practice unfairly, as a technique that causes "blocking" delays of other linked CSS style sheets. The fact is, this is completely false.
      When using the CSS rule "@import", the idea is to break up reusable CSS into files that can be delivered in pieces as needed. Often these CSS styles are placed into a single 'style' tag so all the import calls are managed in one place. Some claim these calls then add additional download time as they are "render-blockers", meaning they cause either the other "@import" calls to wait, or other 'link' CSS file downloads to be delayed. Others claim the reason for this is that import calls no longer download in parallel with each other or the other synchronous sheets, like linked sheets are designed to do. It turns out all that is completely false!
      In fact, multiple imported style sheets inside a linked style sheet all download in parallel relative to each other, with no blocking issues ever, and use shared connections for added speed in most browsers. The "@import" style rule only adds one extra call when combined with CSS styles inside the same linked parent sheet as the importing of other sheets must make one call in addition to the parent sheet call that holds them. Any delay here is on that one extra connection, not the import call. Thats it! The parent sheet that holds imports starts the new required connection then downloads all internal import sheets together as long as there is no other delays in receiving its own CSS. My sheets never have any additional CSS, only more imports. Only old Internet Explorer browsers had some inability to download imported files in parallel with other linked sheets. The main way to reduce render blocking is NOT avoiding use of "@import" CSS rules, but by using fewer external files and smaller files, like smaller images and less JavaScript. Most modern browsers have a default connection limit of 6 connections anyway, as I have mentioned, so parallel downloads of numerous imported CSS files does not speed up CSS if scripts or images are being downloaded in parallel via those few connections. "@import" isn't affecting parallel downloads of files as long as you avoid combining them with other raw CSS in the same file. I never do this, so using @import is a viable CSS strategy to use in connecting to multiple CSS files in your web page and to hide cutting-edge CSS3 from older browsers. The "myth" of these "blocking" claims has been exposed and should now be ignored. It is 100% safe to use @import in CSS linked files to download more CSS you might need without any worry of page render delays or blocking of other linked CSS files.
    8. Browser Support: 'style' element has wide support in nearly all browsers, old and new. So, is fully supported.
    <sub>, <sup> subscript, superscript

    Subscript and Superscript

    <p>Here is a chemical formula: H<sub>2</sub>O. <br />Here is a famous equation: e=mc<sup>2</sup>.</p>

    Here is a chemical formula: H2O.
    Here is a famous equation: e=mc2.

    My Recommendations:
    1. The 'sub' and 'sup' elements represent inline subscript or superscript text that must appear half a character below or above existing text. This text is often formatted in a smaller font-size setting for typographical reasons. Both 'sub' and 'sup' have been around since early HTML standards and still used today. Use these types of text for footnotes, mathematical expressions, scientific formulas, date notation, references, and more.
    <summary> summary

    Summary

    also see <details>

    The "summary" text is show below. It is the top gray "click-able" section in the 'details' element below.


    <details id="summaryexample1">
      <summary style="background-color: #ccccccff;box-shadow: 2px 2px 3px #aaa;">&copy; Copyright 2022</summary>
      <div style="margin: 0;padding: .2em 1em;background-color: #efefef;box-shadow: 2px 2px 3px #aaa;">
        <p>Owned by Company ABC. All Rights Reserved.</p>
        <p>All content and graphics on this web site are the property of Company ABC.</p>
      </div>
    </details>
    © Copyright 2022

    Owned by Company ABC. All Rights Reserved.

    All content and graphics on this web site are the property of Company ABC.


    My Recommendations:
    1. The 'summary' element is new interactive element in HTML5 which belongs to the 'detail' interactive element. It represents a title, caption, or legend for additional content contained within a "click-able" disclosure box. The text summary shows 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. The 'details' element is typically used as a JavaScript-free toggle widget to disclose additional information if the user chooses to view it.
    2. CSS and the 'summary' Element: In general, avoid styling this element or risk "erasing" the browser's built-in arrow and toggle interactive feature. Some like to add block-level elements inside the 'summary' tags. But this gets pushed down below the arrow to the next line and destroys the layout feature. Changing 'summary' to then be a "display:inline" element pulls the block element back up, but then text below 'summary' in 'details' pulls up to the right of the element in many browsers (like IE). Because IE and Trident Edge still do not support this element correctly (see the 'details element), changing the CSS on it start confusing browsers and dismantling its native interactivity. You then get into a rabbit hole with elaborate CSS hacks. Developers then start adding elaborate JavaScript "polyfills" to compensate, and before you now it you have turned a simple, elegant HTML5 feature into a monstrosity! I recommend you stick with only changing colors and text styles on the 'summary' element, if you choose to style it, and avoid these circus tricks.
    3. See the <details> element for more detailed information about this element and all its features and properties.
    <svg> scalable vector graphics

    Scalable Vector Graphics

    also see <canvas>


    A Simple SVG Example

    Below, is a simple example of how to use SVG in HTML5 to create an image dynamically in the browser. If your browser supports HTML5, then it will likely see the words "SVG" drawn in the middle. There are many more powerful examples of SVG art online.

    
    <svg height="120" width="120" xmlns="http://www.w3.org/2000/svg" title="My SVG Image" aria-label="SVG Image">
        <text x="0" y="0" style="font-size:3em;fill:green;">
            <tspan x="32" y="55">SVG</tspan>
        </text>
      Sorry, your browser does not support Scalable Vector Graphics technology (SVG).  
    </svg>
    
    SVG Sorry, your browser does not support Scalable Vector Graphics technology (SVG).

    SVG for Cross-Browser Support

    If you plan to use "external" SVG XML files (which I recommend you do), you have the power to deliver alternative SVG images to regular HTML5 browsers with added bitmap versions or alternative images of your SVG in pixel formats for older browsers that do not support HTML5. Below is an example of a "fallback" code you can copy and modify as needed when supporting older browsers that do not support SVG. Modern HTML5 browsers will read the 'object', 'embed' or "xlink" image source, while older browsers will either see a pixel JPEG image or text.

    
    <object 
        id="mysvgobject1" 
        name="mysvgobject1" 
        data="mysvgfile.svg" 
        type="image/svg+xml" 
        title="My SVG Image" 
        aria-label="SVG Image" 
        title="My SVG Image" aria-label="SVG Image">
            <embed 
                    id="mysvgembed1" 
                    src="mysvgfile.svg" 
                    type="image/svg+xml" 
                    title="My SVG Image" 
                    aria-label="SVG Image" 
                    title="My SVG Image" aria-label="SVG Image">
                <img xlink:href="mysvgfile.svg" src="myfallback.jpg" title="My SVG Image" aria-label="SVG Image"> />
                <noembed>
                    Sorry, your browser does not support Scalable Vector Graphics technology (SVG).  
                </noembed>
            </embed>
    </object>
    
    My Recommendations:
    1. The 'svg' element stands for "Scalable Vector Graphics" and is a new graphics display element in HTML5 which allows rendering of visual design in the browser using XML. This new graphics coding ability in HTML5 browsers supports fast rendering of linear or "vector-based" designs using points, lines, and effects which are scalable and transferable across various systems using simple XML code rather than JavaScript libraries, static pixelated images, or image processing software.
    2. Features of the new 'svg' Element: The promise in HTML5 of using faster, coded forms of graphics and images in web browsers arrives with the new 'svg' element! We have been using this type of image format for decades and decades offline, in applications like Adobe Illustrator and Adobe Acrobat with their ".eps" and ".pdf" postscript formats. The power to design text using vectors is the basis for font technology, as well. Most of this technology came about in the 1980's, and has been in use for laser printing and other screen rendering technologies for many decades. But the web browser has not had this graphics feature until now in HTML5.
      Unlike its HTML5 cousin, <canvas>, the 'svg' ("Scalable Vector Graphics" or SVG) element is a fully-featured linear 2-D design feature that gives you complete control over images using simple XML code. It is fully compatible with HTML5 and markup, as a result. Like 'canvas', the browser is used in creating the image and visuals. But 'canvas' relies on a "one time" rasterized image call using the graphic libraries in the device's operating system. As such, it will not re-render the image as the browsers viewport changes. 'svg' elements, however, will redraw images, as they rely on the browser's rendering abilities to draw vector shapes in the viewport. This gives 'svg' elements a very fast and powerful edge over all other pixel-based, static, or rasterized image systems online. However, photographic imagery is not suitable for 'scalable vector images. So 'svg' is generally not used for high definition imagery or manipulating pixels in photos. Understand it has its place in solving some image-rendering issues, but not all.
      Below is a list of the main features of SVG elements, and things to remember:
      • SVG is XML - You may love or hate XML, but it is still a powerful way to structure data. In SVG's case, that is exactly what it does and why it works so well, as unlike JSON or other data document formats, XML has full support for nesting, tag attributes, and custom tag design.
      • The main 'svg' parent element is a "window" - The top-level 'svg' element controls available boundaries to your inside images, much like a "window". So, be sure to add dimensions to it. All its child elements and graphics will fit inside it, not outside it. By default, elements that attempt to overflow this parent box are "cut off", or rather designed to not overflow this boundary box defined by the 'svg' parent. But if you get used to the idea of 'svg' as a "boundary" or "visual "box" and add dimensions to it, it will start to make sense how your designs should fit inside it. You can of course assign widths and heights on this box using CSS styles. I encourage you to do so.
      • Use an external XML 'svg' file - Instead of typing SVG code directly in your page, some developers download an XML SVG file into an <object>, <embed>, <use>, or <image> tag. The advantage to this technique is you manage all your complex SVG code externally and in modules you can add as needed using a set of small XML files. It also allows you to use cross-browser support for non-supporting SVG browsers, with an alternative pixel-based image in the 'img' tag for browsers that do not support the SVG code (see my example above).
      • Cross-browser support for SVG - If you want to support older browsers that do not know SVG or HTML5, the best solution similar to the same one I supply for <video> elements in my article, "How to Create a Cross-Browser Video in HTML5". I have created a custom version of this in the code examples above. You must use an external SVG file for this to work properly. Basically, using the 'object', 'embed', and 'img' tags, browsers that fully support SVG will display the external SVG file downloaded into 'object'. Some browsers use the 'embed' element to run an SVG application in the browser. Finally, those browsers that need to download the SVG file as an image can use the 'img' tag. All legacy browsers would download a plain image you supply that is a screenshot of the SVG file. This would give you nearly 100% fallback support of your SVG image using alternative pixel-based images in older browsers.

      Addendum: Using Scalable Vector Graphics (SVG) is a "big" topic with many features - too many to list here! So, I will not go into all the various forms of code available here. The code example I provide above will help you get started. There are also large tutorials online. Just know that 'svg' elements and their children allow you a must faster and wider ability to display imagery online than ever before. Though a wide range of older browsers will fail to see your 'svg' elements, I still recommend its use, as long as you offer some alternative imagery for those browsers that will not support your images. The same approach applies to screen readers who will not understand your visual images. "title" attribute tooltips and alternative ARIA labeling will help. I have added a few of those to the example above.
    3. Browser Support for the 'svg' Element: With Scalable Vector Graphic elements now for the web, we have the promise of faster image rendering using simple XML code. The problem, however, is the same one we have always had with new technology for the Web: Lack of cross-browser support. The good news is most of the major HTML5 browsers have ramped up to support more and more of the recommended SVG features. This includes Internet Explorer 9-11, which usually has good support, though some features like filters, Gaussian blurs, etc. will not be supported. That means, most of your users online will see 'svg' graphics ok. But, many may see partial or no implementation of your carefully designed code. Because most older HTML5 browsers have good SVG support, I do recommend use of this element, as long as you provide a full set of fallback pixel-based images, alert messages, and text description alternatives to assist various user agents understand what your SVG designs were meant to convey.
    4. Free SVG Images and Software: There are free SVG libraries of images and even software online to help you build powerful SVG XML files and images for your website. I encourage you to use those!
    <table>,
    <thead>,
    <tbody>,
    <tfoot>,
    <tr>,
    <th>,
    <td>
    table

    Table

    also see <col> and <colgroup>

    Included in this section is <table> and all its child elements: <thead>, <tbody>, <tfoot>, <tr>, <th>, <td>


    Plain Table Example

    Below, I am showing an example of a basic table template you can use in all your projects. This one has all the traditional "grouping" table elements, including 'thead' at the top and 'tfoot' at the bottom. 'thead' and 'tfoot' not only support the 'tbody' data in the page, but are added at the top and bottom of printed pages in many browsers. The 'tbody' contains all of the main content cells. Included are two examples of spanning, a process which allows cells to stretch across multiple rows and columns using the "rowspan" and "colspan" attributes. The new ARIA attributes of "aria-colcount=4" and "aria-rowcount=6" tell screen readers the expected count of columns and rows in your table, if you know those values. I've also added the "scope" attribute in the header elements to help screen readers understand labels as they relate to groups of columns. I have added an optional "headers" attribute to cells to help screen readers associate them with headers using their "id" values. If you use "scope", this is not needed. But I have added it to show how they are used. I have also added the optional 'colgroup' and col' elements to create the blue color. These two elements are generally non-traditional elements used to control background or other design features in tables. But I do not recommend you use 'colgroup' or 'col' elements in tables at this time. Try and use CSS "class" attributes with styles instead to control the look-and-feel of your table's columns and rows.

    
    <table id="tableexample1" title="Table Example With Column Groups" 
        aria-label="Table Example 1" aria-colcount="4" aria-rowcount="6">
    <caption>Table Example 1 : Column Groups</caption>
    <colgroup>
        <col style="background-color:white;"/>
        <col span="2" style="background-color:lightblue;" />
    </colgroup>
    <thead>
        <tr>
            <th id="header1" scope="col">header 1</th>
            <th id="header2" scope="colgroup" colspan="2">header 2</th>
            <th id="header3" scope="col">header 4</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td headers="header1" >body 1</td>
            <td headers="header2">body 2</td>
            <td headers="header2">body 3</td>
            <td headers="header3">body 4</td>
        </tr>
        <tr>
            <td headers="header1">body 1</td>
            <td headers="header2" colspan="2">"colspan" applied</td>
            <td headers="header3">body 4</td>
        </tr>
        <tr>
            <td headers="header1" rowspan="2">"rowspan" applied</td>
            <td headers="header2">body 2</td>
            <td headers="header2">body 3</td>
            <td headers="header3">body 4</td>
        </tr>
        <tr>
            <td headers="header1">body 2</td>
            <td headers="header2">body 3</td>
            <td headers="header3">body 4</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td headers="header1">footer 1</td>
            <td headers="header2">footer 2</td>
            <td headers="header2">footer 3</td>
            <td headers="header3">footer 4</td>
        </tr>
    </tfoot>
    </table>
    
    Table Example 1 : Column Groups
    header 1 header 2 header 4
    body 1 body 2 body 3 body 4
    body 1 "colspan" applied body 4
    "rowspan" applied body 2 body 3 body 4
    body 2 body 3 body 4
    footer 1 footer 2 footer 3 footer 4

    Nested Table Example

    Below, I am showing an example of a table with an added nested table so you can see how that is done.

    
    <table id="tableexample2" title="Table Example Containing a Nested Table" 
        aria-label="Table Example 2"  aria-colcount="3" aria-rowcount="3">
        <caption>Table Example 2 : Nested Tables</caption>
        <thead>
            <tr>
                <th scope="col">header 1</th>
                <th scope="col">header 2</th>
                <th scope="col">header 3</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>body 1</td>
                <td>
                    body 2
                    <table id="tablenested1">
                        <tr>
                            <td>nested 1</td>
                            <td>nested 2</td>
                            <td>nested 3</td>
                        </tr>
                    </table>
                </td>
                <td>body 3</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td>footer 1</td>
                <td>footer 2</td>
                <td>footer 3</td>
            </tr>
        </tfoot>
    </table>
    
    Table Example 2 : Nested Tables
    header 1 header 2 header 3
    body 1 body 2
    nested 1 nested 2 nested 3
    body 3
    footer 1 footer 2 footer 3

    Multi-Header Table Example

    This example shows how you can have "headers" ('th') in columns, as well as rows. This example contains both types to show you how you can create tables with horizontal and vertical titles. Notice I changed the "scope" in the 'tbody' header cells to "row" to tell screen readers these left-hand headers represent the row of cells only. The 'tfoot' group was removed at the bottom of the table, as it is not needed.

    
    <table id="tableexample3" title="Table Example Containing Multiple Headers" 
        aria-label="Table Example 3" aria-colcount="4" aria-rowcount="4">
        <caption>Table Example 3 : Multiple Headers</caption>
        <thead>
            <tr>
                <th scope="col"> </th>
                <th scope="col">top header 1</th>
                <th scope="col">top header 2</th>
                <th scope="col">top header 3</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th scope="row">left header 1</th>
                <td>cell 1</td>
                <td>cell 2</td>
                <td>cell 3</td>
            </tr>
            <tr>
                <th scope="row">left header 2</th>
                <td>cell 1</td>
                <td>cell 2</td>
                <td>cell 3</td>
            </tr>
            <tr>
                <th scope="row">left header 2</th>
                <td>cell 1</td>
                <td>cell 2</td>
                <td>cell 3</td>
            </tr>
        </tbody>
    </table>
    
    Table Example 3 : Multiple Headers
      top header 1 top header 2 top header 3
    left header 1 cell 1 cell 2 cell 3
    left header 2 cell 1 cell 2 cell 3
    left header 2 cell 1 cell 2 cell 3
    My Recommendations:
    1. The 'table' element represents a set of tabular data defined by rows and columns. The 'table' element is the top container or box. It holds numerous child HTML elements that define the table structure (see below). The origin of the 'table' element goes back to the birth of HTML in the 1990's and has been a stable element since its creation. It is still part of the HTML recommendations and has changed very little in 20+ years. The table remains a reliable element for displaying tabular grids of data and information in web pages today.
    2. The History of the 'table' Element: Little has changed in the design and layout of the table. The first proposal for HTML tables began in 1993 and continued until its standardized HTML 3.2 integration in 1997. In later years, the newer HTML4 recommendations (1998) added additional features, like interior elements for 'thead', 'tbody', and 'tfoot' to further define sections of the table grid, semantically.
      Most web developers have used the 'table' element in fulfilling its original purpose of displaying grids of tabular data. But some developers starting in 2001, out of frustration with trying to build "flexible" layout designs in stubborn Internet Explorer 5 and 6, starting using tables to build page layouts and structures in HTML. At first, it seemed that tables in HTML provided the perfect flexible architecture for laying out flexible grids. These worked well across all browsers instantly and solved the issues around cross-browser flexible layouts. The problem was the table was not meant to do web page layouts. This defied the true purpose of the 'table' element. And so began what I call the "Table Wars". In 2000, this battle raged in parallel with the browser wars between Internet Explorer and Netscape, and between those that loved and hated JavaScript. Back then we used 'div' quite successfully for layout with elaborate negative margins and positioning tricks to build these flexible layouts in troublesome browsers like IE6. After some work, these worked great! We never ever needed to even consider tables. But we suffered from rushed developers back then that refused to take the time to learn these CSS tricks or IE's "quirksmode" issues, which we had elegantly resolved for them.
      By 2001, many professional web developers began noticing this trend among some using tables for layouts and quickly caught the problem and explained that semantically using 'table' elements was confusing to both developers and search engines. They later showed that such use was forbidden. Web layout did not represent tabular data. This led to a brief battle over HTML structure vs semantics vs design in web logs online, which birthed the "Web Standards" movement in 2003. This universal concept for acceptable HTML use in web pages helped the W3C to refine the semantic purpose and use of all HTML tags and pushed for more standardization of each element's use. Most young developers today think this discussion happened after 2010, but Web Standards started a decade before and was resolved many years prior to even the first HTML5-supporting browsers. The first Mozilla browsers in 2001 were already very much compliant with HTML4.1 and the correct use of tables was already recommended. Today's discussion about tables and standards in 2022 is thus just a second "reworking" of what we already figured out in 2003. The people learning today about tables represents a generation not bothering to learn from the past, and so reinventing the wheel by re-investigating the debate 20 years later. Today in 2022, it is not "illegal" to use the 'table' element to layout a grid for your web page. It is just not recommended and is poor HTML page design. Besides, HTML5 finally has its own layout elements now.
      In summary, the history of the 'table' element ends with the fact almost no one now uses tables for layouts, though some on "medium.com" still pretend its a new issue. There is nothing new online when it comes to HTML and tables. Sadly, convincing people that tables used for layouts was bad took HTML5 and CSS3 to fix it by adding new elements and styles. But why did it take 20+ years to convince developers to stop using tables in the first place?
    3. The 'table' Child Elements: Rather than list each of these child elements in their own section in this HTML5 tutorial, I felt it was much easier to combine them here under 'table' and show how each are used (see my code examples above). Below is a comprehensive list of all the possible child elements of 'table' in HTML5 and my recommendations for how to use them. Included are any special attributes needed, or ones now deprecated and not recommended. Always review my code samples above for full examples of coding best practices when building tables in HTML:

      Table Elements

      • <table> - The 'table' element is the root element for all the elements below and creates the "box" or grid that holds rows and columns of data. Note that you can nest tables inside each other as well as grids for more complex data structures. Below are the recommended attributes for 'table'.

        Recommended Attributes

        • 'id' - Always give tables a unique 'id' value so scripts can quickly identify it in the DOM for script manipulation.
        • 'title' - Always give tables tooltips so on rollover there is some basic description of the table in addition to its caption or label.
        • ARIA - In general, avoid "role=table" here as tables are self-describing, have the 'caption' element for descriptions, support 'title' attributes, and the data represents most of the meaning, anyway. You can add "aria-label" to add a simpler name to your table. Two attributes you can add, if you know these values, are "aria-colcount" and "aria-rowcount", which just tells screen readers the total counts of data expected.
        • 'class' (CSS) - See my sample CSS below to get started using a clean, cross-browser design for all your tables.
        • 'summary', 'align', 'cellspacing', 'cellpadding', 'border', 'bgcolor'. 'background', 'bordercolor', 'attributes', 'height', 'width', 'rules', 'nowrap', 'frame' - DO NOT USE THESE! These attributes on 'table' elements were used years ago to control the design of tables but are deprecated in HTML5, so avoid them.

      • <thead> - The 'thead' element is one of the newer semantic wrappers and defines the section of rows and columns that define a "header" for all body and footer rows and columns. This element had poor support in early versions of Internet Explorer and Netscape (pre-2000) so was avoided. Later versions fully supported them. Typically, headers in this group represent bold text titles in a top horizontal row. But these can be moved to the left or right in a table to represent the first or last column in multiple rows. Note: If you leave these "wrapper" elements out of tables most browsers will insert them anyway around your rows and columns in the Document Object Model. These grouped elements usually have no design or formatting by default. Note that this attribute has "display:table-header-group" assigned. When printing a large table that spans multiple pages, this element can enable the table header and footer to be printed at the top and bottom of each page. By default, many modern browsers will print the 'thead' and 'tfoot' content at the top and bottom of every printed page.
      • <tbody> - The 'tbody' element is one of the newer semantic wrappers and defines the section of rows and columns that define the main "body" of data. This element had poor support in early versions of Internet Explorer and Netscape (pre-2000) so was avoided. Later versions fully supported them. Note: If you leave these "wrapper" elements out of tables most browsers will insert them anyway around your rows and columns in the Document Object Model. These grouped elements usually have no design or formatting by default. Note that this attribute has "display:table-body-group" assigned. Browsers or CSS can use this element to enable scrolling of the table body independently of the header and footer when you have large sets of table data.
      • <tfoot> - The 'tfoot' element is one of the newer semantic wrappers and defines the section of rows and columns that define the lower "footer" area of the table. This element had poor support in early versions of Internet Explorer and Netscape (pre-2000) so was avoided. Later versions fully supported them. Footer supplemental information that supports the main data in 'tbody' is usually added here. Note: If you leave these "wrapper" elements out of tables most browsers will insert them anyway around your rows and columns in the Document Object Model. These grouped elements usually have no design or formatting by default. Note that this attribute has "display:table-footer-group" assigned. When printing a large table that spans multiple pages, this element can enable the table header and footer to be printed at the top and bottom of each page. By default, many modern browsers will print the 'thead' and 'tfoot' content at the top and bottom of every printed page.
      • <tr> - This is the original HTML 3.2 table row element and holds multiple columns inside it. It can be contained inside any of the three group table elements above. Table rows usually have no design, padding, or formatting by default. But see my CSS code below.

        Recommended Attributes

        • ARIA - In general, avoid the ARIA "role" and "aria-label" attributes here as this element is self-describing. If some rows appear or disappear from your table due to settings, and you want to help screen readers identify the index of a row from the total, you can add "aria-rowindex={row number}".
        • 'class' (CSS) - See my sample CSS below to get started using a clean, cross-browser design for all your tables.
        • 'align', 'valign', 'bgcolor' - DO NOT USE THESE! These attributes on 'table' elements were used years ago to control the design of tables but are deprecated in HTML5, so avoid them.

      • <th> - This is the original HTML 3.2 table header element and holds a single header or title for a single column inside it. This can include text, images, lists, media, grids, tables, or other items. It can be contained inside any of the three group table elements above. Text is usually bold and centered by default to highlight the "column title" aspects of headers.

        Recommended Attributes

        • 'id' - You are only required to assign a unique 'id' attribute to an 'hd' element if you plan to use the "headers" attribute in 'td' cells. The "headers" attribute would then point to your 'id' value.
        • 'colspan' - This attribute allows you to set a single table cell to span multiple columns in a table. The number represents the number of columns the cell should fill.
        • 'rowspan' - This attribute allows you to set a single table cell to span multiple rows in a table. The number represents the number of rows the cell should fill.
        • 'scope' - The scope attribute specifies whether a header cell is a header for a column, a row, a group of columns, or a group of rows. Note: The scope attribute has no visual effect in ordinary web browsers, and is mainly used by screen readers.
        • ARIA - In general, avoid the ARIA "role" and "aria-label" attributes here as this element is self-describing. If some columns appear or disappear from your table due to settings, and you want to help screen readers identify the index of a column from the total, you can add "aria-colindex={column number}".
        • 'class' (CSS) - See my sample CSS below to get started using a clean, cross-browser design for all your tables.
        • 'align', 'valign', 'bgcolor' - DO NOT USE THESE! These attributes on 'table' elements were used years ago to control the design of tables but are deprecated in HTML5, so avoid them.

      • <td> - This is the original HTML 3.2 table data or column element and holds a single piece of data for a single column. This can include text, images, lists, media, grids, tables, or other items. It is usually contained inside 'tbody' and 'tfoot' group elements, is left aligned, vertically aligned to the middle, not bold, and not padded by default in tables.

        Recommended Attributes

        • 'colspan' - This attribute allows you to set a single table cell to span multiple columns in a table. The number represents the number of columns the cell should fill.
        • 'rowspan' - This attribute allows you to set a single table cell to span multiple rows in a table. The number represents the number of rows the cell should fill.
        • 'headers' - The headers attribute specifies which 'th' element a specific 'td' element is associated with using the 'id' value of the 'th' tag in the "headers" value. This is a screen reader technology and not needed if you use the "scope" attribute above. Most screen readers will identify what cells fall under which header elements quite easily, anyway. So, I do not recommend this element.
        • ARIA - In general, avoid the ARIA "role" and "aria-label" attributes here as this element is self-describing. If some columns appear or disappear from your table due to settings, and you want to help screen readers identify the index of a column from the total, you can add "aria-colindex={column number}".
        • 'class' (CSS) - See my sample CSS below to get started using a clean, cross-browser design for all your tables.
        • 'align', 'valign', 'bgcolor' - DO NOT USE THESE! These attributes on 'table' elements were used years ago to control the design of tables but are deprecated in HTML5, so avoid them.

      Additional Table Elements

      • <caption> - Captions sit on top of a table box and are usually centered. It provides a text title or description of your table and replaces the outdated "summary" attribute on the 'table' element.

      Table Elements I Would Avoid

      • <colgroup> - This element is shown in the example above but is not recommended as you can easily replace this element with CSS classes and styles.
      • <col> - This element is shown in the example above but not recommended as you can easily replace this element with CSS classes and styles.
    4. Table Cells and Weirdness in Formatting - In general, it's best that you ALWAYS remove all spacing inside 'th' and 'td' cells and align table cells next to content immediately after each tag, stack each table header or cell on a single line, and add content without any spaces, carriage returns, or line breaks between content as so: <td>My Text or Image</td>. Why do this tight wrapping of elements around table cell text? In the old days, many older browsers like Netscape 4 Series would create artifical padding and line breaks in tables if you had spaces, carriage returns, or added images that were not on the same line as your table cell HTML tags. So, always line up all your table tags around text and images and you will never see this spacing!
    5. Designing Tables with CSS - Because most default table designs in modern browsers are terrible, I have created a "reset" table element style sheet set below you can use to give your tables a solid starting design which you can easily customize:
      
      body table {
      	display: table;
      	margin: 0;
      	padding: 0;
      	border: 1px solid #000;
      	border-spacing: 0;
      	border-collapse: collapse;
      	vertical-align: top;
      }
      
      body thead {
      	display: table-header-group;
      	margin: 0;
      	padding: 0;
      	border: none;
      	border-spacing: 0;
      	border-collapse: collapse;
      }
      
      body tbody {
      	display: table-row-group;
      	margin: 0;
      	padding: 0;
      	border: none;
      	border-spacing: 0;
      	border-collapse: collapse;
      }
      
      body tfoot {
      	display: table-footer-group;
      	margin: 0;
      	padding: 0;
      	border: none;
      	border-spacing: 0;
      	border-collapse: collapse;
      }
      
      body tr {
      	display: table-row;
      	margin: 0;
      	padding: 0;
      	border: none;
      	border-spacing: 0;
      	border-collapse: collapse;
      }
      
      body th {
      	display: table-cell;
      	margin: 0;
      	padding: .5em;
      	padding: .5rem;
      	border: 1px solid #000;
      	border-spacing: 0;
      	border-collapse: collapse;
      	text-align: center;
      	font-weight: bold;
      	color: inherit;
      }
      
      body td {
      	display: table-cell;
      	margin: 0;
      	padding: .5em;
      	padding: .5rem;
      	border: 1px solid #000;
      	border-spacing: 0;
      	border-collapse: collapse;
      	color: inherit;
      }
      
    <template> template

    Template

    This 'template' element and its content below would be hidden by most HTML-supporting browsers until revealed by some type of JavaScript code.

    <template id="template1">
      <p>My hidden Template Text.</p>
    </template>
    My Recommendations:
    1. The 'template' element is new in HTML5 and reserves a hidden piece of content until revealed by a script. Most modern HTML5 browsers that support 'template' should "hide" the element and not parse it while loading the rest of the page into the DOM. You can then use JavaScript to show the 'template' and its content. But, I do not recommend use of this element due to its scripting dependency.
    2. If you choose to use 'template', it should have a unique 'id' and value so that JavaScript can locate it in the DOM faster and reveal it. Scripts will typically process the contents by parsing its contents then showing it, or cloning and appending it to another HTML node.
    3. Do Not Use the 'template' Element: Keep in mind, most older, non-HTML5 supporting browsers will render such a hidden element as this visible by default, destroying its main feature. Scripting as a dependency with this element is the next problem. Those which do support 'template' but have JavaScript disabled, some scripting features turned off, or no support for scripting at all might never see its contents! Because this element depends upon JavaScript to function, yet has no support in many older non-HTML5 browsers (like Internet Explorer 1-11), I do not recommend its use. There are simply too many ways it can appear or not appear.
    4. Alternatives to the 'template' Element: The 'template' element is really not needed and redundant, as there are numerous ways to now show and hide content from browsers. These new ways also allow you to use scripted and non-scripted techniques, including several CSS techniques, a "hidden" input element type, and even the new HTML5 "hidden" attribute which you can use on any element now. See my article below called "How to Hide HTML5 Elements and Content using CSS" for better options in hiding elements using plain CSS. These techniques have worked reliably in all browsers, old and new, the past 20 years
    <textarea> textarea

    Textarea

    see <form> for more details using <textarea> in forms

    Shown below is a complete code sample of the <textarea> element, which you can copy-and-paste into your web project. It has a rich set of attributes I recommend you use for each scenario. The visual design for this form is shown below the code. With these examples you have a complete set of code you can use in your web forms.


    <form id="formtextarea" name="formtextarea" method="post" action="#" title="Textarea Example" aria-label="Textarea Example" autocomplete="off" autocapitalize="off" spellcheck="false">
    <fieldset id="formtextarea_fieldset1" name="formtextarea_fieldset1" form="formtextarea" style="background-color:#fff;">
    <legend style="background-color:#aaa;color:#fff;">Textarea</legend>
    <div>
    <label for="formtextarea_textarea1" title="Textarea">Textarea Label:</label><br />
    <textarea id="formtextarea_textarea1" name="formtextarea_textarea1" title="Textarea" aria-label="Textarea" tabindex="0" contenteditable="true" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="true" maxlength="200">Enter your text here...</textarea>
    </div>
    </fieldset>
    </form>
    Textarea

    A textarea form field is also called a "textbox" or "text" by some. The Textarea allows users to submit large volumes of text in a form. Notice I have added the "spellcheck" attribute, which means in most HTML5 browsers, any misspelled word in the textarea box will have a "wavy" line under it. This indicates a misspelled word that needs to be corrected. Right-click the word to see a list of correct options provided by the browser.


    My Recommendations:
    1. The 'textarea' element defines a type of form field control used for submitting text. Unlike the 'input' text box, 'textarea' allows larger volumes of text to be submitted. The 'textarea' element has been around since the 1990's and in the earliest of HTML recommendations by the W3C. Like most form controls, the 'textarea' element is considered a "replaced" element, as its design and actions are controlled by the browser and operating system. It has changed very little in the past 20 years, so is a bedrock form field element supported in all browsers and versions. As such, it can be safely used in all your web forms.
    2. Always Wrap a <form>: Element Around Your 'textarea' Elements: When you wrap a form tag around a 'textarea' control, it tells the browser your 'textarea' is associated with a specific form "id" value and will only submit the field elements associated with that control. If you have multiple textareas and form fields to submit to a web page, it is crucial you know what select belongs with which form. You can still place the element outside a form if you give it a 'form={yourformid}' attribute with a value associated with a specific form "id". In that case, it will be submitted with all the fields inside that specific form. However, I do not recommend you move form controls outside of a form, as some older browsers may fail to send the right data when submitted.
    3. Always Use the <label> Element with Your 'textarea' Element: Try and use the 'label' element before your 'textarea' tag, then add the "for" attribute with a value that matches the textarea's 'id' value to associate the two together. This links the label to the form field and allows the browser, search engines, and screen readers to connect the two, adding semantic meaning. Often, the browsers will float the label text above the textarea control. But I have added a break after it as textarea boxes tend to float right as an inline-block element (see my code samples above for examples of labels and textarea controls). "clicking" on the label's text auto-selects the textarea and places your cursor in its box. Also add a 'title' attribute with description of your textarea to the your label.
    4. Collecting Form Field Data Using Textarea: The process of using 'textarea' elements and other form fields to collect and process data is way beyond the scope of this tutorial. The single most important aspect of good form field design (beyond HTML) is validation. That is discussed in-depth in the 'form' element section. The main thing to understand about forms and form fields is that data collection is the single most complicated aspect of web design, simply because it requires so many levels of exchange, validation, processing, analysis, and storage. Data collection and processing of form field element data is way beyond the scope of this tutorial. Just know, I have built dozens and dozens of large data collection applications in my life-time, and I can tell you good data collection always begins with solid HTML design, not fancy JavaScript, not fast REST API's, not secure server processes, not relational databases, and not fancy business applications. HTML is always King simply because HTML is the gateway between your users, your server, and your database.
    5. Always Use the 'id' and 'name' Attributes: Always use 'id' and a matching 'name' attribute with the same value when possible on all form field elements. The 'id' affects client-side scripts that must access a unique 'id' on the form field in order to access the control and its data. But 'id' is never sent to the server, unlike 'name'. As mentioned, I like to always match the 'id' value to the 'name' attribute, as I do in all my other form fields. Why? The 'name' attribute is what is always sent to the server, along with the input's "value" attribute. Assigning both 'id' and 'name' to the same value helps your server-side processes identify which form field you are processing and align the field's 'name' on the server or in the HTML with any client-side scripted validation or pre-processing that uses the 'id' value. If the two attribute values match, it's very easy to locate and sort client-side from server-side processes.
    6. Always Assign a 'tabindex' Attribute Number: Almost all browsers, old and new, add form field elements to a "tabindex" list. This means that all interactive elements are available for tabbing through by a user in the browser as they fill out larger forms. You really do not have to add this extra attribute to your form field elements or worry about this feature as it's built into all modern browsers. Most of the old ones, as well new ones will logically add all your form fields and buttons to a tab list. Nearly all form fields, links, and buttons are added to the tabindex, by default. However, you can manipulate this to change the tab order of your form fields in the index, remove a form field control from the tabindex, or add one that was missed by using the "tabindex" attribute. I always add the "tabindex=0" attribute to all my form fields to enforce addition of each control to browser's tabindex, which also lets the browser reorder everything, naturally. I add "tabindex=-1" to remove fields from the tabindex I do not want included. "hidden" types fields are never added to the tab index anyway, but I add the "-1" value to all other interactive form controls I don't want users stumbling across (including disabled fields, read-only fields, etc.). You can also granularly control tabindex by setting each of your controls to a specific number in an order, like "tabindex=2", and set the specific order you want your users to use. You can also set "autofocus=autofocus" to force focus immediately to a specific textarea field after the page renders. This overrides the natural tabindex, however. You don't have to override these features in browsers unless you want to change tab indexing. "tabindex" and "autofocus" can help enrich your forms and add more control over how you intend users to use them. See my code samples above which use "tabindex", and read my section in this page called "TabIndex and Autofocus in HTML" for more details on "tabindex".
    7. Title, Required, Disabled, Read-only, and Hidden Attributes - Always add a "title" tooltip attribute as it provides a nice rollover description of your form field control. For any form field that must be filled out or selected, you must use the "required=required" attribute. Required text means the form field must be filled out with some data by the user or an error will be generated and the submission will fail. This attribute can be overridden by add the "novalidate=novalidate" on the form or form field. Be sure to set any 'select element' you do not want sent to the server as "disabled=disabled" in your inputs. Data you do want sent to the server, but not changed by the user, should be set using the "readonly=readonly" attribute. Also set "tabindex=-1" on these "disabled" and "readonly" controls so the user does not tab through them. In modern HTML5 browsers, a form field element with the added "hidden" attribute will not be seen by the viewer but remain an active form field. But, if the browser does not supports HTML5 your form control will not be hidden! The new "hidden" attribute is redundant, however, as there is a "hidden" 'input' type you can use instead which is always hidden and always submitted. But, there may be rare cases where you just need to hide it. In those situations, I recommend you use CSS "visibility" instead to hide things, as it will work more reliably in older browsers. If you use "display:none" to hide controls, remember the input will not be seen AND will not be sent to the server on submission, unlike the CSS "visibility" property or the "hidden" element attribute. See my section called "How to Hide HTML5 Elements and Content using CSS" for more information on hiding elements in HTML correctly. Note: Always use the "XML-friendly" version of these attributes so your tags are always cross-compatible with both XHTML and XML. Do not use "readonly", but type "readonly=readonly".
    8. Optional 'novalidate': I discuss this attribute in more detail under the 'form' section (see <form>), as the form really controls this setting over all its child fields. But often you will have a 'form' with default settings and want to override them in each form field. A difficult one to manage is "novalidate". In general, the code samples above showcase my "best practices" and recommendations for how each field should use this attributes.
      The good news is "novalidate" is removed by default, meaning validation is enabled for the textarea control, which in my opinion is a good thing as HTML5 browsers now come with a new array of validation checks and features. Again, see my 'form' section for more details on how these work and some additional tricks to force them to do what you expect. But if you want to turn off validation on a field and override the 'form' element's default value, you can add the "novalidate=novalidate" attribute to your element.
    9. Do Not Use "accesskey": I do not recommend use of this attribute. Long ago, it was designed to allow keyboard presses to access form fields. But it is not reliable and requires various additional combinations of keys to work that are specific per device or just not accessible. It also conflicts with operating system shortcuts and could trigger other features on a laptop or phone by accident. Also avoid legacy attributes, like 'wrap', etc.
    10. Do Not Use New "inputmode": This new attribute is gaining in popularity, but still poorly supported in browsers. "inputmode" is now used as a "hint" to tell browsers the type of data to expect, like "email", "search", "url", etc. Because its not supported in IE, Safari, or Firefox browsers prior to version 24, it is not helpful or reliable.
    11. The Optional "data-" Attribute: As mentioned below in my "Best Practices" article called "The New 'data-' HTML5 Attribute", you can now safely use the new "data-" attribute in any HTML form element to store extra data values. Know that this is an extra attribute, and that "data-" values are not submitted to the web server anyway, so pretty useless. Its mainly an add-on for JavaScripted frameworks on the client-side.
    12. ARIA Attributes: The 'textarea' element is another "self-describing" structure recognized by most modern screen readers. Most screen readers can read each textarea box quite well, and understand what each one does. So, they do not need the ARIA "role" attribute. But they do need help knowing what type of data is being used so they can identify its semantic meaning. For that reason, it is recommended you add an ARIA "aria-label={Name of Item}" on each 'textarea' element to give screen readers more details about your 'textarea' does and its meaning within the form. You do not need the ARIA "live" attributes telling screen readers the "state" of your controls as they change unless you are manipulating the DOM using JavaScript. Use my code samples above to see "best practice" uses of ARIA attributes when designing textarea controls that assist screen readers.
    13. Form Field Validation: 'textarea' does NOT support "pattern matching" like 'input' fields. So validation must be limited to removing any dangerous injected scripts. Try spellcheck attribute to improve user spelling, and maxlength to limit text entries before entering textarea values into the database. As mentioned above, and in the <form> section, it is not enough to drop form fields like 'textarea' onto web pages and then hope the data coming into the server works. I have found too many cases where poor data processing ends up destroying a website! Even with fancy JavaScript, you cannot ignore the HTML design and server processing. That also includes heavy database scrubbing and processing. You need to always validate your form fields, no matter what the type, in ALL layers of your application. Do it, not just to improve data collection, but for security reasons as well! Data validation is not part of the scope of this tutorial but is native to the specific language, framework, network, and database architecture you are using. Don't rely on a single product like jQuery (JavaScript), either. Rely on good server-side validation, always, but good HTML design, too. It will help the user get the data right on their end without waiting on elaborate scripts to warn them later. Getting the HTML design right helps them navigate your forms faster, and makes it much easier for them to enter good data. Good HTML means it's one less layer you have to wrestle with. And it frees up control of data entry to your users, not your script libraries or your server.
    14. Trouble Styling Replaced Controls with CSS: "Replaced" elements like 'select', 'textarea', and others are notoriously difficult to style using CSS and have been for years. The reason is, they are not part of HTML but controls generated and dropped into the viewport by the browser. This is why these controls look so different between Macs, Windows PC's, and mobile phones. The browsers on these devices call the OS which helps determine their designs. Without getting into all the "hacks" and fixes out there to try and override these OS controls, I highly recommend you use plain HTML then stay with plain CSS code to style what you can and avoid all JavaScript, Modernizr, Polyfills, or "scripted hacks" to try and change their native designs. There are some clever CSS styles you can apply that alter the look-and-feel of these controls enough using just a few lines of CSS text that they are "presentable" and look close to the same across old and new browsers alike. There are also "prefixed" CSS rules (browser-specific styles like "-moz", etc.) that also can safely be used and which avoid JavaScript completely. If you start using scripts that hide or replace the HTML with a new form of control, you not only add complexity and unnecessary "hacks" that will likely cause form submission issues, but often it will fail completely in certain older browsers. In addition, your HTML will now be too complex for others to customize and likely erased when the next developer comes behind you.

      Below, I have added a very clean, widely supported piece of CSS code you can use to give your 'textarea' element a nice clean style that looks the same across many browsers and versions. This is the basic style I use for the 'textarea' example above:

      
      textarea,
      textarea:visited,
      textarea:hover,
      textarea:focus,
      textarea:active {
      	display: inline-block;
      	width: auto;
      	height: auto;
      	min-width: 20em;
      	min-width: 20rem;
      	max-width: 100%;
      	min-height: 10em;
      	min-height: 10rem;
      	padding: .2em;
      	padding: .2rem;
      	margin: 0;
      	-webkit-appearance: textarea;
      	-moz-appearance: textfield-multiline;
      	cursor: text;
      	overflow: auto;
      	resize: both;
      	background-color: #eee;
      	word-wrap: normal;
      	border: 2px solid #bbb;
      	border-radius: .2em;
      	border-radius: .2rem;
          line-height: normal;
      }
      
      textarea:visited,
      textarea:hover,
      textarea:focus,
      textarea:active {
      	background: #f9f9ff;
      	border: 2px solid #999;
      }
      
      textarea:focus {
      	background: #fff;
      	border: 2px solid #999;
      }
      
      
    15. See the <form> element section for more details about this element within a form.
    <tt> teletype text

    Teletype Text


    <tt>This is teletype text. If your browser supports it, it should be in a monospace font.</tt>
    This is teletype text. If your browser supports it, it should be in a monospace font.
    My Recommendations:
    1. The 'tt' element represents inline teletype text as would appear in a monospace font in fixed width displays and devices. This element is either deprecated in HTML5, not supported, or not recommended. Any element that is used solely for style is generally not useful in HTML. If you need monospace text use the <span> inline element with a CSS "class" attribute added and the following style declaration: "font-family:monospace". So, avoid use of the 'tt' element.
    <time> time

    Time

    <p>It is <time datetime="2021-06-26T22:00:00Z" title="2021-06-26T22:00:00Z">5 o'clock</time> here in my state. But what time is it in your state? My 'time' element might help!</p>

    It is here in my state. But what time is it in your state? My 'time' element might help!

    My Recommendations:
    1. The 'time' element is a new HTML5 element. It represents an inline piece of text representing time, date, date-time, or duration. It mainly assists search engines, screen readers, and other user agents in accurately interpreting page text as more complete, formal units of date and time. It is common to include the 'time' element with the local "datetime" attribute translated into Coordinated Universal Time (UTC).
    2. How Can The 'time' Element Help You? The local clock, time format, or calendar available on one computer, browser, or server can often fail to relate to time units posted elsewhere online or around the world. The 'time' attribute helps software, like search engines, ingest your text and extract out valuable date-time information. To do that, it needs your help. If you post time units online it is good practice to help others translate your time, date, or "time zone" information into a format others can relate to. Add this element where you would like the search engines, screen readers, or even some browsers to interpret your text as a formal date or unit of time they can use.
      Because there are so many different clocks and date time formats, its often important to frame them as some calendar date or time format that's relative to some standard universal unit of time, like UTC. The 'time' element is there to help interpret text in a "better" date-time format. To do this, its important to use the "datetime" attribute to display an "alternative" but formal unit of time in a format thats a supported "date-time standard" others know. So use this attribute for that dual purpose: To show your date or time text again in a more accurate format, but also in a standard unit that is know, like Coordinated Universal Time or "UTC".
      Example: It might be "5 o'clock" where you are, but what is that in UTC? Here, you might assume "PM" in Central Standard Time. But others online would have no idea what you intended. A good way to help them know what time you meant would be to translate your local time into universal time using "Coordinated Universal Time" (UTC). This time set is known around the world. Using UTC also helps search engine databases who can now easily index your time then translate it into multiple other "offsets" or time zones for others. To translate your time into UTC you would need to express your time in a new attribute in the 'time' element called "datetime". Add your translated date-time value there to help search engines or parsers see your time as UTC. An example would be expressing your local time shown in the example above as: "datetime=22:00:00Z" in UTC (this is assuming a standard time format, not daylight savings time). So, this value of "22:00:00Z" is what you might put inside the "datetime" attribute to give these search engines or the browser a frame of reference for your actual time relative to the rest of the world. Or, maybe you just need to clean up the "local" time format by expressing it as "datetime=5 PM CDT". Or, maybe you simply need show a more complete UTC format by also adding a full date to your time: "2021-06-26T22:00:00Z". Wow, that is really detailed now! Use "datetime" for those reasons. I highly recommend you read up on "UTC" and the global standard for time offsets for UTC, time in various web formats, and then "time zones". I also recommend you start translating all times and dates to the UTC format translation, which will then open up all your dates and time displays to an easily parsed UTC time both JavaScript and the web server can easily store and translate into other dates and times, using the UTC version of your local date-time values. Your web page will then have some longevity as search engines will be able to share your dated web page accurately for many years to come.
    3. Styling the 'time' element: By default, the 'time' element does not come with any styles. It also has no rollover or other default UA style in most browsers. It mainly serves parses and search engines. But I like to allow the 'time' element to have some visual effects. So above I have added the 'title' attribute with the UTC time in the rollover. In my style sheets, I've also added a dotted underline to the 'time' element ("text-decoration: underline dotted #000") so a user knows it is interactive.
    4. No Internet Explorer browser (IE 1-11) supports the 'time' element, nor any browser that does not support HTML5. But, because it adds value and is a non-obtrusive inline element when it fails, 'time' is safe to use.
    <title> title

    Title

    see <html>
    My Recommendations:
    1. The 'title' element defines the title of a web page as found in the head area of a web page. See the <html> element for a full description.
    <track> track, video tracks

    Track

    Avoid the 'track' element' in video in HTML5 until wider support for common track file "types" are more widely supported. But, an example of how to use the 'track' element in 'video' elements is shown below.


      <video id="trackvideo1" controls="controls" preload="metadata" title="My Video with Tracking">
        <source src="video1.mov" type="video/quicktime" />
        <source src="video1.ogv" type="video/ogg" />
        <track default="default" kind="subtitles" srclang="en" src="video/track.vtt" />
        <p><strong>Sorry, this video file will not play. Your browser does not support the video element or the file formats available.</strong></p>
      </video>
    My Recommendations:
    1. The 'track' element is a new HTML5 element that represents a set of timed text tracks added as captions, subtitles, chapters, or descriptions to movies or multimedia. This element is a child of the <video> and <audio> elements, and allows you to load caption timed text using a secondary "track" text file and display that text within the parent media file. This element is supported in HTML5, but because of the industry-wide failure to agree to a standard (to match common media types with tracking file types in web display), most text tracks technology will fail to achieve cross-browser minimum support, so I do not recommend its use today.
    2. Problems With Playing Web Video Persist: In past years, I have built and sold my own video, audio, and multimedia website software. So I know what I am talking about when it comes to the inherent issues in delivering successful cross-browser multimedia on the Web. I cover some of that history of movies and video on the Web and my experiences in my <video> section. But here is a bit more.
      Prior to 2010, there were only a handful of video formats and players for web browsers to use when displaying movies online. The main ones supported were Windows Media Player for ".wmv" files, Apple's Quicktime player for ".mov" files, Adobe Flash for ".flv" files, and a handful of others that included open source video, like .mpeg1, .mpeg2, .avi, etc. Today there are dozens. After 2007, adoption of the Adobe Flash Player was so widespread that most video could be encoded into Flash and be delivered widely across millions of websites and multiple browsers (and their many versions) with minimal issues. The Flash player was universal back then. But after 2010 and the demise of Flash on mobile, this solution has faded. We are now back to an even worse situation in HTML5, despite the "promise" of universal browser support of video online.
      Most of the video formats once supported years ago are diminishing and being replaced with a "potpourri" mess of partially supported codices that each manage player support, web browser support, and track file support differently. Add to this problem, the "specialized" 3rd party video players and products like YouTube, that require you to use their streaming architecture if you want to play videos. You must upload files into their system which use an amalgam of JavaScript, encoding, and other techniques to control video playback and encoding online. To use their product you also must embed video in a very proprietary way into your web site. It is not the "open" video system that HTML5 promised us. If you want a good video playback solutions in your website, you are stuck with 3rd party vendors, yet again.
      Without confusing you too much more, the problem with delivering video or any multimedia object online is the fact you are stuck with too many video products that each use their own proprietary system. This translates into video that often will not play in certain browsers, has no or partial support in older browsers, and is very inconsistent in how they support HTML5's new video player. Remember, when a video is created, it comes with its own unique "codec" or software that must be used to encode and decode it for Web display. Add the fact that each type requires a special "player", plugin, or software tool to play it. Each browser also comes with support for only specific "sub-versions" of each encoded type (older or newer versions of the MPEG-4 codec, operating system versions, etc.). And some players support either one type or multiples of each. But the Operating Systems also have limitations. For example, playing Apple ".mov" files on Windows, or the opposite, Windows Media Video files on Apple Mac's, was problematic in the past, regardless of which browser was used. Web "players", or third party software you downloaded to the browser solved this issue 2 decades ago. But the situation is far worse today, simply because HTML5 is trying to force all video to work inside the new 'video' element which must support as many video formats as possible, but often does not. Because so many factors influence video display in web sites (browser type, browser version, the operating system, codec type, codec version, player type, p[layer version, support of HTML5's 'video' element, etc.), there is no solid or predictable video tool to help you decide what's best in all scenarios. Example: The best video codec today with the "widest support" is MPEG-4. But MPEG-4 alone has different "encoding" types for each operating system, with Apple having one, DivX another, Windows another, etc. Some may or may not play based on operating system version, what software is installed, and whether the video is encoded in a version or type to support playback on that particular OS with its various players and their versions. Its possible some devices or browser versions do not have the player to play MPEG-4's at all, or have an older player that does not support a newer codec. On Windows 10 today this is still an issue for millions of people using MPEG-4, which is supposed to have almost universal support. So my point is, the problem of using 'track' elements begins with the problem of just getting video to consistently play across browsers and devices commonly used today.
    3. Problems Using 'track' Elements in Video: The 'time' track element is dependent on a supported video format and player in the user's browser, but is also dependent upon a "time track file" it must download and which must have both the right text and the right video codec support necessary to display that text inside the video. That track file dependency is what often fails in web videos, for multiple reasons, and why time track captions do not work reliably today. My goal in delivering web video and tracks, like my goal in HTML, has always been to pick the solution with the biggest "chances" of working for the most users possible. But in the case of "video tracking" files, this still is almost impossible for the fact that so many types of video and tracking in video is not standardized across the industry. I could give you one solution and tell you how to do it. But then for many of the readers of this article, it is not likely to work. One example is using the new "WEBVTT" format. It turns out it might work in MPEG-4, but will not in Apple Quicktime or many versions of Windows Media video files. In addition, there are numerous "versions" of each video codec that support different formats for tracking files used in video. Even if you added in all the variations of codecs, then added in all their supporting tracking file types, the video file might still fail across a wide range of devices, like iPhone, or Windows 10 users, etc.
      Video "time tracking" file "types" have their own problems and just compound the issues, when you truly look at all the types available today. There are so many "types" and "versions" of video tracking files in 2022, its way too complicated to sort out what is truly supported on what OS or browser. Below is a short list of the tracking file "types", some of which work for multiple video types, while others work for just one type:
      • .smil (Apple movies mainly)
      • .dfxp (Flash using ttml)
      • .vtt (new WebVTT format for the web)
      • wmp.txt (For Windows Media using .wmv formats)
      • .ttxt (3g devices)
      • .sami
      • .srt
      • .sub
      • .ttml
      Compound this issue with the fact there are multiple ways to add captions to videos. Beyond files, some video types have internal captions that do not support tracking files, where the captions must be encoded INTO the file. Some formats do not have any tracking, subtitle, or caption support. For these reasons and more, I recommend you abandon the 'track' element and instead use third party products and their proprietary caption systems. Most of these allow you to creatively build your videos and caption text online using their services or software, or have text captions embedded into their proprietary video formats. They then customize the video to support "on"/"off" caption and subtitling, translate the text for languages, and add other features and goodies way beyond what a simple HTML 'track' element might provide. YouTube would be one type I recommend. They also offer free streaming of the video (rather than on-demand downloads from your web server) and easy ways to "embed" the video into your web site. Some like YouTube, even offer monetization so you get paid when someone views your video! (This is a HUGE industry I will not discuss here).
      For these reasons and more, I cannot recommend use of the 'track' element until either HTML5's "living standard" matures to the point that an agreed on standard is supported across MOST of the browsers and players and codecs, or one codec amongst all the types available rises to the top of the heap, and becomes so widely supported and used that it becomes the standard online. It appears MPEG-4 has the best chance of that occurring. If you wanted to attempt to use the 'track' element, I would start with that codec. But right now in 2022, there is no clear winner when it comes to video much less track file formats. So, until that occurs, I cannot recommend use of the 'track' element in either video or audio. Otherwise, you risk seeing lots of browsers and frustrated users fail to see your carefully built time track text in videos.
    4. Cross-Browser Support of the 'track' Element: The 'track' element has decent support across all HTML5-supporting browsers except IE9. But it has NO support or alternative solution for all older browsers that do not support HTML5. So, tracking would not appear for those viewers. But, because lack of support of the 'track' element does not harm video playback, the lack of seeing text captions in video would do no real harm, and would be acceptable, in my opinion. It just would not work in most cases, anyway. So why try?
    5. See the following article for a full discussion of video codec types and limitations with creating a cross-browser video experience on the Web: "How to Create a Cross-Browser Video in HTML5".
    <ul> ul, unordered list

    Unordered List

    see <li>
    My Recommendations:
    1. The 'ul' element defines an unordered list. See the <li> element for a full description.
    <u> underline, unarticulated annotation

    Unarticulated Annotation

    Note that this element used to be called the "underline" element, but is now called the "Unarticulated Annotation", indicating text that is a non-textual annotation. This means it should be used to decorate text that needs further explanation, like a spelling error.

    This is some <u>mis-pelled</u> text that is given focus.
    This is some mis-pelled text that is given focus.
    My Recommendations:
    1. The 'u' element represents inline text that is different from the surrounding text. It often uses a plain "underline" to denote text that is "different", misspelled, or has an error. The general term for this element in 2022 changed to "Unarticulated Annotation"", or text that requires an explanation outside the context of the text content meaning.
    2. The Changing Purpose of the 'u' Element in History: In old HTML4, this element was used as a general way to "underline" any type of text that represented an idea or meaning that was important in a sentence. Later, this element was removed from earlier HTML recommendations because, like the 'small' or 'i' element, it was used by designers solely for styling text, not for assigning any semantic meaning to it. CSS could do that much better. But, in HTML5, the 'u' element has been reinstated. Why? Its purpose and meaning has now changed, though its name and style remain the same. It still underlines text, but the 'u' element now represents text which must be given focus because it is "different". It is now used to wrap around annotated text or text that has an extra meaning, like "misspelled words", mark text that stylistically is different, or text which has an error of some kind. But I do not recommend its use unless you completely change its CSS style, as shown below.
    3. The 'u' is Not Recommended: Why? I personally do not like the HTML5 definition of underlined 'u' text as representing misspelled words as that concept has no real meaning in the world of books and online text pages. No web pages or books I know of ever underlined text to alert someone of spelling errors. Why? Because they corrected them! In addition, you cannot use 'u' for emphasized or important text in a sentence, because 'em' and 'strong' are now designed to cover those scenarios. You also cannot use 'u' to underline text, as that will confuse readers with the 'a' element, or hypertext links. In addition, underlined text has been traditionally used in books for "focused parts" of a sentence, or to alert readers to important text. For all these reasons and more, you will just confuse viewers using 'u' and its default underline style. Plus, we now have the "spellcheck" attribute, which catches all "spelling errors" anyway and underlines them with a "wavy" line for you! So the 'u' element is truly redundant in websites today. And I do not recommend use of this element for the purpose stated in the new HTML5 standard, nor as a quick means of underlining "different" text, UNLESS you change its "underline" style permanently using CSS. If you do use the 'u' element, I HIGHLY recommend at the very least you change the "underline" style of the element to a "wavy" line (as shown above), or at least a "dashed" line for older browsers so users understand something is wrong with the text string (spellcheck error line). This also removes the confusion with hypertext links that are traditionally underlined in millions of web pages today. Because some older browsers supported the older 'u' element style, or might not format 'u' elements at all, I recommend you set the element with this permanent new CSS style. This then associates the underlined text as looking like a true "error". An example is shown below that works in old and new browsers. Note that some older browsers do not support the "wavy" style of line (like IE5), so the fallback "dashed" style is added below:
      
      u {
          /* Older IE browsers only */
          text-decoration: underline dashed red;
      
          /* Try and use the "spellcheck" wavy error line instead. */
          text-decoration: underline wavy red;
      }
      
    <var> variable

    Variable

    <p>The formula is: <var>a</var> + <var>b</var> = <var>c</var>.</p>

    The formula is: a + b = c.

    My Recommendations:
    1. The 'var' element is a piece of inline text representing a variable in a mathematical expression. This inline element is used to wrap around text strings that represent "variables" in equations. 'var' has been around since HTML4 and is still supported in HTML5. This element is similar to <code>, <kbd>, and <samp> in that 'var' formats text to represent abstract computer programs, keys, equations, or ideas.
    <video> video

    Video

    <figure aria-labelledby="myvideo" style="padding: .5rem;border: 1px solid #bbb;background: #f0f0f0;width: auto;height: auto;display: inline-block;">
      <video id="video1" alt="video: Fireplace Video" width="320" height="240" style="width: 320px;height:240px;border:1px solid #bbb;" controls="controls" preload="metadata" title="A Video of a Cracklin' Fireplace" aria-label="Fireplace Video">
        <source src="video1.mov" type="video/quicktime" />
        <source src="video1.ogv" type="video/ogg" />
        <p><strong>Sorry, this video file will not play. Your browser does not support the video element or the file formats available.</strong></p>
      </video>
      <figcaption id="myvideo" style="font-size:smaller;">"Fireplace Video" [<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>

    Notes on this Video Example: If your browser supports the video element below you should see a movie of a fireplace. In this example, I have given HTML5 browsers two video "sources" to choose from: MOV (Apple Quicktime) and OGG. Your browser must support the new HTML5 'video' element and one of the two video codecs in order to see the movie.

    "Fireplace Video" [CC BY-SA 3.0],
    via Wikimedia Commons
    My Recommendations:
    1. The 'video' element is a new HTML5 tag used to embed movie content in web pages, including video files, streams, or movies files. (It replaces the old 'object', 'applet', and 'embed' elements in HTML4). Note: Unlike the old 'object' and 'embed' elements, which were often used with 3rd party plugins and players to play movies in past browsers, the new HTML5 'video' element is built into the browser and managed without a secondary player. Different browsers and OS's support different multimedia codices. So it is never 100% certain your browser or device will support your video file. That is why the 'video' element also comes with the new <source> child element with its "type" attribute to support your many video encoded alternatives (as show in the code above).
    2. The 'video' tag is structured like the <picture> element with multiple fallback child <source> tags representing alternative video 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.
    3. In the code example above, I have wrapped a 'figure' element with a 'figcaption' element around the 'video' element, so you can see how a full caption can be applied. This adds powerful ARIA attributes and descriptions for your videos so they are accessible by screen readers and the blind, as well. This matches how the new HTML5 'picture' element is used with 'figure', as both elements now work the same way with captions.
    4. As always give your element an 'id' for script control and a 'title' attribute to tell users what the video control will do.
    5. The 'src' attribute in 'source' elements must point to a valid video file or the video controls will not play a file when pressed.
    6. The 'alt' attribute in 'video' elements helps screen readers and the blind identify the meaning of embedded video elements, just like images provide. For that reason, always add the "alt" attribute.
    7. The 'width' and 'height' attributes can be set on the element, as well as in CSS. I recommend you ALWAYS set the attribute dimensions first, so the browser can create a placeholder for the 'video' element's dimensions. But you can always override those values and set dimensions in CSS so you have more flexibility. Note: The video 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.
    8. The controls="controls" attribute specifies that video 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 video element, but I do not recommend you play video without giving a user control.
    9. The 'preload' attribute specifies a hint to the browser as to when the video 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 video 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 video 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 video 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 video streaming service and video player would negotiate over a streaming protocol like udp/rdp, etc. So, keep that in mind if your page has lots of video files on your server!
    10. There are other 'video' attributes you can apply, like 'loop', 'muted', 'crossorigin', 'poster', and 'autoplay' you can use for more control of your video, though I do not recommend them.
    11. There are numerous scripted methods and events you can apply to your video element along with scripts to fully control and customize your video player.
    12. Beneath the video control sample above I have added some small text with more info about the video 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 video element, so its text description becomes its caption. This allows it to work with captions as a 'picture' or 'img' element would do.
    13. CSS styling of the video control is difficult if not impossible, so realize there is limited support for designing video controls.
    14. Many modern mobile phone browsers as well as Internet Explorer 8 and earlier browsers on the desktop do not support the 'video' element! These older agents prefer the 'embed' (non-IE) or 'object' (IE only-ActiveX) elements, instead. So, keep in mind the limited support many modern browsers may have for the video control and its many features.
    15. I recommend use of the new HTML5 'video' 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. If you need more universal support for video controls across devices and browsers consider building a JavaScript-based video control. See the following article for a full, cross-browser movie example using the new 'video' element with alternative code for older browsers: "How to Create a Cross-Browser Video in HTML5".
    <wbr> word break

    Word Break

    <div style="border:1px solid black;width:auto;padding:.5em 1em;">
      <p>This (wbr) <wbr /> sentence can (wbr) <wbr /> drop down only where (wbr) <wbr /> I put a wbr element.</p>
    </div>

    This (wbr) sentence can (wbr) drop down only where (wbr) I put a wbr element.

    My Recommendations:
    1. The 'wbr' element is still supported in HTML5, though it was invented by Netscape 1.1 in the 1990's. It represents an inline "marker" that creates a word break "opportunity" should the text block need to break to the next line. Unlike the <br /> element, the 'wbr' does not create a "break" in the word or sentence unless it finds an opportunity to do so. It is rarely used, however.
    2. When to Use the 'wbr' Element: Add this element where you would like the browser to consider "breaking" text strings to the next line, should a breaking opportunity occur. This element allows article writers a little more control in how and where their sentences drop down to the next line when filling a browser window.
    3. 'wbr' and XML: HTML5 suggests you use the <wbr> element version. But, as I mention elsewhere in this tutorial, never use incompatible XML elements like this as they will cause your markup to fail in XML or XHTML parsers should your pages be parsed that way. Instead, always use the correct "XML-friendly" version: <wbr />
    4. No Internet Explorer browser (IE 1-11) supports the 'wbr' element, nor any browser that does not support HTML5. But, because it adds value and is non-obtrusive when it fails, it is safe to use.
    <xml> xml, data island

    Xml Data Island

    Xml Data Islands provided a way to store data in specialized xml tags. These would not be rendered in certain browsers (mainly Internet Explorer pre-version 9) and allow you to use various API's to extract client-side data. The two main methods used were to code directly into 'xml' tags or overload the script tag with these elements. Note: This latter idea was likely to fail in XHTML browsers without special CDATA tags. Today these tags are no longer needed because scripting API's and alternative data access via scripts has changed how and where client-side data is stored.


    <xml id="xmlid1">
      <xmldata>
        <data>text data</<data>
      </xmldata>
    </xml>


    <script id="xmlid2" language="xml">
      <xmldata>
        <data>text data</data>
      </xmldata>
    </script>

    My Recommendations:
    1. The 'xml' element is a deprecated element once supported in old Internet Explorer (pre-v9) and used to store data in a web page. That data was then accessible on the client-side using MSXML or other built in browser parsing JavaScript libraries. Often these were proprietary to Microsoft browsers or Windows users, or limited to JavaScript API library access. Most 'xml' data island tag support by Microsoft in their browsers ended after 2016 after the end of Internet Explorer browser support. It is no longer supported in HTML5 and rarely used. In 2022, you can now turn any element into data in a web page, use new HTML custom attributes like "data-" to store data, or use JavaScript API data solutions in combination with new the Web Workers API, window.LocalStorage, or storage of data in browser memory. My Recommendation: Do not use the 'xml' element or xml data islands to store data in web pages.
    <xmp> xmp

    Xmp

    <xmp>Non-formatted text with <span style="color:red;">HTML</span> text.</xmp>

    Non-formatted text with <span style="color:red;">HTML</span> text.
    My Recommendations:
    1. The 'xmp' element is a deprecated element once suppported in old HTML2/HTML3 that rendered text between the start and end tags without interpreting the HTML in between them. In some modern browsers, the 'xmp' tag may still function, but still should be avoided. Because 'xmp' is no longer supported in HTML5, do not use the 'xmp' element.
    2. Because 'xmp' text is also displayed in a non-formatted, monospaced font, this element can be replaced with the <pre> and <code> tags combined, escaping out HTML brackets as shown below. This simulates a display of HTML code, with text that is allowed to display in its native format, without line breaks, with added HTML escaped characters, and in a monospace or coded font. Use the sample code below to simulate this format in modern browsers:

      <pre><code>Non-formatted &lt;span style="color:red;"&gt;HTML&lt;/span&gt; and text.</code></pre>

      Non-formatted and escaped <span style="color:red;">HTML</span> text.
    * Global HTML Attributes
    The following Global Attributes Apply to all Elements and are Recommended:
    1. 'class' Attribute: Always assign a CSS class attribute to your elements, or multiple classes as needed (example: class="myclass1 myclass2"). Controlling styles this way with classes and matching class selectors in external style sheets is superior to embedded or inline page styles. AVOID the inline 'style' attribute on elements as it runs the risk of cascading over every class style you have, unless you are testing or building up styles on an element you will move to a style sheet later (example: style="font-size:2rem;"). Note: I only used inline style in my examples to show you how I would apply CSS to elements.
    2. 'id' Attribute: Always assign an 'id' with a unique value to all top-level structural elements (example: <header id="header">), to interactive elements like form fields and buttons, and to any element needing manipulation by JavaScript. HTML id's are easy to locate using scripts this way. Make sure they are always unique. I also like to use id's for styling elements, even though many say not to. If a unique elements needs to have its own special style, the heavy weight of an ID in Cascading Style Sheets rules will give it a 1000+ weight and make sure it cascades over any other styles applied. Just remember that 'id' styles only apply to that one element.
    3. 'hidden' Attribute: The new hidden="hidden" attribute can now be applied to any element in HTML. It is used to hide elements and works just like "display:none" in CSS. I still prefer the rich control of CSS as it has more options for hiding things. If you choose to rely on CSS for hiding things, then use "visibility:hidden" or "display:none". But the new HTML5 'hidden' attribute has promise! See my section called "How to Hide HTML5 Elements and Content using CSS" for more details.
    4. 'title' Attribute: The 'title' element can appear as an attribute on any element that appears on mouseover/rollover by the user. As mentioned, I like to apply titles (or what some call "Tooltips") to all my interactive elements, including all images, form fields, links, and headings. It is a nice rollover popup feature you can use when you want to give users more descriptive information about what an image, button, link, or form field represents. Many new developers avoid it in their HTML and leave out a critical piece of good web page interactivity, when they do.
    5. 'data-' Attribute: As mentioned below in my "Best Practices", you can now safely use the new "data-" attribute in any HTML element and name them anything you want after the 'data-' extension. Browsers ignore these, but scripts can use them to store and retrieve powerful information about your elements and the data they represent. Note: Older browsers will safely ignore this new HTML attribute, so its use will degrade gracefully in those older user agents, as well. Note that "data-" attributes are never sent to the server with form data! So do not rely on them for data processing, just scripting tricks.
    6. 'aria-' Attribute: As mentioned below in my "Best Practices", you can now safely use the new 'aria-' attribute in your elements to add additional accessibility and meaning to your HTML markup for screen readers and the blind. Use these new attributes to assist screen readers and other devices in understanding the semantic meaning of your HTML beyond what the elements already provide. But do not overdo it as most HTML elements have semantic meaning that most screen readers already interpret without additional attributes. The exception is "aria-label" which does allow you to "name" an element and its function, assisting screen readers. ARIA attributes are especially critical if you are building heavy Single Page Applications (SPA) using JavaScript-based, client-side web applications that update the browser's DOM behind the scenes without any server refresh or knowledge of those updates provided to screen reader software. In those cases you may find you need to not only add ARIA attributes to your HTML tags but the "live" versions as they change via scripts. Because this is affected by scripting technology, this is not discussed here. Note: Older browsers will safely ignore these new HTML ARIA attributes, so its use will degrade gracefully in those older user agents.
    7. 'inputmode' Attribute: This new attribute is gaining in popularity but still poorly supported in browsers. "inputmode" is now used as a "hint" to tell browsers the type of data to expect, like "email", "search", "url", etc. Because its not supported in IE, Safari, or Firefox browsers prior to version 24, its not widely supported enough to be helpful yet. For now, I do not recommend it. But as browser increase support of it in the years ahead, be prepared to to add it back in.
    8. 'spellcheck' Attribute: This new attribute is gaining in popularity, but still poorly supported in browsers. But when the browser comes with spell checking, adding "spellcheck=spellcheck" to any form element causes a "wavy" colored line to appear under any misspelled word typed by the user. This improves the quality of data coming into your website, when it is supported. Because it does no harm when it fails, it's totally safe to use. I like to add it to all my 'textarea' form fields so users can be alerted when they need to correct their text.
    9. Microdata: Microdata and its array of "item" attributes is a new annotation attribute for decorating your HTML elements with additional data and search engine metadata using name-value pairs that is more machine-readable. Basically you can add Microdata by adding "itemscope" to a top level element to create an "item" for the search engine spiders to index. All tags inside this parent that have an "itemprop=propertyname" tells the engines the tags property name, with the property's value being the text inside the tag. A "schema" is often used for "itemtype" on the parent, and defines a range of recognizable, agreed on standard properties to use. The schema also helps search engines categorize the data quickly when indexed. A simple example of how to use Microdata is shown below:
      
      <div itemscope="itemscope" itemtype="http://schema.org/Movie">
          The itemtype attribute above has been assigned to a third party "schema", and uses its content definition for "Movie" to help identify available properties for the data shown below.
          <h1 itemprop="name">Avatar</h1>
          <p>Here the search engine will see an item for a movie schema with one property assigned called "name" whose value is "Avatar". What is contained in the itemscope is itemprop or a property of the "Movie" schema type. This then tells search engine exactly what the content is and its category of data used by its property and value.</p>
      </div>
      
      This isn't a required HTML attribute, but can be helpful in building apps that will be indexed by search engines. Google is already using this to improve search results and add more granular metadata meaning in all parts of the web they index. Because most HTML is self-describing, this is often extra fluff to what is built into HTML already, and so not needed. Like the "data-" attribute or 'data' element above, it does not affect form field data sent to the server, the design of web pages, or the semantic characteristics of HTML. It is not helpful in terms of adding real meaning to your web pages. It is mainly for JavaScript or certain search engine effects. I would only use it for enhancing search-engine friendly markers in your HTML and for pages that have lots of tabular data. One example is large public-facing, informational websites that will get heavily indexed or archived by many types of parsers, bots, and search engines. Microdata is only fully supported in Firefox on Android at this time, so without wider browser adoption I cannot recommend Microdata.
    10. Microformats: Microformats, like Microdata, allows you to associate more meaning with your HTML and content. Minus the schema design found in Microdata, Microformats allows search engines, booksmarks, subscriptions, feed readers, and future browser extensions to extract more data from your content. The ultimate goal with this strategy is to extract data into JSON or other formats, and enable more access to your web page content and its meaning.
      One example of Microformats is shown below. The "h-card" is inserted into the CSS style "class" attribute, and represents any individual or organization to parsers of Microformats. In theory, this would allow this link to be parsed as a contact "card" to a specific person with a name, email, and "Twitter account" link. This data might be parsed by social media, search engines, and other feeds using your web page:
      
      <dev class="h-card">
          <span class="p-name">Your Name</span>
          <a class="u-email" href="mailto:name@website.com">name@website.com</a>
          <a class="u-url" rel="me" href="https://twitter.com/sometwitter">@sometwitter</a>
      </dev>
      
      Many of these new technologies are being integrated into public-facing websites build by 3rd party products like Wordpress and others. They then allow a limited set of browsers and parsers a slightly improved connection to your page data. This data is then parsed into data formats like JSON or XML, and linked back to your site. However, until we see wider adoption and more more general use, none of these technologies add a real benefit to your pages. Unlike Microdata, Microformats seems to have wider support in browsers. But Microformats is still is not supported by Internet Explorer or Safari browsers, desktop and mobile. It still does not yet replace standard search engine parsing or indexing to a degree that a solid argument can be made for its consistent use in building HTML pages. Until we see wider adoption and IDE's enable more implementations of Microformats in JSON, I do not recommend a major effort in using this new technology. Unless you are designing a very large public-facing site with with data tied into authors, organizations, social media, and indexed data, I see no reason to use Microformats at this time.
    11. RDFa: RDFa (Resource Description Framework in Attributes), like Microformats and Microdata, allows you to associate more meaning with your HTML content using HTML properties attributes tied to schema terms. Like the others, it has limited browser support and even less use-cases to warrant the effort in decorating your HTML with such attributes. If you do choose to use RDFa, remember that it has limited search engine support, is more closely tied to XHTML than HTML, and is best implemented when needing to develop large public sites with lots of rich data that must be consumed by search engine bots. It should be combined with the other data formats described above, so you cover all the various types of search engines and parsers. When used in combination with the other formats, it then becomes a measure of your overall web page search engine indexing performance and search ranking goals versus the cost of maintainability. That is why such HTML attributes are best used in larger sites, like Wordpress blogs and social media sites, where SEO goals are very important.
      An example of a simple RDFa code sample below shows how the new schema attribute "property" defines a term based on an external schema and the "inner HTML" text defines its value in the RDFa world. There are more resources online to cover all the nuances of this attribute and how it is best used. But I cannot recommend it at this time as an important tool in designing your HTML5 elements, unless you are designing a very large public-facing web application that would benefit from data parser support beyond the standard web browser:
      
      <h3 property="http://purl.org/dc/terms/title">Some Title</h3>
      <span property="http://purl.org/dc/terms/created">2021-12-20</span>
      


    HTML5 "Best Practices"

    Rules for Well-Formed HTML5

    Hypertext Markup Language (HTML) is the language of the World Wide Web. HTML has been around since 1990 and was invented by a British computer scientist named Sir Tim Berners-Lee. In fact, you can still view his first HTML website online! The general HTML markup language has not changed much since 1990. I have been coding in it since 1998, and since those early days have fallen in love with its simple, reliable, easy-to-use language (as have millions). Of all the dozen or more advanced languages and frameworks I have used over the years as a software engineer, HTML is still my favorite!

    Here in 2022, HTML5 is the newest markup language for creating web pages on the Internet. It has been around since 2008, but was not widely adopted until after 2010. HTML5 is based on HTML4, and has enriched the older standard with new elements and features. Since its conception, however, HTML5 has moved in a slightly different direction from what I call the "original HTML". HTML5 has in fact become a looser form of the earlier HTML markup languages. For starters, it is no longer aligned with SGML (the language for defining standard markup languages). Nor does HTML5 follow standardized markup rules as it did in the past two decades since its invention. After 2010, the organizations that now manage HTML5 have decided to abandon stricter standards and move forward with what I call a "vendor-based model" for how HTML should be interpreted. That has meant increased flexibility under its new "Living Standard" for browser makers. But the price paid, in my opinion, has been a disconnect from "good" coding practices of the past by many new web developers using new HTML5.

    It is true that HTML5 no longer has any connection to its older and more mature cousins: HTML4, XHTML, and XML. HTML5 now accepts a wide range of coding conventions, mistakes, errors, sub-standards, and styles. The browsers and parsers today that implement it have followed that "free-form" idea and are all stuck in an unending state of partially implementing the latest flavor of HTML5. It is a very forgiving language. But as a result, HTML5 is no longer well-formed, will not validate, nor does it follow older, standardized markup rules. The doctype declaration for HTML5, for example, no longer even needs a true "Document Type Definition" (DTD). Even the "quirksmode" concept of modern browsers flipping from "standards mode" to a quirks rendering mode is quite vague. This means the HTML5 coding "standard" is really a stripped down version of what HTML4 and XHTML1.0 transitional used to be. And that is why in HTML5 we have returned to "tag soup".

    But in its defense, modern HTML5 has been designed in such a way to allow a more "open" interpretation, and to allow a wider range of old and new conventions to be adopted and accepted across many devices, browsers, industries, and users. Many say that kind of flexibility is a good idea. But long term, I disagree. Forgiving coding standards without any enforced rules just allow bad or lazy coding practices to creep in. Already some new developers online are now advocating for a very proprietary, older, subversive "standard" of HTML markup that returns the language back to a non-standard, older, sloppier markup format most of us last used (and abandoned) in 1998 with HTML 4.1. The web will now be an even bigger patchwork quilt of broken HTML if we all allow it to go backwards and support poor markup conventions. All this may bode well for a more "adaptive", forgiving, human-centric web. It means struggles later for the machine-driven AI, "no code", or automated web of the future.

    But there is hope! For starters, you do not have to use HTML5 the way it was "recommended", or even use HTML5 at all! There is now a "polyglot" form of HTML5 called XHTML5 that follows stricter coding strategies, but which supports nearly all HTML5 elements. You can still use old XHTML transitional, XHTML strict, and even old HTML4, if you like. Coding in the XML-compliant versions do require well-formed markup, which also means they automatically work in sloppier HTML5, should you switch. The problem is that the reverse is not always true. Many of these antiquated coding "recommendations" used by HTML5 may support a greater variety of markup practices used online, but they would never support any of the more robust and reliable XML practices used in these other formats.

    The fact remains that HTML5 is what is hip, cool, and popular at the moment. And so that is what we should all adopt for building web applications on the World Wide Web. But, just because HTML5 has consistency flaws does not mean your HTML5 code has to follow bad coding practices. HTML5 is very forgiving, right? That means web developers and designers can adopt HTML5 as their primary web coding language but still follow "good" markup practices, if they like. HTML5 markup can follow "well-formed" XML markup practices and cleaner XML conventions, for example. It just isn't required to. But why would you do that when you can use ugly, sloppy HTML and get away with your "tag soup"? The answer is simple:

    By following the stricter XML markup standards in your HTML code, your HTML5 web pages can now be backward and forward compatible with XHTML5, XHTML1.1, XML, and even old HTML 3.2 or HTML 4.1. It can be nearly 100% cross-browser compatible with all these old and evolving newer standards all at once!

    There will always be markup in your HTML that is not 100% compatible with every language standard. But you can get close if not all the way there if you follow a few simple rules. That is at the heart of what "HTML5 Best Practices" means. But achieving that means hard work, erasing your bad assumptions, then re-learning all over again the RIGHT ways to build web sites in HTML. There are other reasons for you to follow more standardized XML-based markup rules in your HTML. The main one is so you deliver to modern browsers a fast and easily parsed HTML for the DOM tree (Document Object Model) that rendering and layout engines in browsers will inevitably build and display millions of times. Knowing that, why deliver sloppy markup to all those visitors? With cleaner code, rendering engines can build "Render Trees" faster in the DOM, generate faster layouts, and paint the viewport quicker, more reliably, and more efficiently using XML-based, standardized HTML. The user's browsers just run better! In addition, your ECMAScript "flavor-of-the-month" API can also parse, deliver, and read your HTML better with fewer errors or hiccups if the markup is clean, well decorated with attributes, consistent, and follows solid XML conventions. Some applications now read, write, and dynamically parse HTML pages as XML data, or even store them as XML in a database then recreate HTML from this data. Generating sloppy HTML from data that was not compatible with XML in the first place and that had to be "interpreted" or stripped of errors first, would make no sense, right? Why not build clean HTML from good HTML and return better HTML?

    I am not talking about perfection here, or even trying to validate your HTML in some way here. But the evidence is clear. Why not start off learning how to code HTML5 the RIGHT WAY using XML-compatible conventions? That is one of the MAIN REASONS for this tutorial....to teach you the right way to code. If the markup is clean and well-formed, as all XML is, then you will have zero issues with any of the things listed above, and your HTML will work well in XML or XHTML, or in future browsers using future HTML standards should you have to convert it. But coding in good, future-proof HTML means going BACK to older HTML conventions for answers, and forgetting current usage trends and ideas written about online today. Much of the articles written today about web technologies like HTML simply reinvent a wheel that was never broken!

    So, to start coding in good, clean, standardized HTML that is XML-compliant, simply follow my "Rules for Well-Formed HTML5" below. It will get you 99% of the way there!


    Rules for Well-Formed HTML5

    1. ALWAYS use lowercase tags in your HTML5 markup! This is the most important rule of all.

      DO THIS <input />
      NOT THIS <Input /> or <INPUT />

    2. Always use lowercase names for elements, attribute names and values, id's, files, CSS classes, paths, etc., unless it is a special script name. Remember, CSS is case-insensitive, but many HTML elements attribute names, like 'id' names and 'class' names are case-sensitive! So always go lower case to avoid problems!! The case of your names especially affects JavaScript variable names, so those can be cased as needed. Example: "Demo" is not the same as "demo" in ECMAScript variable and method names. I realize scripting frameworks today now use "camelCasing" (example: myMethodName) and other forms that do not follow older case rules. Those can be whatever you like. In terms of file names, many files in frameworks like .NET or on LINUX SERVERS are case-sensitive, too. So, mixed case file names could cause issues. Example: "London.jpg" is not the same as "london.jpg" on UNIX or LINUX, but is the same on most servers, Windows, or in browsers. UNIX also has been known to treat the domain parts of URL's with case-sensitivity. Also, many older browsers (like IE2 and IE3) treated CSS classes with case-sensitivity. That means if you use mixed-case CSS class names some browser would apply them where you did not intend! So assume everything is case-sensitive and stick with your own rules! I still would stick with lowercase text in your HTML tags, attribute names, and CSS until those case standards require changes in your code to support special API's or other 3rd party products.

      DO THIS <img id="myimage1" class="myclass" src="myimage.jpg" alt="My Image" />
      NOT THIS <Img Id="MyImage1" class="MyClass" SRC="MYIMAGE.jpg" Alt="MY IMAGE" />

    3. Avoid use of hyphens ("-"), double underscores ("__"), spaces (" "), numerical-first names ("1myclass"), and non-ASCII characters in all HTML attribute values, CSS names, paths, etc.. There are too many cases to cover where those items fail in various browsers and scenarios. But one example is older IE3 browsers where hyphens ("my-class") on CSS names will not work. Avoid all those special cases that could fail and stick with single underscore ("my_class"), instead. They look the same and can be creatively combined to cover all types of web page systems.

      DO THIS <a id="myanchorid2" class="myclass" href="http://mywebsite.com/mypath/" />
      NOT THIS <a id="2myanchorid" class="my-class" href="http://mywebsite.com/my path/" />

    4. ALWAYS use double quotes around attribute values in HTML elements ("..."), not single ('...'). In the "old days" it was ok to not use quotes around HTML attributes if the value included only alphanumeric values and no spaces, like this (title=hello). Not anymore! So, always quote your attributes in HTML5 to avoid a parser failing to read your values. If you have JavaScript inside, you can use single quotes with substrings inside. The exception to this is special CSS cases inside style sheets that use @import rules or background-image URL's which often use single quotes. Note that quotes in HTML attributes and JavaScript can be safely repeated over and over if you have complex strings within strings within strings using escapes: alert("John said 'What is the \"Truth\"'");
      A typical "best practices" example of quotes in element attributes using scripts is the following:

      DO THIS <a href="http://..." onclick="MyMethod('my string');" />

    5. Always explicitly define values in all attributes, and avoid ALL attribute minimization, despite HTML5 recommendations to the contrary. In elements like input controls, avoid the shorthand attributes. Don't rely on HTML5-recommended shorthand attributes like this as they are not XML-compliant and some may just fail in certain browsers:

      DO THIS <input checked="checked" />
      NOT THIS <input checked />

    6. ALWAYS close all element tags with a matching ending tag or a space plus forward slash. Empty or "void elements" must still end them with " /" so they are XML-compliant. HTML5 now says so-called "void" elements (like <source>) must never have an end tag, regardless. Do not add an end tag, but do add the " /" value. Many older browsers, like Netscape, misinterpreted any ending without a space before "/", so always include the space. Don't accept elements that do not have either an end tag or an explicit " /" at the end, otherwise they are not XML-compliant. Many young HTML designers today regularly fail to close many elements in HTML now simply because the markup rules are not consistent:

      DO THIS <img />
      NOT THIS <img> or <img/> or <img></img>

    7. ALWAYS use plain ASCII supported characters when possible in your HTML5 elements, which is anything alpha-numeric in the basic 128-ASCII character set or that is accepted in a standard browser URI without URL-encoding. This would generally be (a-z, A-Z, 0-9) and a few special characters (-._~). Characters (:/?#[]@!$&'()*+,;=) can be used but are problematic as many define query string delimiters and have to be escaped. So I would avoid all of those. In general, avoid special characters within or above the 128 character set inside your elements. This avoids the need for escaping of unicode characters or other issues. HTML5 is now UTF-8 compliant by default, so your page content will support over a million characters. But inside a typical URL or HTML page they may not accept those higher order characters without special escape characters, character references, or entities. Do not trust your browser as the final word as older agents might not support UTF-8. If you must use them, you can add character references as mentioned, which are special escaped characters starting with an ampersand, which follows XML encoding rules. An example of that is shown below:

      <a href="#" title="&copy; My Copyright, 2022" >My anchor title uses a copyright entity</a>
      My anchor title uses a copyright entity

    8. ALWAYS make sure all your HTML elements are XML-compatible and Consistent. Always pick the right form of an HTML5 element to use in your pages and consistently stick with it! Use that form across all your future projects as well, regardless of what your peers are using. Below is a perfect "case" example of GOOD HTML5 practices I have followed for over 20 years! Always use the <br /> form of the "break" element. This ending "/" with preceding space makes it backwards compatible with HTML4, HTML5, XHTML, XHTML5, XHTML1.1 strict, and is 100% XML-compatible and HTML5-compatible, as well:

      DO THIS <br />
      NOT THIS <br>, <br/>, or <br></br>

    9. ALL HTML documents must be well-formed and properly nested All HTML elements must be placed within the <html> root element, be nested properly in other elements, and have matching node start and end names for a document to be well-formed. Note: This is not the same as a "valid" document, which means the document follows the rules set in the applied HTML5 DOCTYPE in the header of your page. This just makes sure your HTML is not "tag soup" with mixtures of errors and blunders that break how HTML elements nest inside other elements.

      DO THIS <p><span></span></p>
      NOT THIS <p><span></p></span>

    10. ALWAYS use the richest and fullest attribute set you can in your HTML. By decorating your elements with the RIGHT attributes you supply the browser, the user, the search engines, the JavaScript, screen readers, applications, and even the server with all the "goodies" they need to interpret, interact, and respond accurately to your web page. Those groups then can interface with your web application and the information it provides with the interaction you expect from them. The "three-way connection" between the server, HTML, and the user is then maximized. Below is one example of the rich attributes an HTML element can have that affect many different groups in different ways:

      DO THIS <a href="https://mitchellstokely.com/" id="myanchor1" title="This is a Link to my Web Page in a New Tab" rel="noreferrer nofollow noopener" tabindex="0" target="_blank" aria-label="Internal Page Link">My Web Page</a>
      My Web Page

      NOT THIS <a href="#">My Web Page</a>
      My Web Page

    11. ALWAYS give all your important elements a unique "id" value! Many web developers complain about the use of "id" attributes and argue they don't use them, or do not need them until in a panic using JavaScript or CSS, they suddenly need one at the last minute. This is bad practice. In fact, there are so many cases for using "id" attributes on HTML elements, I cannot list them all. A few are: "id" allows easy access to a specific HTML element by JavaScript, high selectivity weight when used to assign a CSS style rule, access as a quick bookmark from an anchor links, access to paired elements by ARIA "aria-labelledby" attributes, and support by XHTML over the use of "name", which is not supported. The list goes on a on! The fact does remain that some older browsers did not support "id" for say bookmarks. Also, form fields never use "id" when they send data to the server. They use "name". For all these reasons I always use BOTH, and match the two with the same value. See below. Just remember to always use "id" with a matching "name" when you do, and all your web pages will be fully functional forever!

      DO THIS <div id="message1" name="message1">This block-level element has a unique id and name, so can be easily accessed as a bookmark, accessed via CSS, or manipulated by a script!</div>

      NOT THIS <div name="message1">This block-level element has no unique id, so cannot be assigned a CSS style, accessed as a bookmark, nor manipulated by a script so easily.</div>

    12. ALWAYS use Absolute Paths, not Relative Paths in all your HTML. Many new web developers have started to adopt these new, shoddy relative path systems in their HTML, CSS, JavaScript API's, and software systems that make updating and managing code paths difficult. They run the risk of failing in numerous ways, and add unnecessary complexity to simple web applications. You should AVOID relative paths as they often fail in older browsers when using paths in CSS and HTML. CSS was a perfect example where relative paths failed. But they also make maintenance of code extremely convoluted and difficult. When you use absolute paths, all paths are based off the web root, and allow you to see the true path to the files in question. With relative paths, its a mess as you can never know where the path starts and if the path up and down the folder tree is correct. Is the path to the file relative to the HTML file, some arbitrary virtual application path, the 'base' element path, or some artificially constructed application path? Relative paths can fail if the path does not know either the source or the destination, both of which can change and break relative paths quickly. There are just too many ways relative paths can break. Absolute paths always start at the web root and dive directly to the source, avoiding the need to know the start of the path. The web root is always the start in absolute paths. In the past, some older browsers like Netscape and IE3 would break if relative CSS paths were used. The one case for using relative paths is if you plan to have a website with multiple virtual applications that will move around under the same domain. In that one case, relative paths would allow you in most cases to move a website folder of files high, lower, or horizontally in an application and all the paths work. But absolute paths offer you the ability to move applications when you use server paths generated dynamically. Because all the paths start at the root, the server could easily inject a single root path for all images, styles, and scripts used in the project so that moving them is dynamically updating on the server via a single application path. Thats not possible with relative paths, which are all different. So, stay with absolute paths always, and avoid relative ones.

      Even a famous web designer, J. Zeldman, agrees with me:
      "Absolute URLs are more reliable than relative URLs because they don't break if file locations change; for instance, if "/events.html" moves to "/events/ index.html", the absolute reference to "/content/logo.gif" will still work. Also, absolute URLs help avoid a CSS bug in some old browsers that misunderstand relative file references in style sheets."


      USE ABSOLUTE PATHS LIKE THIS: "/css/theme1/styles.css"

      DO NOT USE RELATIVE PATHS LIKE THIS: "../../theme1/styles.css"

    13. ALWAYS use HTML elements that are widely supported in as many older browsers as possible and avoid most newer specialized HTML5 markup and tags that are not supported. (I cover this issue extensively in the sections below.) This is a no-brainer, and shows sensitivity to people whose browsers would fail to interpret your HTML layouts or content correctly. Often, this does not mean creating elaborate alternative HTML, polyfills, or running huge script libraries with fixes like Modernizr, but enabling older browsers to display your content adequately with bare-bones HTML, letting your layouts degrade gracefully in these older agents. This is now called "Progressive Web Design". In the old days we just called it good practice! Sensitive HTML designers must refrain from using the "latest and greatest" HTML5 tricks just to support fancy layout designs when needing to assist users with older browsers. In addition, JavaScript "polyfills" and other JavaScripted fixes that pollute the user agent with huge file downloads, JavaScript libraries, and additional CPU processing in order to add fixes to the browser's DOM are not good solutions in HTML, and are not recommended. "KISS", or "Keep it Simple Stupid", was the recommendation 20 years ago. It still applies today!

    My Complete HTML5 Template

    Below is a complete HTML5 template you can use that has all the recommended elements and attributes needed to build a good web page. This is a great starter template that you can cut-and-paste into any HTML5 web project knowing it will always work well in many browsers, old and new. This one has many good features for full cross-browser support in numerous browser versions and types, including full support for the latest and greatest HTML features used in more modern HTML5 browsers. (The elements shown are all discussed in detail in my HTML5 element section above.) This code below is well-formatted and coded in lower case text, is XHTML5/XHTML/XML friendly, includes all code needed to support CSS and JavaScript, and even has alerts for those browsers that do not support styles and scripting. What is best about this template is it required no JavaScript to create any of these features! It is pure HTML! You will need to add custom HTML page elements to this template under 'body', add custom server paths and files, add your external style sheets, and any JavaScript code or file paths needed. You will need to apply custom CSS to this template. It includes many hidden "gems" you will see in the code below that you will want to hide, show, or customize using CSS.

    Copy-and-Paste the Code Below to Create A Complete Web Page in HTML5