HTML Structure and Semantics: Block, Inline, and Meaningful Markup

In the previous article, we covered the basics of HTML: what it is, how tags work, and how to build a simple web page from scratch. You should now have a good idea of how to create headings, paragraphs, links, images, and lists.

But here's something you might have noticed while experimenting. If you put two <strong> elements next to each other, they sit on the same line. But if you put two <p> paragraphs next to each other, each one takes up its own line. Why do some elements flow side by side while others stack vertically?

The answer comes down to a fundamental concept in HTML: block elements vs inline elements. Understanding this distinction is one of the most important steps toward working with CSS and building real page layouts.

In this article, we'll explore that concept, then look at how HTML handles whitespace and line breaks, elements that give your text richer meaning, and finally the semantic elements that give your page a clear, logical structure.

Block Elements vs Inline Elements

Every HTML element falls into one of two display categories: block or inline. This is one of those things that's really easy to understand once you see it, but can be confusing if nobody explains it clearly.

Note: Technically, the modern HTML specification no longer uses the "block" and "inline" categories. Instead, it defines a different set of content categories (flow content, phrasing content, and so on). That said, thinking in terms of block vs inline is still one of the most intuitive ways to understand how elements behave on a page, so we'll stick with the traditional terms throughout this article.

Block Elements

A block element always starts on a new line and stretches out to fill the full width available. Think of it as a box that takes up an entire row. Even if the content is short, the element still claims the whole line.

As introduced in the previous article, elements like <h1>, <p>, <ul>, and <div> are all block elements.

See how each paragraph sits on its own line? That's block behavior. The colored backgrounds make it easier to see that each element spans the full width of its container.

Inline Elements

An inline element does not start on a new line. It flows within the surrounding text, only taking up as much space as its content needs. You can place multiple inline elements next to each other and they'll sit on the same line.

Elements like <a>, <strong>, <em>, <code>, and <span> are all inline elements.

The <strong>, <em>, and <a> elements are all sitting within the same line of text. They don't force a line break - they just flow naturally with the words around them.

A Quick Visual Comparison

Here's a side-by-side look at the difference. The background colors are added so you can clearly see the space each element occupies:

Block elements stack vertically and take the full width. Inline elements sit next to each other and only take up as much width as they need.

Tip: You might have noticed the unfamiliar background-color: #b9e1ff; in the code above. That's not a regular HTML attribute - it's a style written with CSS (Cascading Style Sheets), applied directly to the tag through the style attribute. background-color: #b9e1ff; simply means "make the background a light blue." The #b9e1ff part is a color code: the characters after # are hexadecimal digits that specify the color. Don't worry about the details for now - we'll cover CSS properly in a future article. For the moment, it's enough to know that "this tag has a background color applied to it." CSS can control text color, margins, padding, and pretty much every other visual aspect of a page.

<div> - The Generic Block Container

<div> is a block-level container that has no special meaning on its own. It's a generic box. Its job is to group other elements together so you can style or position them as a unit.

On its own, <div> doesn't do anything visible. It doesn't add any spacing, color, or formatting. But it becomes incredibly useful once you start applying CSS. You can think of it as an invisible box that you can wrap around anything to control its layout.

In fact, <div> is probably the most commonly used element in real-world web development. If you "View Page Source" on almost any website, you'll see <div> elements everywhere.

<span> - The Generic Inline Container

<span> is the inline counterpart to <div>. Just like <div>, it has no meaning of its own. It's used to wrap a piece of inline content (usually a few words or a phrase) so you can apply styles to it.

Without the <span>, there would be no way to target just the price text and make it red. The <span> gives you a "hook" to grab onto with CSS without changing the structure of the text.

Tip: A common question is "when do I use <div> and when do I use <span>?" The simple answer: use <div> when you need a block-level container (to group sections of the page), and <span> when you need to target a piece of text within a line.

Also, don't be tempted to use <div> in place of <p> for a paragraph. Visually it looks identical - the text breaks onto its own line either way - but you lose the meaning of "this is a paragraph." HTML is fundamentally a language for building structured documents, so use <p> (which carries that meaning) rather than a generic <div> when you're marking up a paragraph of text.

Later in this article, we'll also look at semantic elements like <header> and <nav> that work like <div> but carry extra meaning.

Nesting Rules: What Can Go Inside What?

There's one important rule about block and inline elements:

  • Block elements can contain both block and inline elements.
  • Inline elements should generally only contain other inline elements or text.

For example, this is fine:

<!-- OK: block contains block and inline -->
<div>
  <p>A paragraph with a <a href="#">link</a>.</p>
</div>

But this is not valid:

<!-- Not valid: inline element containing a block element -->
<span>
  <p>This doesn't work properly.</p>
</span>

Browsers might still display it somehow, but it can lead to unexpected layout issues. As a general rule: block elements are containers, inline elements are content within those containers.

Note: The terms "block" and "inline" originally describe the default display behavior of elements. With CSS, you can actually change any element's display type - for example, making a <span> behave like a block element. We'll cover that when we get to CSS. For now, just focus on the default behavior.

