W3docs

HTML5 Browser Support

On this page, you can find useful information about browser support in HTML5, learn about semantic elements and HTML5Shiv and find different examples.

Every evergreen browser — Chrome, Firefox, Safari, and Edge — has supported HTML5 semantic elements natively for over a decade (since roughly 2013). On today's web this is rarely something you need to think about: you can write <header>, <nav>, <article>, and the rest, and they just work.

This page covers two related topics. First, the one small CSS line that historically guaranteed semantic elements rendered as blocks. Second — kept here mainly for historical context — the HTML5Shiv polyfill that was once needed to make those elements work at all in Internet Explorer 8 and earlier. We finish with the modern way to check for browser capabilities.

Why Older Browsers Needed Help

When a browser meets an element it doesn't recognize, it doesn't ignore it — it still puts the element in the DOM. The question is how it renders it. By default, an unknown element is treated as display: inline. The new HTML5 semantic elements, however, are all block-level by design (like <div>). So in a browser that didn't know about, say, <section>, that element would lay out inline instead of as a block, quietly breaking margins, widths, and stacking.

There are two separate problems an old browser could have:

  1. Layout — the element exists but renders inline instead of block. Fixed with one CSS rule (below).
  2. Styling at all — Internet Explorer 8 and earlier could not even apply CSS to elements it didn't recognize until they were "registered" via JavaScript. That is the problem the HTML5Shiv solved.

Semantic Elements as Block Elements

HTML5 specifies several new semantic elements, and all of them are block-level elements. Here they are:

To force these elements to render as blocks in an older browser, set the CSS display property explicitly. Modern browsers already apply this rule themselves, so it does no harm to leave it in:

header, section, footer, aside, nav, main, article, figure {
  display: block;
}

Note that display: block alone is enough to fix layout. It does not, on its own, make Internet Explorer 8 able to style the element at all — that older limitation required the JavaScript shim described next.

HTML5Shiv (Legacy)

Legacy / historical. HTML5Shiv (also spelled "shim") was a tiny JavaScript file needed only for Internet Explorer 8 and earlier, which couldn't apply CSS to unknown elements. Microsoft ended support for those versions, and Internet Explorer itself reached end of life in 2022. Unless you have an explicit, unusual requirement to support IE 8, you do not need HTML5Shiv today. It is included here only for context.

The shiv is placed inside the <head> and referenced in a <script> tag. It is wrapped in an IE-only conditional comment (<!--[if lt IE 9]>) so that every other browser ignores it entirely.

Example of the HTML5Shiv:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <!--[if lt IE 9]>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <section>
      <h1>The most beautiful places in the world</h1>
      <article>
        <h2>Salar de Uyuni, Bolivia</h2>
        <p>The world's largest salt flats, spanning 4086 miles (10,582 sq. km), Salar de Uyuni is unlike anywhere else on earth.</p>
      </article>
      <article>
        <h2>Moraine Lake, Canada</h2>
        <p>Moraine Lake may be only half the size of its nearby neighbour Lake Louise, but it's even more scenic.</p>
      </article>
      <article>
        <h2>Iguazu Falls, Argentina/Brazil border</h2>
        <p>One of the modern natural wonders of the world, this chain of mini waterfalls is one of the planet's most awe-inspiring sights.</p>
      </article>
    </section>
  </body>
</html>

The Modern Approach: Feature Detection

Shiv-style polyfills patched a missing element for one specific dead browser. The contemporary way to handle browser differences is feature detection: instead of asking "which browser is this?", you ask "does this browser support the feature I want?" and adapt accordingly.

In CSS, the @supports at-rule tests whether a property/value pair is understood before applying a block of styles:

/* Use a grid layout only where the browser supports it */
@supports (display: grid) {
  .gallery {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
}

In JavaScript, you check for the API or property directly:

if ('IntersectionObserver' in window) {
  // Use IntersectionObserver
} else {
  // Provide a fallback
}

This pattern is more reliable than version sniffing because it tests the actual capability, and it keeps working as new browsers and versions ship. For semantic HTML5 elements specifically, no detection is needed at all in today's evergreen browsers.

What Else to Read

Practice

Practice
Which of these browsers support HTML5 semantic elements natively (no shiv required)?
Which of these browsers support HTML5 semantic elements natively (no shiv required)?
Was this page helpful?