Table of Contents

HTML Style Rules

Document Type

Use HTML5.

Always declare the document type as the first line in your document.

<!DOCTYPE html>

Protocol

Use HTTPS for embedded resources where possible.

Always use HTTPS for scripts unless each file is available via HTTPS.

// Wrong
<script src="http://api.pelagornis.com/..."></script>

// RIGHT
<script src="https://api.pelagornis.com/..."></script>

Close All HTML Elements

In HTML, you do not have to close all elements.

we strongly recommend closing all HTML elements.

// Wrong
<section>
  <p>Hello, Pelagornis.</p>
  <p>Pelagornis StyleGuide.</p>
</section>

// Right
<section>
  <p>Hello, Pelagornis.</p>
  <p>Pelagornis StyleGuide.</p>
</section>

Spaces and Equal Signs

Do not prefer spaces around HTML equals.

Without spaces, it’s easier to read, and you can better group an entity.

// Wrong
<a href="/signin">Sign In</a>

// Right
<a href="/signin">Sign In</a>

Semantics

Use the appropriate HTML.

The purposeful use of HTML can have a good impact on accessibility, reusability, and code efficiency.

// Wrong
<div onclick="navigateToSemantics();">Semantics</div>

// Right
<a href="/semantics">Semantics</a>

Entity References

Do not use entity references.

In HTML, entity references are unnecessary except for characters with special meanings (e.g., < and &) and control characters or “invisible” characters (e.g., indistinguishable spaces).

// Wrong The symbol for classification is &ldquo;&sect;&rdquo;. // Right The
symbol for classification is "§".

type Attributes

Omit type attributes for style sheets and scripts.

Do not use type attributes for style sheets (unless not using CSS) and scripts (unless not using JavaScript).

// Wrong
<link rel="stylesheet" href="/styles.css" type="text/css" />

// Right
<link rel="stylesheet" href="/styles.css" />

HTML Formatting Rules

Indentation

Indent by 2 spaces at a time.

Don’t use tabs or mix tabs and spaces for indentation.

<ul>
  <li>Home</li>
  <li>Opensource</li>
</ul>

Capitalization

Use only lowercase.

// Wrong
<a href="/">Home</a>

// Right
<a href="/">Home</a>

Trailing Whitespace

Remove trailing white spaces.

// Wrong
<p>Hello, World_</p>

// Right
<p>Hello, World</p>

General Formatting

Use a new line for every block, list, or table element, and indent every such child element.

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
</ul>

HTML Quotation Marks

we recommend quoting attribute values.

// Wrong
<a class="sign-in-button">Sign In</a>

// Right
<a class="sign-in-button">Sign In</a>

Modern HTML Features

HTML5 Semantic Elements

Use semantic HTML5 elements for better structure and accessibility.

<!-- Document structure -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Page Title</title>
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/about">About</a></li>
        </ul>
      </nav>
    </header>

    <main>
      <article>
        <header>
          <h1>Article Title</h1>
          <time datetime="2024-01-15">January 15, 2024</time>
        </header>
        <section>
          <h2>Section Title</h2>
          <p>Article content...</p>
        </section>
      </article>

      <aside>
        <h3>Related Links</h3>
        <ul>
          <li><a href="/related1">Related Article 1</a></li>
          <li><a href="/related2">Related Article 2</a></li>
        </ul>
      </aside>
    </main>

    <footer>
      <p>&copy; 2024 Company Name. All rights reserved.</p>
    </footer>
  </body>
</html>

Form Elements and Validation

Use modern form elements with proper validation.

<form novalidate>
  <fieldset>
    <legend>User Information</legend>

    <div class="form-group">
      <label for="email">Email Address</label>
      <input
        type="email"
        id="email"
        name="email"
        required
        autocomplete="email"
        aria-describedby="email-error"
      />
      <div id="email-error" class="error-message" role="alert"></div>
    </div>

    <div class="form-group">
      <label for="password">Password</label>
      <input
        type="password"
        id="password"
        name="password"
        required
        minlength="8"
        autocomplete="new-password"
        aria-describedby="password-help"
      />
      <div id="password-help" class="help-text">
        Password must be at least 8 characters long.
      </div>
    </div>

    <div class="form-group">
      <label for="age">Age</label>
      <input
        type="number"
        id="age"
        name="age"
        min="13"
        max="120"
        aria-describedby="age-help"
      />
      <div id="age-help" class="help-text">
        You must be at least 13 years old.
      </div>
    </div>

    <div class="form-group">
      <label for="country">Country</label>
      <select id="country" name="country" required>
        <option value="">Select a country</option>
        <option value="us">United States</option>
        <option value="ca">Canada</option>
        <option value="uk">United Kingdom</option>
      </select>
    </div>

    <div class="form-group">
      <fieldset>
        <legend>Newsletter Subscription</legend>
        <input type="radio" id="newsletter-yes" name="newsletter" value="yes" />
        <label for="newsletter-yes">Yes, subscribe me</label>

        <input type="radio" id="newsletter-no" name="newsletter" value="no" />
        <label for="newsletter-no">No, thanks</label>
      </fieldset>
    </div>

    <div class="form-group">
      <input type="checkbox" id="terms" name="terms" required />
      <label for="terms">
        I agree to the <a href="/terms" target="_blank">Terms of Service</a>
      </label>
    </div>

    <button type="submit">Create Account</button>
  </fieldset>