Whitespace and Line Breaks

One thing that trips people up early on is how HTML handles whitespace. In your HTML source code, you might add extra spaces, tabs, or blank lines to keep things neat and readable. But the browser ignores most of that.

Whitespace Collapsing

In HTML, multiple consecutive spaces, tabs, and newlines are all collapsed into a single space. This is called whitespace collapsing.

All three of these render exactly the same way: "Hello World" with a single space. The browser doesn't care about extra spaces or line breaks in your source code.

This is actually useful. It means you can format your HTML code however you like (with indentation, blank lines, etc.) for readability, without worrying about it affecting the page's appearance.

Because whitespace is collapsed (outside of <pre>), you're free to add spaces to line things up and make your code easier to read. This is called indentation. The common convention is to indent your HTML based on how tags are nested, so the structure of the document is easy to see at a glance. Many editors handle this automatically these days, and there are plenty of formatting tools that do it for you. Even so, getting into the habit of keeping your HTML neatly indented is worthwhile - future you (and anyone else reading your code) will thank you for it.

<br> - Line Break

Since the browser ignores newlines in your source code, how do you actually start a new line? You use the <br> element. We touched on this in the previous article, but here's a quick review:

<br> is a void element (no closing tag needed). Use it for content where line breaks are part of the meaning, like poetry, song lyrics, or addresses. But don't use <br> to create spacing between paragraphs - that's what <p> and CSS margins are for.

<pre> - Preformatted Text

What if you do want the browser to respect your whitespace exactly as written? That's what <pre> (preformatted text) is for. Inside a <pre> element, spaces, tabs, and line breaks are preserved as-is.

The browser renders the text in a monospace font (like Courier) and keeps all the spacing intact. <pre> is commonly used for displaying code snippets, ASCII art, or any content where exact formatting matters.

You'll often see <pre> combined with <code> like this:

<pre><code>
function greet(name) {
  return "Hello, " + name;
}
</code></pre>

The <pre> preserves the formatting, and the <code> tells the browser (and screen readers) that the content is a piece of code.

Text Semantics: Giving Text Meaning

HTML isn't just about making text look a certain way. It's about telling the browser what the text means. This is an important distinction.

For example, you could make text bold using CSS, and it would look the same visually. But when you use <strong>, you're telling the browser "this text is important." Screen readers will emphasize it, and search engines will take note of it. That extra layer of meaning is what we call semantics.

<strong> and <em> - Emphasis

We used these in the previous article, but let's look at them a bit more closely.

  • <strong> marks text as having strong importance. Browsers display it in bold by default.
  • <em> marks text with emphasis (stress emphasis). Browsers display it in italics by default.

A common question: "What about <b> and <i>?" Those tags also exist. <b> makes text bold and <i> makes it italic, but they don't carry special meaning. They're purely visual. In most cases, <strong> and <em> are the better choice because they also communicate importance and emphasis to machines (search engines, screen readers, etc.).

<blockquote> and <q> - Quotations

When you want to quote someone or cite a passage from another source, HTML has two elements for that.

<blockquote> is a block-level element for longer quotations. Browsers typically indent it:

You can also add a cite attribute with the source URL:

<blockquote cite="https://example.com/source">
  <p>The Web does not just connect machines, it connects people.</p>
</blockquote>

The cite attribute doesn't display on the page, but it provides metadata about where the quote comes from.

<q> is the inline version, used for short quotations within a sentence. Most browsers automatically add quotation marks around it:

<ins> and <del> - Inserted and Deleted Text

Sometimes you want to show that text has been added or removed. <ins> marks text that was inserted (added), and <del> marks text that was deleted (removed).

By default, browsers render <del> with a strikethrough and <ins> with an underline. You'll often see these on e-commerce sites where the original price is crossed out and the sale price is shown next to it.

<address> - Contact Information

The <address> element is for contact information about the author or the organization. It's typically rendered in italics:

Note: As mentioned in the previous article, example.com is reserved for documentation and testing purposes. The same applies to email addresses at this domain - messages sent to any address ending in @example.com won't actually reach anyone, so it's safe to use in examples like this without any risk of emailing a real person by mistake.

Note that <address> is not for any physical address - it's specifically meant for contact details related to the page or article. For a general street address, a regular <p> is fine.

Semantic Structure: Giving Your Page Shape

So far, you know that <div> is a generic container you can use to group elements together. And it works great. But here's the thing: if you build an entire page using only <div> elements, it works visually, but the browser has no idea what each section actually is.

Look at this structure:

<div class="header">...</div>
<div class="nav">...</div>
<div class="main">...</div>
<div class="sidebar">...</div>
<div class="footer">...</div>

You and I can read the class names and guess what each section is. But to the browser, all it sees is five identical <div> elements. It doesn't know which one is the navigation, which is the main content, or which is the footer. Search engines have the same problem. This pattern of using <div> for everything is sometimes called "div soup".

