Semantic HTML elements clearly describe their meaning to both the browser and the developer. They give structure and meaning to your content, improving SEO, accessibility, and code maintainability.
Why Semantic HTML?
Before HTML5, developers used generic <div> elements for everything:
<!-- Old way: Non-semantic -->
< div id = "header" >
< div id = "nav" > ... </ div >
</ div >
< div id = "content" >
< div class = "post" > ... </ div >
</ div >
< div id = "sidebar" > ... </ div >
< div id = "footer" > ... </ div >
HTML5 introduced semantic elements that give meaning:
<!-- Modern way: Semantic -->
< header >
< nav > ... </ nav >
</ header >
< main >
< article > ... </ article >
</ main >
< aside > ... </ aside >
< footer > ... </ footer >
Benefits of Semantic HTML
Better SEO Search engines understand your content structure better, potentially improving rankings.
Accessibility Screen readers navigate semantic landmarks more effectively, helping visually impaired users.
Maintainability Code is more readable and easier to understand for developers.
Consistency Standard elements create a common language among developers.
Main Semantic Elements
< header class = "header" id = "main-header" >
< div class = "header__container" >
<!-- Logo -->
< div class = "header__logo" >
< a href = "/" class = "header__logo-link" >
< span class = "header__logo-text" > ML </ span >
< span class = "header__logo-subtitle" > Store </ span >
</ a >
</ div >
<!-- Navigation -->
< nav class = "header__nav" >
< ul class = "header__nav-list" >
< li >< a href = "#" > Home </ a ></ li >
< li >< a href = "#" > Products </ a ></ li >
< li >< a href = "#" > Contact </ a ></ li >
</ ul >
</ nav >
</ div >
</ header >
Use <header> for :
Page header with logo and main navigation
Section headers within articles
Header area of any content block
Characteristics :
Can have multiple headers in a document (one per section/article)
Typically contains branding, navigation, search bars
Usually appears at the top but position isn’t required
A <header> doesn’t have to be at the page top. Articles and sections can have their own headers.
<nav> - Navigation Links
< nav class = "header__nav" >
< ul class = "header__nav-list" >
< li class = "header__nav-item" >
< a href = "#" class = "header__nav-link" > Crear cuenta </ a >
</ li >
< li class = "header__nav-item" >
< a href = "#" class = "header__nav-link" > Ingresar </ a >
</ li >
< li class = "header__nav-item" >
< a href = "#" class = "header__nav-link" > Mis compras </ a >
</ li >
</ ul >
</ nav >
Use <nav> for :
Primary navigation menu
Secondary navigation (categories, filters)
Breadcrumb navigation
Table of contents
Don’t use for :
Footer links (unless it’s a major navigation)
Social media links
Tags or keyword lists
Multiple Navigation Sections
A page can have multiple <nav> elements for different navigation contexts: <!-- Main navigation -->
< header >
< nav aria-label = "Main navigation" >
< ul >
< li >< a href = "/" > Home </ a ></ li >
< li >< a href = "/products" > Products </ a ></ li >
< li >< a href = "/about" > About </ a ></ li >
</ ul >
</ nav >
</ header >
<!-- Secondary navigation -->
< nav aria-label = "Categories" class = "categories-nav" >
< ul >
< li >< a href = "/electronics" > Electronics </ a ></ li >
< li >< a href = "/clothing" > Clothing </ a ></ li >
< li >< a href = "/books" > Books </ a ></ li >
</ ul >
</ nav >
<!-- Breadcrumb navigation -->
< nav aria-label = "Breadcrumb" >
< ol >
< li >< a href = "/" > Home </ a ></ li >
< li >< a href = "/products" > Products </ a ></ li >
< li >< a href = "/products/laptops" > Laptops </ a ></ li >
</ ol >
</ nav >
Use aria-label to distinguish between multiple navigation sections.
<main> - Primary Content
< main class = "main" id = "main-content" >
< section class = "hero" >
< h1 > Welcome to ML Store </ h1 >
< p > Find the best products at the best prices </ p >
</ section >
< section class = "products" >
<!-- Product catalog -->
</ section >
</ main >
Use <main> for :
The dominant/primary content of the page
Content unique to this page (not repeated across pages)
Important rules :
Only ONE <main> per page
Excludes content repeated across pages (header, footer, navigation)
Helps screen readers jump directly to main content
Can be a direct child of <body> or nested in other elements
Never use more than one <main> element in a document. This is a hard rule for valid HTML.
<section> - Thematic Grouping
< section class = "benefits" id = "benefits-section" >
< div class = "benefits__container" >
< h2 class = "benefits__title" > ¿Por qué elegirnos? </ h2 >
< div class = "benefits__grid" >
< article class = "benefits__item" >
< div class = "benefits__icon" > 🚚 </ div >
< h3 class = "benefits__item-title" > Envío gratis </ h3 >
< p class = "benefits__item-text" > En compras mayores a $299 </ p >
</ article >
< article class = "benefits__item" >
< div class = "benefits__icon" > 🔒 </ div >
< h3 class = "benefits__item-title" > Pago seguro </ h3 >
< p class = "benefits__item-text" > Todas las transacciones protegidas </ p >
</ article >
</ div >
</ div >
</ section >
Use <section> for :
Thematically related content
Chapters or tabbed content
Distinct parts of a page with their own heading
Characteristics :
Should generally have a heading (<h1>-<h6>)
Groups related content together
Has semantic meaning (unlike generic <div>)
<article> - Self-Contained Content
< article class = "product-card" >
< figure class = "product-card__figure" >
< img src = "laptop.jpg" alt = "Gaming Laptop" class = "product-card__image" />
</ figure >
< div class = "product-card__content" >
< span class = "product-card__category" > Electronics </ span >
< h3 class = "product-card__title" > Gaming Laptop Pro </ h3 >
< p class = "product-card__price" > $1,299.99 </ p >
< button type = "button" class = "product-card__btn" >
Add to Cart
</ button >
</ div >
</ article >
Use <article> for :
Blog posts
News articles
Product cards
Comments
Forum posts
Independent, self-contained content
Key question : Could this content be distributed independently (RSS feed, syndication)?
<section> vs <article>
When to Use Which
<section> : Thematic grouping of content
Part of a larger whole
Wouldn’t make sense on its own
Example: “Features” section on a landing page
<article> : Independent, self-contained content
Makes sense on its own
Could be syndicated or shared
Example: Blog post, product card, comment
<!-- SECTION: Groups related content -->
< section class = "testimonials" >
< h2 > Customer Reviews </ h2 >
<!-- ARTICLE: Each review is independent -->
< article class = "review" >
< h3 > Great product! </ h3 >
< p > I love this laptop... </ p >
</ article >
< article class = "review" >
< h3 > Excellent service </ h3 >
< p > Fast shipping... </ p >
</ article >
</ section >
<aside> - Complementary Content
< aside class = "sidebar" >
< section class = "sidebar__section" >
< h3 > Related Products </ h3 >
< ul >
< li >< a href = "#" > Wireless Mouse </ a ></ li >
< li >< a href = "#" > USB-C Hub </ a ></ li >
< li >< a href = "#" > Laptop Bag </ a ></ li >
</ ul >
</ section >
< section class = "sidebar__section" >
< h3 > Popular Categories </ h3 >
< ul >
< li >< a href = "#" > Electronics </ a ></ li >
< li >< a href = "#" > Fashion </ a ></ li >
< li >< a href = "#" > Home & Garden </ a ></ li >
</ ul >
</ section >
</ aside >
Use <aside> for :
Sidebars
Pull quotes
Advertisements
Related links
Additional information
Characteristics :
Content related to surrounding content but not essential
Could be removed without affecting the main content’s meaning
Often positioned to the side visually (but not required)
< footer class = "footer" id = "main-footer" >
< div class = "footer__container" >
< div class = "footer__grid" >
<!-- About column -->
< div class = "footer__column" >
< h4 class = "footer__column-title" > Sobre ML Store </ h4 >
< address class = "footer__address" >
< p > Tu tienda de confianza desde 2024 </ p >
< p > Contacto: [email protected] </ p >
</ address >
</ div >
<!-- Links column -->
< div class = "footer__column" >
< h4 class = "footer__column-title" > Enlaces útiles </ h4 >
< ul class = "footer__links" >
< li >< a href = "#" class = "footer__link" > Cómo comprar </ a ></ li >
< li >< a href = "#" class = "footer__link" > Métodos de pago </ a ></ li >
< li >< a href = "#" class = "footer__link" > Envíos </ a ></ li >
</ ul >
</ div >
</ div >
< hr class = "footer__divider" />
< div class = "footer__bottom" >
< small class = "footer__copyright" >
© 2024 ML Store. Todos los derechos reservados.
</ small >
</ div >
</ div >
</ footer >
Use <footer> for :
Page footer with copyright, legal links
Section or article footer
Author information
Related documents
Can contain :
Copyright information
Contact information (<address>)
Legal links (privacy policy, terms)
Social media links
Site map
Additional Semantic Elements
< figure class = "product-card__figure" >
< img
src = "laptop.jpg"
alt = "Gaming Laptop with RGB keyboard"
class = "product-card__image"
loading = "lazy"
/>
< figcaption > Dell XPS 15 - High-performance laptop </ figcaption >
</ figure >
Use <figure> for :
Images with captions
Code snippets
Diagrams
Illustrations
Embedded content
<address>
< address class = "footer__address" >
< p > ML Store Inc. </ p >
< p > 123 Commerce Street </ p >
< p > San Francisco, CA 94103 </ p >
< p > Email: < a href = "mailto:[email protected] " > [email protected] </ a ></ p >
< p > Phone: < a href = "tel:+15551234567" > +1 (555) 123-4567 </ a ></ p >
</ address >
Use <address> for :
Contact information
Physical addresses
Email addresses
Phone numbers
<time>
< article class = "blog-post" >
< h2 > New Product Launch </ h2 >
< p >
Published on
< time datetime = "2024-03-04T10:30:00Z" >
March 4, 2024 at 10:30 AM
</ time >
</ p >
</ article >
Use <time> for :
<mark>
< p > Search results for "laptop": </ p >
< p > Gaming < mark > Laptop </ mark > Pro - High-performance < mark > laptop </ mark > for gamers </ p >
Use <mark> for :
Highlighting text
Search result highlighting
Emphasizing relevant text
Complete Semantic Page Structure
Here’s how all semantic elements work together:
<! DOCTYPE html >
< html lang = "es" >
< head >
< meta charset = "UTF-8" />
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
< title > ML Store | Tu Tienda Online </ title >
</ head >
< body >
< header >
< nav >
<!-- Main navigation -->
</ nav >
</ header >
< main >
< section class = "hero" >
< h1 > Welcome </ h1 >
</ section >
< section class = "products" >
< h2 > Products </ h2 >
< article class = "product-card" >
< figure >
< img src = "..." alt = "..." />
< figcaption > Product name </ figcaption >
</ figure >
</ article >
</ section >
< aside class = "sidebar" >
<!-- Related content -->
</ aside >
</ main >
< footer >
< address >
<!-- Contact info -->
</ address >
</ footer >
</ body >
</ html >
Best Practices
Do
Use semantic elements for their intended purpose
Include only one <main> per page
Give sections meaningful headings
Use <article> for independent content
Nest elements logically
Don't
Don’t use <section> when <div> is more appropriate
Don’t skip heading levels
Don’t use semantic elements just for styling
Don’t nest <main> inside <article> or <section>
Don’t use multiple <main> elements