</form>

Media Elements

Use modern media elements with proper attributes.

<!-- Responsive images -->
<picture>
  <source media="(min-width: 800px)" srcset="large-image.jpg" />
  <source media="(min-width: 400px)" srcset="medium-image.jpg" />
  <img src="small-image.jpg" alt="Descriptive alt text" loading="lazy" />
</picture>

<!-- Video with multiple sources -->
<video controls preload="metadata" poster="video-poster.jpg">
  <source src="video.mp4" type="video/mp4" />
  <source src="video.webm" type="video/webm" />
  <track kind="captions" src="captions.vtt" srclang="en" label="English" />
  <p>Your browser doesn't support HTML5 video.</p>
</video>

<!-- Audio with multiple sources -->
<audio controls preload="metadata">
  <source src="audio.mp3" type="audio/mpeg" />
  <source src="audio.ogg" type="audio/ogg" />
  <p>Your browser doesn't support HTML5 audio.</p>
</audio>

Accessibility Guidelines

ARIA Labels and Roles

Use ARIA attributes to improve accessibility.

<!-- Navigation with ARIA -->
<nav role="navigation" aria-label="Main navigation">
  <ul>
    <li><a href="/" aria-current="page">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

<!-- Button with ARIA -->
<button
  type="button"
  aria-expanded="false"
  aria-controls="menu"
  aria-label="Toggle navigation menu"
>
  <span class="hamburger-icon" aria-hidden="true"></span>
  Menu
</button>

<!-- Modal dialog -->
<div
  role="dialog"
  aria-modal="true"
  aria-labelledby="modal-title"
  aria-describedby="modal-description"
>
  <h2 id="modal-title">Confirm Action</h2>
  <p id="modal-description">Are you sure you want to delete this item?</p>
  <button type="button" aria-label="Close dialog">×</button>
</div>

<!-- Form with ARIA -->
<div class="form-group">
  <label for="username">Username</label>
  <input
    type="text"
    id="username"
    name="username"
    required
    aria-describedby="username-error username-help"
    aria-invalid="false"
  />
  <div id="username-help" class="help-text">
    Username must be 3-20 characters long.
  </div>
  <div id="username-error" class="error-message" role="alert"></div>
</div>

Focus Management

Implement proper focus management for keyboard navigation.

<!-- Skip links -->
<a href="#main-content" class="skip-link">Skip to main content</a>

<!-- Focusable elements -->
<button type="button" tabindex="0">Focusable Button</button>
<input type="text" tabindex="0" placeholder="Focusable Input" />
<a href="/link" tabindex="0">Focusable Link</a>

<!-- Non-focusable elements -->
<div tabindex="-1">Non-focusable div</div>
<span tabindex="-1">Non-focusable span</span>

Screen Reader Support

Provide proper support for screen readers.

<!-- Hidden text for screen readers -->
<button type="button">
  <span class="icon" aria-hidden="true">🔍</span>
  <span class="sr-only">Search</span>
</button>

<!-- Live regions for dynamic content -->
<div aria-live="polite" aria-atomic="true" id="status-messages"></div>

<!-- Descriptive text -->
<img
  src="chart.jpg"
  alt="Sales increased by 25% from Q1 to Q2, reaching $2.5M in revenue"
/>

<!-- Complex images with long descriptions -->
<img
  src="infographic.jpg"
  alt="Detailed infographic showing market trends"
  longdesc="infographic-description.html"
/>

SEO Optimization

Meta Tags

Use comprehensive meta tags for SEO.

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <!-- Primary meta tags -->
  <title>Page Title - Company Name</title>
  <meta name="title" content="Page Title - Company Name" />
  <meta
    name="description"
    content="Brief description of the page content (150-160 characters)"
  />
  <meta name="keywords" content="keyword1, keyword2, keyword3" />
  <meta name="author" content="Author Name" />

  <!-- Open Graph / Facebook -->
  <meta property="og:type" content="website" />
  <meta property="og:url" content="https://example.com/page/" />
  <meta property="og:title" content="Page Title - Company Name" />
  <meta
    property="og:description"
    content="Brief description of the page content"
  />
  <meta property="og:image" content="https://example.com/image.jpg" />
  <meta property="og:site_name" content="Company Name" />

  <!-- Twitter -->
  <meta property="twitter:card" content="summary_large_image" />
  <meta property="twitter:url" content="https://example.com/page/" />
  <meta property="twitter:title" content="Page Title - Company Name" />
  <meta
    property="twitter:description"
    content="Brief description of the page content"
  />
  <meta property="twitter:image" content="https://example.com/image.jpg" />

  <!-- Additional SEO -->
  <meta name="robots" content="index, follow" />
  <meta name="googlebot" content="index, follow" />
  <link rel="canonical" href="https://example.com/page/" />
  <link rel="alternate" hreflang="en" href="https://example.com/page/" />
  <link rel="alternate" hreflang="es" href="https://example.com/es/page/" />
