---
# System prepended metadata

title: Coding Guidelines

---

# Coding Guidelines

# CSS
=====================================================================
## CSS 1
Avoid using more than 2 levels of nesting

#### Don't
```
.selector {
  .level-2 {
    .level-3 {
      .child-1 {}

      .child-2 {}
    }
  }
}
```


#### Do
```
.selector {
  .level-3 .child-1 {}
  .level-3 .child-2 {}
}
```
=====================================================================


=====================================================================
## CSS 2
Use nested media queries

#### Don't
```
.selctor1 {}
.selctor2 {}
.selctor3 {}

@media (max-width) {
  .selctor1 {}
  .selctor2 {}
  .selctor3 {}
}

```


#### Do
```
.selctor1 {
  @media (max-width) {}
}

.selctor2 {
  @media (max-width) {}
}

.selctor3 {
  @media (max-width) {}
}
```
=====================================================================


=====================================================================
## CSS 3
Group rules by meaning i.e. fonts, colors, size, position

#### Don't
```
  .selector {
    position: absolute;
    font-size: 14px;
    background-color: red;
    height: 50%;
    top: 50%;
    line-height: 1.3;
    left: 50%;
    color: blue;
    width: 50;
  }
```


#### Do
```
  .selector {
    width: 50%;
    height: 50%;
    position: absolute;
    top: 50%;
    left: 50%;
    font-size: 14px;
    line-height: 1.3
    color: blue;
    background-color: red;
  }
```
=====================================================================


=====================================================================
## CSS 4
Use shorthand rules 

#### Don't
```
  .selector {
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 50px;
    padding-left: 10px;
  }
```


#### Do
```
  .selector {
    .padding: 10px 20px 50px 10px;
  }
```
=====================================================================


=====================================================================
## CSS 5
Use hex instead of rgb

#### Don't
```
  .selector {
    .color: rgb(255, 255, 255);
  }
```


#### Do
```
  .selector {
    .color: #000
  }
```
=====================================================================


=====================================================================
## CSS 6
Comma separated selectors on new lines

#### Don't
```
  .selector1, .selecto2, .selector3, .selector4 {}
```


#### Do
```
.selector1, 
.selecto2, 
.selector3, 
.selector4 {}
```
=====================================================================

=====================================================================
## CSS 7
Use global or local variables to avoid repetition

#### Don't
```
  .selector1 {
    color: #1e1e1e;
  }

  .selector2 {
    color: #1e1e1e;
  }

  .selector3 {
    color: #1e1e1e;
  }
```


#### Do
```
  $formLabelGray: '#1e1e1e';

  .selector1 {
    color: formLabelGray;
  }

  .selector2 {
    color: formLabelGray;
  }

  .selector3 {
    color: formLabelGray;
  }
```
=====================================================================

=====================================================================
## CSS 8
Use single quotes

#### Don't
```
  .selector1 {
    background-image: url("path-to-file")
  }
```


#### Do
```
  .selector1 {
    background-image: url('path-to-file')
  }
```
=====================================================================

=====================================================================
## CSS 9
Use stateful selectors

#### Don't
```
  .active {}
  .clicked {}
  .hidden {}
```


#### Do
```
  .is-active {}
  .is-clicked {}
  .is-hidden {}
```
=====================================================================

=====================================================================
## CSS 10
Add trailing semicollons

#### Don't
```
  .selector {
    color: red;
    background-color: blue;
    display: block
  }
```


#### Do
```
  .selector {
    color: red;
    background-color: blue;
    display: block;
  }
```
=====================================================================









# Liquid
=====================================================================
## Liquid 1
Use {% render %} instead of {% include %}

#### Don't 
```
{% include 'icon-misc', icon: 'search', colour: 'red' %}
```

#### Do
```
{% render 'icon-misc' with icon: 'search', colour: 'red' %}
```
=====================================================================


=====================================================================
## Liquid 2
Break to multiple lines when snippets have more than 2 params or the whole snippet goes over 80 characters

#### Don't
```
{% render 'social-sharing' with share_title: product.title, share_permalink: product.url,
share_image: product.featured_image %}
```

#### Do
```
{% render 'social-sharing' with
  share_image: product.featured_image,
  share_permalink: product.url,
  share_title: product.title,
%}
```
=====================================================================


=====================================================================
## Liquid 3
Use {% break %} and {% continue %} to exit out of a loop iteration early and to break out of the loop 

