Skip to content

Latest commit

 

History

History
266 lines (208 loc) · 7.46 KB

README.md

File metadata and controls

266 lines (208 loc) · 7.46 KB

HTML Guidelines

The below guidelines cover only specific scenarios and should not be considered exhaustive. For more general HTML guidelines visit Google's HTML Style guide.

Where there are differences our guidelines take precedence.

Table of contents

  1. Attributes
  2. Characters
  3. Commenting
  4. <div> or <span>
  5. Indenting
  6. Spacing & line character limits
  7. Self-closing element

← Back to homepage

Attributes

Don't

<input id="NewsletterModal-Email" class="newsletter-modal__textarea" autocapitalize="off" autocomplete="newsletter-address" autocorrect="off" name="contact[email]" placeholder="{{ 'general.newsletter_form.email_placeholder' | t }}" type="email" value="{{ customer.email }}" aria-labelledby="NewsletterModal-EmailLabel" data-show="true" js-newsletter="email">
>

Do

<input
  id="NewsletterModalEmail"
  class="newsletter-modal__textarea"
  autocapitalize="off"
  autocomplete="newsletter-address"
  autocorrect="off"
  name="contact[email]"
  placeholder="{{ 'general.newsletter_form.email_placeholder' | t }}"
  type="email"
  value="{{ customer.email }}"
  aria-labelledby="NewsletterModalEmailLabel"
  data-show="true"
  js-newsletter="email"
>
  • When an element has more than two attributes they should be stacked on newlines
  • They should follow this order:
    • id
    • class
    • {native}
    • aria-
    • data-
    • js-
  • {native} covers everything else, items within {native} should be in alphabetical order
  • This makes it easier for managing merges in Git
  • Make sure you trim trailing spaces after each line

🗒 Note: Be sure to follow the formatting; the trailing > should be on a newline with the attributes indented in two spaces.

Also

<div class="hero template-article__hero-image lazyload" data-bgset="{% render 'responsive-bg-image' with image: article.image %}"></div>

<div
  class="hero template-article__hero-image lazyload"
  data-bgset="{% render 'responsive-bg-image' with image: article.image %}"
>
</div>
  • Use multi-line attributes if as a single line it would exceed 80 characters
  • id values should be PascalCase
  • class values should follow BEM naming conventions
  • js- attributes should be camelCase

ꜛ Back to TOC

Don't

<div class='foo'></div>

Do

<div class="foo"></div>
  • Use quotations " HTML elements, not apostrophes '

ꜛ Back to TOC

Don't

<!-- Comment goes here -->

Do

{% comment %} Comment goes here {% endcomment %}
  • Do not use HTML comments, use the {% comment %} filter with whitespace operators
  • Liquid {% comment %} will not be rendered in the HTML
  • Use spaces inside the {% comment %} tag

ꜛ Back to TOC

<div> and <span> are often used interchangeably but there are specific use cases for each:

  • If the content is going to be displayed inline, use <span>
  • If you want the element to display block, on its own line, use <div>
  • If you're using CSS to change its display property, consider using the other

ꜛ Back to TOC

Don't

<p class="body-1">
{{ product.description }}
</p>

Do

<p class="body-1">
  {{ product.description }}
</p>
  • Indent two spaces inside each opening HTML element

ꜛ Back to TOC

Don't

<div id="Product" class="product" data-id="{{ product.id }}" js-product="container">
  <h1 class="product__title">{{ product.title }}</h1>
  <h2 class="product__subtitle">{{ product.type }}</h2>
  <button class="product__button product-button"><span class="product-button__icon">{% render 'icon-misc' with icon: 'plus' %}</span><span class="product-button__text">{{ 'products.product.add_to_cart' | t }}</span></button>
  <div class="product__content product-content">
    <p class="product-content__description">{{ product.description }}</p>
    <p class="product-content__shipping">{{ pages['shipping'].content | strip_html }}</p>
  </div>
  <div class="footer"><div class="footer__inner"><span class="footer__copy">{{ 'footer.copyright' | t }}</span><span class="footer__name">{{ shop.name }}</span><img src="{{ settings.logo | img_url: '300x' }}" alt="{{ settings.logo.alt }}"></div></div>
</div>

Do

<div
  id="Product"
  class="product"
  data-id="{{ product.id }}"
  js-product="container"
>
  <h1 class="product__title">{{ product.title }}</h1>
  <h2 class="product__subtitle">{{ product.type }}</h2>

  <button class="product__button product-button">
    <span class="product-button__icon">
      {% render 'icon-misc' with icon: 'plus' %}
    </span>

    <span class="product-button__text">
      {{ 'products.product.add_to_cart' | t }}
    </span>
  </button>

  <div class="product__content product-content">
    <p class="product-content__description">
      {{ product.description }}
    </p>

    <div class="product-content__shipping">
      {{ pages['shipping'].content }}
    </div>
  </div>

  <div class="footer">
    <div class="footer__inner">
      <span class="footer__copy">{{ 'footer.copyright' | t }}</span>
      <span class="footer__name">{{ shop.name }}</span>

      <img
        alt="{{ settings.logo.alt }}"
        src="{{ settings.logo | img_url: '300x' }}"
      >
    </div>
  </div>
</div>
  • Use common sense spacing to improve the readability of your code
  • Block-level elements should open onto a new line and indent
  • Inline-level elements should be written on a single line
  • Single line elements should be grouped together by type
  • Multi-line elements should have a newline between them
  • This guideline includes empty block-level elements, e.g. the following is correct:
<div
  class="article__image"
  data-bgset="{% render 'responsive-bg-image' with image: article.image %}"
  js-article="image"
></div>
  • Once you are writing something over multiple lines, each line should only have one attribute or value on it
  • If an attribute's value exceeds 80 characters then it should be split in the following format:
<div
  class="
    class-1
    class-2
    class-3
    class-4
  "
  data-handle="{{ product.handle }}"
  js-product="content"
>
  <!-- Content -->
</div>

Exceptions

  • Short block-level elements like <h1>, <li> or <title> can be displayed on a single line unless they're greater than 80 characters long
  • Inline-level elements greater than 80 characters long should follow multi-line rules

ꜛ Back to TOC

Don't

<img src="image.png" alt=""/>
<input class="foo" placeholder="Content"/>

Do

<img src="image.png" alt="">
<input class="foo" placeholder="Content">
  • The / in self-closing tags is obsolete, do not use it

ꜛ Back to TOC