</head>

Structured Data

Implement structured data for better search results.

<!-- JSON-LD structured data -->
<script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "Company Name",
    "url": "https://example.com",
    "logo": "https://example.com/logo.png",
    "contactPoint": {
      "@type": "ContactPoint",
      "telephone": "+1-555-123-4567",
      "contactType": "customer service"
    },
    "sameAs": [
      "https://facebook.com/company",
      "https://twitter.com/company",
      "https://linkedin.com/company/company"
    ]
  }
</script>

<!-- Microdata -->
<article itemscope itemtype="https://schema.org/Article">
  <h1 itemprop="headline">Article Title</h1>
  <div itemprop="author" itemscope itemtype="https://schema.org/Person">
    <span itemprop="name">Author Name</span>
  </div>
  <time itemprop="datePublished" datetime="2024-01-15">January 15, 2024</time>
  <div itemprop="articleBody">
    <p>Article content...</p>
  </div>
</article>

Performance

Resource Loading

Optimize resource loading for better performance.

<!-- Preload critical resources -->
<link
  rel="preload"
  href="/fonts/main-font.woff2"
  as="font"
  type="font/woff2"
  crossorigin
/>
<link rel="preload" href="/css/critical.css" as="style" />
<link rel="preload" href="/js/critical.js" as="script" />

<!-- Prefetch resources for next page -->
<link rel="prefetch" href="/next-page.html" />
<link rel="prefetch" href="/images/hero-image.jpg" />

<!-- DNS prefetch for external domains -->
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
<link rel="dns-prefetch" href="//api.example.com" />

<!-- Lazy loading for images -->
<img src="image.jpg" alt="Description" loading="lazy" decoding="async" />

<!-- Defer non-critical scripts -->
<script src="/js/analytics.js" defer></script>
<script src="/js/chat-widget.js" defer></script>

<!-- Async for independent scripts -->
<script src="/js/third-party-widget.js" async></script>

Critical CSS

Inline critical CSS for faster rendering.

<head>
  <style>
    /* Critical CSS for above-the-fold content */
    body {
      margin: 0;
      font-family: Arial, sans-serif;
    }
    .header {
      background: #333;
      color: white;
      padding: 1rem;
    }
    .hero {
      background: #f0f0f0;
      padding: 2rem;
      text-align: center;
    }
  </style>

  <!-- Load non-critical CSS asynchronously -->
  <link
    rel="preload"
    href="/css/main.css"
    as="style"
    onload="this.onload=null;this.rel='stylesheet'"
  />
  <noscript><link rel="stylesheet" href="/css/main.css" /></noscript>
</head>

Semantic HTML

Content Structure

Use semantic elements to structure content properly.

<!-- Article structure -->
<article>
  <header>
    <h1>Article Title</h1>
    <div class="article-meta">
      <address class="author">
        By <a href="/author/john-doe">John Doe</a>
      </address>
      <time datetime="2024-01-15T10:30:00Z">January 15, 2024 at 10:30 AM</time>
    </div>
  </header>

  <div class="article-content">
    <p>Article introduction...</p>

    <section>
      <h2>Section Title</h2>
      <p>Section content...</p>

      <figure>
        <img src="image.jpg" alt="Descriptive alt text" />
        <figcaption>Image caption explaining the image</figcaption>
      </figure>
    </section>

    <section>
      <h2>Another Section</h2>
      <p>More content...</p>

      <blockquote cite="https://example.com/source">
        <p>This is a quote from an external source.</p>
        <footer>
          <cite>Source Name</cite>
        </footer>
      </blockquote>
    </section>
  </div>

  <footer>
    <div class="article-tags">
      <span>Tags:</span>
      <ul>
        <li><a href="/tag/web-development">Web Development</a></li>
        <li><a href="/tag/html">HTML</a></li>
      </ul>
    </div>
  </footer>
</article>

Create accessible navigation structures.

<!-- Breadcrumb navigation -->
<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="/">Home</a></li>
    <li><a href="/category">Category</a></li>
    <li aria-current="page">Current Page</li>
  </ol>
</nav>

<!-- Main navigation -->
<nav role="navigation" aria-label="Main navigation">
  <ul>
    <li><a href="/" aria-current="page">Home</a></li>
    <li>
      <a href="/products" aria-expanded="false" aria-haspopup="true">
        Products
      </a>
      <ul>
        <li><a href="/products/software">Software</a></li>
        <li><a href="/products/hardware">Hardware</a></li>
      </ul>
    </li>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

<!-- Pagination -->
<nav aria-label="Pagination">
  <ul>
    <li><a href="/page/1" aria-label="Previous page">«</a></li>
    <li><a href="/page/1">1</a></li>
    <li><a href="/page/2" aria-current="page">2</a></li>
    <li><a href="/page/3">3</a></li>
    <li><a href="/page/3" aria-label="Next page">»</a></li>
  </ul>
</nav>