```
{% for tag in product.tags %}
  {% if tag != 'value' %}
    {% continue %}
  {% endif %}

  {% render 'tag-snippet' %}

  {% break %}
{% endfor %}
```
=====================================================================


=====================================================================
## Liquid 4
Add how-to-use comments for liquid snippets at the top of the file
```
{% comment %}
Usage: In your liquid template file, copy the following line
- {% render 'responsive-image' with image: featured_image, image_class: "css-class", wrapp
er_class: "wrapper-css-class", max_width: 700, max_height: 800 %}
{% endcomment %}
```
=====================================================================


=====================================================================
## Liquid 5
- In areas where the client can customize the content, do not assume that they will want to display every part of a section's settings
- Wrap each setting in a {% if %} to hide it if no content is entered
- Use != '' rather than {% if condition %} or != blank as it is more reliable, it is possible for a setting to exist if it previously had a value
- When testing make sure the section does not appear visually broken, the client will expect it to work with missing settings

#### Don't
```
{% for block in section.blocks %}
  {% assign _block = block.settings %}
  <div class="block">
    <img src="{{ _block.image | img_url: '2000x' }}" alt="{{ _block.image.alt }}">

    <h2 class="block__title">{{ _block.title }}</h2>

    <div class="block__text rte">{{ _block.text }}</div>
    <a class="block__button" href="{{ _block.button_url }}">
      {{ _block.button_text }}
    </a>
  </div>
{% endfor %}
```

#### Do
```
{% for block in section.blocks %}
  {% assign _block = block.settings %}
  <div class="block">
    {% if _block.image != '' %}
      <img
        alt="{{ _block.image.alt }}"
        src="{{ _block.image | img_url: '2000x' }}"
      >
  {% endif %}

  {% if _block.title != '' %}
    <h2 class="block__title">{{ _block.title }}</h2>
  {% endif %}

  {% if _block.text != '' %}
    <div class="block__text rte">
      {{ _block.text }}
    </div>
  {% endif %}

  {% if _block.button url != '' and _block.button_text != '' %}
    <a class="block__button" href="{{ _block.button_url }}">
      {{ _block.button_text }}
    </a>
  {% endif %}

  </div>
{% endfor %}
```
=====================================================================


=====================================================================
## Liquid 6
Don't use variable names that are already allocated in Shopify

#### Don't
```
{% assign section = section.settings %}
```

#### Do
```
{% assign _section = section.settings %}
```
=====================================================================


=====================================================================
## Liquid 7
Hoist settings variables in _section and _block

#### Don't 
```
{% if section.settings.main_image != blank %}
  <img src="{{- section.settings.main_image.src -}}" alt="{{- section.settings.main_image.alt -}}">
{% endif %}
```

#### Do
```
{% assign _section = section.settings %}
{% assign main_image = _section.main_image %}
{% assign section_title = _section.title %}

{% if main_image != blank %}
  <img src="{{- main_image.src -}}" alt="{{- main_image.alt -}}">
{% endif %}
```
=====================================================================


=====================================================================
## Liquid 8
Don't use multiple inline if statements

#### Don't 
```
<div class="row {% if section.settings.width == 'full' or section.settings.display == 'ful
l' %}row--full-width{% endif %} {% if is_hidden %}is-hidden{% endif %}"></div>
```

#### Do
```
{% if section.settings.width == 'full' or section.settings.display == 'full' %}
  {% assign row_class = 'row--full-width' %}
{% endif %}

<div
  class="
    row
    {{ row_class }}
    {% if is_hidden %}is-hidden{% endif %}
  "
>
  <!-- Content -->
</div>
```
=====================================================================


=====================================================================
## Liquid 9
Use proper indenting for nested code

#### Don't 
```
{% if variable %}
<h1>{{ product.title }}</h1>
{% endif %}
``` 

#### Do
```
{% if variable %}
  <h1>{{ product.title }}</h1>
{% endif %}
```
=====================================================================


=====================================================================
## Liquid 10
Spacing and line character limits

- Add spaces inside each object and tag
- Add spaces around filters
- Separate blocks of Liquid code with a newline
- Opening {% if %} tags should be on separate lines
- {% if %} tags with more than two filters and exceeding 80 characters should be split
  onto multiple lines
- {% assign %} tags with more than two filters and exceeding 80 characters should be
  broken up over multiple lines and indented
- Once you are writing something over multiple lines, each line should only have one
  attribute or value on it