HTML5 introduced a set of semantic elements that solve this problem. They work exactly like <div> (they're all block containers), but they carry meaning about the role of that section on the page.

<header>

The <header> element represents introductory content, typically at the top of the page or at the top of a section. A page header usually contains the site logo, title, and navigation.

<header>
  <h1>My Blog</h1>
  <p>A blog about web development</p>
</header>

<nav>

The <nav> element is for a section of the page that contains navigation links - like the main menu, a table of contents, or breadcrumb links.

<nav>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="/contact">Contact</a>
</nav>

Not every set of links needs a <nav> - it's meant for major navigation blocks. A few links in a paragraph don't need to be wrapped in <nav>.

<main>

The <main> element represents the primary content of the page - the stuff that's unique to this particular page. Headers, footers, and sidebars that appear on every page should be outside of <main>.

<main>
  <h2>Today's Article</h2>
  <p>Here is the main content of the page...</p>
</main>

There should be only one <main> element per page. Think of it as the answer to the question: "What is this page about?"

<section>

The <section> element represents a thematic grouping of content, usually with a heading. If your page has multiple distinct topics or chapters, each one could be a <section>.

<section>
  <h2>Introduction</h2>
  <p>Welcome to this tutorial...</p>
</section>

<section>
  <h2>Getting Started</h2>
  <p>To begin, you'll need...</p>
</section>

How is this different from <div>? A <section> tells the browser "this is a meaningful, standalone chunk of content." A <div> is just a generic wrapper with no special meaning. If you could give the section a heading, it's probably a <section>. If you're just grouping things for styling, use a <div>.

<aside>

The <aside> element is for content that is related to the main content but not essential to it. Think of it as a sidebar, a pull-quote, or a "related articles" box.

<aside>
  <h3>Related Articles</h3>
  <ul>
    <li><a href="/article-1">What is CSS?</a></li>
    <li><a href="/article-2">CSS Flexbox Guide</a></li>
  </ul>
</aside>

If you removed the <aside>, the main content should still make sense on its own.

<footer>

The <footer> element represents a footer for the page or for a section. A page footer typically contains copyright information, links to terms of service, or contact details.

<footer>
  <p>&copy; 2026 My Website. All rights reserved.</p>
</footer>

Putting It All Together: A Blog Page Layout

Now let's combine everything we've learned into a realistic example. Here's a simple blog page using semantic elements:

Notice how each section of the page has a clear role. There's no ambiguity about what's the header, what's the main content, or what's the sidebar. The browser, search engines, and assistive tools can all understand the structure without needing to guess.

Tip: A lot of new tags showed up at once - don't worry if it feels like a lot to take in. You don't need to master every one of them right away. Using <div> in place of <article>, <section>, or <aside> still works perfectly fine - your page will look exactly the same. When you're starting out, it's totally enough to divide your page into just <header>, <main>, and <footer>. Those three are usually the easiest to identify, and they already give your page a clear structure. Once you get comfortable, you can start reaching for <article>, <section>, and the others to describe your content in more detail.

Note: You might have spotted <article> in the example above. It's another semantic element that represents a self-contained piece of content - something that could stand on its own, like a blog post, a news story, or a product card. Think of it this way: if the content makes sense on its own (for example, if it appeared in an RSS feed), it's a good candidate for <article>.

Why Use Semantic Elements?

You might wonder: "If semantic elements look the same as <div>, why bother?" There are several good reasons:

  • Accessibility - Screen readers use semantic elements to help users navigate the page. For example, a user can jump directly to <main> to skip the header navigation.
  • SEO - Search engines understand your page structure better when you use the right elements. Google can tell the difference between your main content and a sidebar advertisement.
  • Readability - For you and other developers reading the code, <nav> is instantly recognizable. <div class="nav"> requires you to read the class name and trust that it's accurate.
  • Future-proofing - As browsers and tools evolve, they can offer better features for well-structured content. Semantic HTML is an investment in your page's longevity.

Summary

  • Block elements (like <div>, <p>, <h1>) start on a new line and take up the full width.
  • Inline elements (like <span>, <a>, <strong>) flow within the text and only take the space they need.
  • <div> is the generic block container; <span> is the generic inline container. Both have no meaning on their own but are essential for hooking into CSS.
  • HTML collapses multiple spaces and newlines into a single space. Use <br> for line breaks and <pre> to preserve whitespace.
  • <strong> and <em> add semantic meaning (importance and emphasis), not just visual formatting.
  • Use <blockquote> and <q> for quotations, <ins> and <del> for inserted/deleted text, and <address> for contact info.
  • Semantic structure elements (<header>, <nav>, <main>, <section>, <aside>, <footer>) give your page a clear, meaningful structure for browsers, search engines, and accessibility tools.

Try It Yourself

Try building a simple blog page layout using the semantic elements from this article. Add a <header> with navigation, a <main> section with a couple of <section> blocks, an <aside> sidebar, and a <footer>. See how the structure takes shape even before adding any CSS.

Open the SyncFiddle Editor and build your own page layout