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 -->
<p>The symbol for classification is &ldquo;&sect;&rdquo;.</p>

<!-- Right -->
<p>The symbol for classification is "§".</p>

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>