#### Don't
```
{% if template contains 'search' or template contains 'account' or template contains 'cust
omer' or template contains 'cart' %}<meta name="robots" content="noindex, nofollow">{% end
if %}
{% assign sanitized_var = string|downcase|split: '/'|last|remove:'<p>'|remove:'</p>'|money
_with_currency %}
{%if variable%}<h1 class="product__title">{{ product.title }}</h1>
<div class="product__price product__price--large money subtitle-1">{{ product.price | mo
ney }}</div>{% else %}<h2 class="product__title">{{ product.title }}</h2>{%endif%}
```

#### Do
```
{% if
  template contains 'search' or
  template contains 'account' or
  template contains 'customer' or
  template contains 'cart'
%}
  <meta content="noindex, nofollow" name="robots">
{% endif %}

{% assign sanitized_variable = string |
  downcase |
  split: '/' |
  last |
  remove:'<p>' |
  remove:'</p>' %} |
  money_with_currency
%}

{% if variable %}
  <h1 class="product__title">{{ product.title }}</h1>

  <div
    class="
      product__price
      product__price--large
      money
      subtitle-1
    "
  >
  {{ product.price | money }}
  </div>
{% else %}
  <h2 class="product__title">{{ product.title }}</h2>
{% endif %}
```
=====================================================================









# Javascript
=====================================================================
## JS 1
Write explicit code

#### Don't
```
  // implicitly convert to integer
  const dataIndex = +item.dataset.index;
```


#### Do
```
  // explicitly convert to integer
  const dataIndex = parseInt(item.dataset.index);
```
=====================================================================

=====================================================================
## JS 2
Add comments even on simple pieces of code

#### Don't
```
function sumTwoIntegers(a, b) {
  return a + b;
}
```


#### Do
```
/**
 * Return the sum of two integers
 * @param {Integer} a
 * @param {Integer} b
 * @returns Integer
 */
function sumTwoIntegers(a, b) {
  return a + b;
}
```
=====================================================================

=====================================================================
## JS 3
Use full name variables

#### Don't
```
  const accPass = '...';
```


#### Do
```
  const accountPassword = '...';
```
=====================================================================

=====================================================================
## JS 4
Always null check

#### Don't
```
  const item = document.querySelector(selector);
  item.classList.add('class');
```


#### Do
```
  const item = document.querySelector(selector);
  if (item !== null) {
    item.classList.add('class');
  }
```
=====================================================================

=====================================================================
## JS 5
Hoist variables at the top of a js module

#### Don't
```
const var1 = '';
function useVar1() {
  return var1;
}

const var2 = '';
function useVar2() {
  return var2;
}

const var3 = '';
function useVar3() {
  return var3;
}
```


#### Do
```
const var1 = '';
const var2 = '';
const var3 = '';

function useVar1() {
  return var1;
}

function useVar1() {
  return var2;
}

function useVar1() {
  return var3;
}
```
=====================================================================

=====================================================================
## JS 6
Define long conditions as variables

#### Don't
```
  if (window.width > 767 && window.height > 600 && window.scrollY > section.offset.top) {
    ...
  }
```


#### Do
```
  const isDevice = window.width > 767 && window.height > 600;
  const isSectionInView = window.scrollY > section.offset.top;

  if (isDevice && isSectionInView) {
    ...
  }
```
=====================================================================

=====================================================================
## JS 7
Always leave trailing commas

#### Don't
```
const object = {
  prop: 'value',
  prop2: 'value2',
  prop3: 'value3'
}
```


#### Do
```
const object = {
  prop: 'value',
  prop2: 'value2',
  prop3: 'value3',
}
```
=====================================================================

=====================================================================
## JS 8
Use arrow functions whenever it's possible and makes sense to do so

#### Do
```
 array.map(item => {
   ...
 })

 const sumTwoIntegers = (a, b) => {
   return a + b;
 }
```
=====================================================================

=====================================================================
## JS 9
Use stateful naming for stateful variables

#### Don't
```
  const mobile = window.width < 767;
  const children = item.children.length;
```


#### Do
```
  const isMobile = window.width < 767;
  const hasChildren = item.children.length;
```
=====================================================================

=====================================================================
## JS 10
Brake multiple methods on their own line

#### Don't
```
  array.map(item => item.props).sort().reverse();
```


#### Do
```
  array
    .map(item => item.props)
    .sort()
    .reverse();
```
=====================================================================