forked from pixelunion/code-guide
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
2008 lines (1612 loc) · 76.6 KB
/
index.html
File metadata and controls
2008 lines (1612 loc) · 76.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
layout: default
---
<div class="heading" id="toc">
<h2>Table of contents</h2>
</div>
<div class="section toc">
<div class="col">
<h4><a href="#pxu">Shop Talk</a></h4>
<ul>
<li><a href="#pxu-golden-rule">The Golden Rule</a></li>
<li><a href="#pxu-browser-support">Browser Support</a></li>
<li><a href="#pxu-peer-review">Peer Review</a></li>
</ul>
</div>
<div class="col">
<h4><a href="#html">HTML</a></h4>
<ul>
<li><a href="#html-syntax">Syntax</a></li>
<li><a href="#html-doctype">HTML5 doctype</a></li>
<li><a href="#html-lang">Language attribute</a></li>
<li><a href="#html-encoding">Character encoding</a></li>
<li><a href="#html-ie-compatibility-mode">Internet Explorer compatibility mode</a></li>
<li><a href="#html-style-script">CSS and JavaScript includes</a></li>
<li><a href="#html-practicality">Practicality over purity</a></li>
<li><a href="#html-attribute-order">Attribute order</a></li>
<li><a href="#html-boolean-attributes">Boolean attributes</a></li>
<li><a href="#html-reducing-markup">Reducing markup</a></li>
<li><a href="#html-javascript">JavaScript generated markup</a></li>
</ul>
</div>
<div class="col">
<h4><a href="#liquid">Liquid</a></h4>
<ul>
<li><a href="#liquid-intro">An Introduction to Shopify</a></li>
<li><a href="#liquid-syntax">Syntax</a></li>
<li><a href="#liquid-whitespace">Whitespace in Expressions and Statements</a></li>
<li><a href="#liquid-variables">Variables</a></li>
<li><a href="#liquid-debugging">Debugging Tips</a></li>
</ul>
</div>
<div class="col">
<h4><a href="#sass">Sass</a></h4>
<ul>
<li><a href="#sass-syntax">Syntax</a></li>
<li><a href="#sass-selectors">Selectors</a></li>
<li><a href="#sass-nesting">Nesting</a></li>
<li><a href="#sass-variables">Variables</a></li>
<li><a href="#sass-includes-extends">@includes vs @extends</a></li>
<li><a href="#sass-comments">Comments</a></li>
<li><a href="#sass-media-queries">Media query placement</a></li>
<li><a href="#sass-single-declarations">Rules with single declarations</a></li>
<li><a href="#sass-shorthand">Shorthand notation</a></li>
<li><a href="#sass-classes">Classes</a></li>
<li><a href="#sass-organization">Organization</a></li>
<li><a href="#sass-maintainability">Maintainability</a></li>
<li><a href="#sass-declaration-order">Declaration order</a></li>
</ul>
</div>
</div>
<div class="section toc">
<div class="col">
<h4><a href="#javascript">JavaScript (ES6)</a></h4>
<ul>
<li><a href="#javascript-whitespace">Syntax</a></li>
<li><a href="#javascript-variables">Variables</a></li>
<li><a href="#javascript-comparison">Comparison</a></li>
<li><a href="#javascript-typecasting">Type casting</a></li>
<li><a href="#javascript-naming">Naming conventions</a></li>
<li><a href="#javascript-comments">Comments</a></li>
<li><a href="#javascript-destructuring">Destructuring</a></li>
<li><a href="#javascript-modules">Modules</a></li>
<li><a href="#javascript-strings">Strings</a></li>
<li><a href="#javascript-arrays">Arrays</a></li>
<li><a href="#javascript-functions">Functions</a></li>
<li><a href="#javascript-objects">Objects</a></li>
<li><a href="#javascript-classes">Classes</a></li>
<li><a href="#javascript-events">Events</a></li>
<li><a href="#javascript-jquery">jQuery</a></li>
</ul>
</div>
<div class="col">
<h4><a href="#coffee">CoffeeScript</a></h4>
<ul>
<li><a href="#coffee-code-layout">Code layout</a></li>
<li><a href="#coffee-imports">Module Imports</a></li>
<li><a href="#coffee-whitespace">Whitespace in Expressions and Statements</a></li>
<li><a href="#coffee-comments">Comments</a></li>
<li><a href="#coffee-naming">Naming Conventions</a></li>
<li><a href="#coffee-functions">Functions</a></li>
<li><a href="#coffee-strings">Strings</a></li>
<li><a href="#coffee-conditionals">Conditionals</a></li>
<li><a href="#coffee-looping">Looping and Comprehensions</a></li>
<li><a href="#coffee-annotations">Annotations</a></li>
<li><a href="#coffee-miscellaneous">Miscellaneous</a></li>
</ul>
</div>
<div class="col">
<h4><a href="#php">PHP</a></h4>
<ul>
<li><a href="#php-introduction">Introduction</a></li>
<li><a href="#php-quotes">Single and Double Quotes</a></li>
<li><a href="#php-indentation">Indentation</a></li>
<li><a href="#php-brace-style">Brace Style</a></li>
<li><a href="#php-function-guards">Function Guards</a></li>
<li><a href="#php-regular-expressions">Regular Expressions</a></li>
<li><a href="#php-spaces">Space Usage</a></li>
<li><a href="#php-sql-statements">Formatting SQL statements</a></li>
<li><a href="#php-database-queries">Database Queries</a></li>
<li><a href="#php-naming">Naming Conventions</a></li>
<li><a href="#php-self-explanatory">Self-Explanatory Flag Values for Function Arguments</a></li>
<li><a href="#php-ternary-operator">Ternary Operator</a></li>
<li><a href="#php-yoda-conditions">Yoda Conditions</a></li>
<li><a href="#php-miscellaneous">Miscellaneous</a></li>
</ul>
</div>
<div class="col">
<h4><a href="#git">Git</a></h4>
<ul>
<li><a href="#git-introduction">An introduction to Git</a></li>
<li><a href="#git-repos">Repo Naming</a></li>
<li><a href="#git-setup">Setup</a></li>
<li><a href="#git-branches">Branches and Pull Requests</a></li>
<li><a href="#git-commits">Commits</a></li>
<li><a href="#git-pushing">Pushing</a></li>
<li><a href="#git-merging">Merging</a></li>
<li><a href="#git-tagging">Tagging and Releasing</a></li>
</ul>
</div>
</div>
<div class="heading" id="pxu">
<h2>Shop Talk</h2>
</div>
<div class="section" id="pxu-golden-rule">
<div class="col">
<h2>Golden rule</h2>
<p>For additions or contributions to this Code Guide, please <a href="https://github.com/ShopPad/code-guide/issues/new">open an issue on GitHub</a>.</p>
</div>
<div class="col">
<blockquote>
<p>Every line of code should appear to be written by a single person, no matter the number of contributors.</p>
</blockquote>
</div>
</div>
<div class="section" id="pxu-browser-support">
<div class="col">
<h3>Browser Support</h3>
<ul>
<li>Internet Explorer 10+</li>
<li>Chrome 45+</li>
<li>Mobile Safari 8.4+</li>
<li>Firefox 41+</li>
<li>Safari 8+</li>
<li>Chrome for Android 45+</li>
<li>Android Browser 4.4.4+</li>
</ul>
<p>We do not "support" the following browsers:</p>
<ul>
<li>Opera</li>
<li>Anything not listed above</li>
</ul>
<p>Not supporting doesn't mean a broken website, it means a lack of testing.</p>
</div>
</div>
<div class="section" id="pxu-peer-review">
<div class="col">
<h3>Peer Review</h3>
<p>We don't release code that hasn't been peer reviewed. Whether it's a two line change to some CSS or a complete refactoring of a JavaScript function, your pull request will always be reviewed by one of your peers.</p>
<p>Since all of your code is written on a <a href="#git-branches">different branch</a> than master anyways, peer review is as simple as opening up a pull request and assigning it to somebody to review.<p>
<h4>The Exception</h4>
<p>The <em>only</em> exception to committing code that isn't up to the standards in this document is when working on an older theme. It's preferable to keep code consistent to the theme that you're working on even if that code isn't up to our current standards (within reason). It's important to document these decisions in your Pull Request.</p>
<p>If the theme still has shelf life (not going to be archived any time soon), create a new task detailing the changes that should be made to bring the theme up to our current standards.</p>
</div>
</div>
<div class="heading" id="html">
<h2>HTML</h2>
</div>
<div class="section" id="html-syntax">
<div class="col">
<h3>Syntax</h3>
<ul>
<li>Use soft tabs with two spaces—they're the only way to guarantee code renders the same in any environment.</li>
<li>Nested elements should be indented once (two spaces).</li>
<li>Always use double quotes, never single quotes, on attributes.</li>
<li>Don't include a trailing slash in self-closing elements—the <a href="http://dev.w3.org/html5/spec-author-view/syntax.html#syntax-start-tag">HTML5 spec</a> says they're optional.</li>
<li>Don’t omit optional closing tags (e.g. <code></li></code> or <code></body></code>).</li>
</ul>
</div>
<div class="col">
{% highlight html %}{% include html/syntax.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-doctype">
<div class="col">
<h3>HTML5 doctype</h3>
<p>Enforce standards mode and more consistent rendering in every browser possible with this simple doctype at the beginning of every HTML page.</p>
</div>
<div class="col">
{% highlight html %}{% include html/doctype.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-lang">
<div class="col">
<h3>Language attribute</h3>
<p>From the HTML5 spec:</p>
<blockquote>
<p>Authors are encouraged to specify a lang attribute on the root html element, giving the document's language. This aids speech synthesis tools to determine what pronunciations to use, translation tools to determine what rules to use, and so forth.</p>
</blockquote>
<p>Read more about the <code>lang</code> attribute <a href="http://www.w3.org/html/wg/drafts/html/master/semantics.html#the-html-element">in the spec</a>.</p>
<p>Head to Sitepoint for a <a href="http://reference.sitepoint.com/html/lang-codes">list of language codes</a>.</p>
</div>
<div class="col">
{% highlight html %}{% include html/lang.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-ie-compatibility-mode">
<div class="col">
<h3>IE compatibility mode</h3>
<p>Internet Explorer supports the use of a document compatibility <code><meta></code> tag to specify what version of IE the page should be rendered as. Unless circumstances require otherwise, it's most useful to instruct IE to use the latest supported mode with <strong>edge mode</strong>.</p>
<p>For more information, <a href="http://stackoverflow.com/questions/6771258/whats-the-difference-if-meta-http-equiv-x-ua-compatible-content-ie-edge-e">read this awesome Stack Overflow article</a>.</p>
</div>
<div class="col">
{% highlight html %}{% include html/ie-compatibility-mode.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-encoding">
<div class="col">
<h3>Character encoding</h3>
<p>Quickly and easily ensure proper rendering of your content by declaring an explicit character encoding. When doing so, you may avoid using character entities in your HTML, provided their encoding matches that of the document (generally UTF-8).</p>
</div>
<div class="col">
{% highlight html %}{% include html/encoding.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-style-script">
<div class="col">
<h3>CSS and JavaScript includes</h3>
<p>Per HTML5 spec, typically there is no need to specify a <code>type</code> when including CSS and JavaScript files as <code>text/css</code> and <code>text/javascript</code> are their respective defaults.</p>
<h4>HTML5 spec links</h4>
<ul>
<li><a href="http://www.w3.org/TR/2011/WD-html5-20110525/semantics.html#the-link-element">Using link</a></li>
<li><a href="http://www.w3.org/TR/2011/WD-html5-20110525/semantics.html#the-style-element">Using style</a></li>
<li><a href="http://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#the-script-element">Using script</a></li>
</ul>
</div>
<div class="col">
{% highlight html %}{% include html/style-script.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-practicality">
<div class="col">
<h3>Practicality over purity</h3>
<p>Strive to maintain HTML standards and semantics, but not at the expense of practicality. Use the least amount of markup with the fewest intricacies whenever possible.</p>
</div>
</div>
<div class="section" id="html-attribute-order">
<div class="col">
<h3>Attribute order</h3>
<p>HTML attributes should come in this particular order for easier reading of code.</p>
<ul>
<li><code>class</code></li>
<li><code>id</code>, <code>name</code></li>
<li><code>data-*</code></li>
<li><code>src</code>, <code>for</code>, <code>type</code>, <code>href</code></li>
<li><code>title</code>, <code>alt</code></li>
<li><code>aria-*</code>, <code>role</code></li>
</ul>
<p>Classes make for great reusable components, so they come first. Ids are more specific and should be used sparingly (e.g., for in-page bookmarks), so they come second.</p>
</div>
<div class="col">
{% highlight html %}{% include html/attribute-order.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-boolean-attributes">
<div class="col">
<h3>Boolean attributes</h3>
<p>A boolean attribute is one that needs no declared value. XHTML required you to declare a value, but HTML5 has no such requirement.</p>
<p>For further reading, consult the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#boolean-attributes">WhatWG section on boolean attributes</a>:</p>
<blockquote>
<p>The presence of a boolean attribute on an element represents the true value, and the absence of the attribute represents the false value.</p>
</blockquote>
<p>If you <em>must</em> include the attribute's value, and <strong>you don't need to</strong>, follow this WhatWG guideline:</p>
<blockquote>
<p>If the attribute is present, its value must either be the empty string or [...] the attribute's canonical name, with no leading or trailing whitespace.</p>
</blockquote>
<p><strong>In short, don't add a value.</strong></p>
</div>
<div class="col">
{% highlight html %}{% include html/boolean-attributes.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-reducing-markup">
<div class="col">
<h3>Reducing markup</h3>
<p>Whenever possible, avoid superfluous parent elements when writing HTML. Many times this requires iteration and refactoring, but produces less HTML. Take the following example:</p>
</div>
<div class="col">
{% highlight html %}{% include html/reducing-markup.html %}{% endhighlight %}
</div>
</div>
<div class="section" id="html-javascript">
<div class="col">
<h3>JavaScript generated markup</h3>
<p>Writing markup in a JavaScript file makes the content harder to find, harder to edit, and less performant. Avoid it whenever possible.</p>
</div>
</div>
<div class="heading" id="liquid">
<h2>Liquid</h2>
</div>
<div class="section" id="liquid-intro">
<div class="col">
<h3>In Introduction to Shopify</h3>
<p>Shopify is the only platform that we develop for that uses Liquid. Fortunately, they've done a great job on <a href="http://docs.shopify.com/themes">documentation</a> and almost all of the info that you need can be found there.</p>
<ul>
<li><a href="http://docs.shopify.com/themes/liquid-documentation/basics">Basics</a></li>
<li><a href="http://docs.shopify.com/themes/liquid-documentation/tags">Tags</a></li>
<li><a href="http://docs.shopify.com/themes/liquid-documentation/objects">Objects</a></li>
<li><a href="http://docs.shopify.com/themes/liquid-documentation/filters">Filters</a></li>
</ul>
<p>The <strong>Objects</strong> link above is almost certainly the most important resource available to you when writing code for Shopify. It contains every single object you might come across during development and all of the values attached to them.</p>
</div>
</div>
<div class="section" id="liquid-syntax">
<div class="col">
<h3>Syntax</h3>
<ul>
<li>Use soft tabs with two spaces—they're the only way to guarantee code renders the same in any environment.</li>
<li>Nested elements should be indented once (two spaces).</li>
</ul>
</div>
<div class="col">
{% highlight liquid %}{% include liquid/syntax.liquid %}{% endhighlight %}
</div>
</div>
<div class="section" id="liquid-whitespace">
<div class="col">
<h3>Whitespace in Expressions and Statements</h3>
<ul>
<li>Always surround these binary operators with a single space on either side:
<ul>
<li>assignment: <code>=</code></li>
<li>comparisons: <code>==</code>, <code>!=</code>, <code><</code>, <code>></code>, etc.</li>
<li>conditionals: <code>if</code>, <code>unless</code>, <code>and</code>, <code>or</code></li>
<li>filters: <code>|</code>, <code>minus:</code>, <code>divided_by:</code>, <code>strip</code></li>
<li>braces: <code>{% raw %}{{ }}{% endraw %}</code>, <code>{% raw %}{% %}{% endraw %}</code></li>
</ul>
</li>
</ul>
</div>
<div class="col">
{% highlight liquid %}{% include liquid/whitespace.liquid %}{% endhighlight %}
</div>
</div>
<div class="section" id="liquid-variables">
<div class="col">
<h3>Variables</h3>
<ul>
<li>always assign and capture variables in camelCase</li>
<li>only assign a variable if it:
<ol>
<li>is used more than once on a page</li>
<li>reduces line length and confusion where it gets outputted</li>
</ol>
</li>
</ul>
</div>
<div class="col">
{% highlight liquid %}{% include liquid/variables.liquid %}{% endhighlight %}
</div>
</div>
<div class="section" id="liquid-debugging">
<div class="col">
<h3>Debugging Tips</h3>
<ul>
<li>double check that Shopify is returning the correct data with the <code>json</code> filter</li>
<li>make sure the theme settings page isn't lying to you by creating a Theme Settings Javascript object</li>
</ul>
</div>
<div class="col">
{% highlight liquid %}{% include liquid/debugging.liquid %}{% endhighlight %}
</div>
</div>
<div class="heading" id="sass">
<h2>Sass</h2>
</div>
<div class="section" id="sass-syntax">
<div class="col">
<h3>Syntax</h3>
<ul>
<li>Use soft tabs with two spaces—they're the only way to guarantee code renders the same in any environment.</li>
<li>When grouping selectors, keep individual selectors to a single line.</li>
<li>Include one space before the opening brace of declaration blocks for legibility.</li>
<li>Place closing braces of declaration blocks on a new line.</li>
<li>Include one space after <code>:</code> for each declaration.</li>
<li>Each declaration should appear on its own line for more accurate error reporting.</li>
<li>End all declarations with a semi-colon, even the last one</li>
<li>Comma-separated property values should include a space after each comma (e.g., <code>box-shadow</code>).</li>
<li>Don't include spaces after commas <em>within</em> <code>rgb()</code>, <code>rgba()</code>, <code>hsl()</code>, <code>hsla()</code>, or <code>rect()</code> values. This helps differentiate multiple color values (comma, no space) from multiple property values (comma with space).</li>
<li>Prefix property values or color parameters with a leading zero (e.g., <code>0.5</code> instead of <code>.5</code> and <code>-0.5px</code> instead of <code>-.5px</code>).</li>
<li>Lowercase all hex values, e.g., <code>#fff</code>. Lowercase letters are much easier to discern when scanning a document as they tend to have more unique shapes.</li>
<li>Use shorthand hex values where available, e.g., <code>#fff</code> instead of <code>#ffffff</code>.</li>
<li>Quote attribute values in selectors, e.g., <code>input[type="text"]</code>. <a href="http://mathiasbynens.be/notes/unquoted-attribute-values#css">They’re only optional in some cases</a>, and it’s a good practice for consistency.</li>
<li>Avoid specifying units for zero values, e.g., <code>margin: 0;</code> instead of <code>margin: 0px;</code>.</li>
</ul>
<p>Questions on the terms used here? See the <a href="http://en.wikipedia.org/wiki/Cascading_Style_Sheets#Syntax">syntax section of the Cascading Style Sheets article</a> on Wikipedia.</p>
</div>
<div class="col">
{% highlight css %}{% include css/syntax.css %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-selectors">
<div class="col">
<h3>Selectors</h3>
<ul>
<li>Use classes over generic element tag or IDs for optimum rendering performance.</li>
<li>Prefer descriptive class names to descendent selectors.</li>
<li>Avoid using several attribute selectors (e.g., <code>[class^="..."]</code>) on commonly occuring components. Browser performance is known to be impacted by these.</li>
<li>Keep selectors short and strive to limit the number of elements in each selector to three.</li>
<li>Scope classes to the closest parent <strong>only</strong> when necessary (e.g., when not using prefixed classes).</li>
</ul>
<p>Additional reading:</p>
<ul>
<li><a href="http://markdotto.com/2012/02/16/scope-css-classes-with-prefixes/">Scope CSS classes with prefixes</a></li>
<li><a href="http://markdotto.com/2012/03/02/stop-the-cascade/">Stop the cascade</a></li>
</ul>
</div>
<div class="col">
{% highlight css %}{% include css/selectors.css %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-nesting">
<div class="col">
<h3>Nesting</h3>
<p>Nesting is very helpful to define element states such as active and hover, pseudo elements like before and after, and minimal child selectors that don't justify an additional class name.</p>
<ul>
<li>Avoid unnecessary nesting. Just because you can nest, doesn't mean you always should.</li>
<li>At a maximum, nesting should only go three levels deep.</li>
<li>Maximum amount of nested lines is 60. Your entire nest should be visible on a laptop's screen.</li>
</ul>
</div>
<div class="col">
{% highlight scss %}{% include css/nesting.scss %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-variables">
<div class="col">
<h3>Variables</h3>
<p>Variables in Sass are a powerful way to define values in one place that can be reused in multiple places in your project. They allow you to make changes from a central point without needing to use find and replace across multiple files and directories. <a href="http://thesassway.com/beginner/variable-naming">[ref]</a></p>
<ul>
<li>Names should be descriptive of purpose or function, not of the value.</li>
<li>Multi-word variables should be separated by hyphens.</li>
<li>Keep variables in a centralized file. For our Shopify themes, that's <code>_user-settings.scss</code>.</li>
</ul>
</div>
<div class="col">
{% highlight scss %}{% include css/sass-variables.scss %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-includes-extends">
<div class="col">
<h3>@include vs @extend</h3>
<p>First, some basics:</p>
<ul>
<li>The <strong>@extend</strong> directive tells Sass that one selector should inherit the styles of another selector.</li>
<li>The <strong>@include</strong> directive takes the name of a mixin and optionally arguments to pass to it, and includes the styles defined by that mixin into the current rule.</li>
</ul>
<h4>When to use @extend</h4>
<p>This should be your first plan of attack. Using an @extend limits customizability but produces a more efficient CSS file. Smaller is better.</p>
<h4>When to use @include</h4>
<p>If you need to overwrite declarations of an @extend or need to pass values to it then you'll want to set up a mixin and use @include instead. Mixins are powerful and are generally used to accomplish complicated or labor-intensive tasks. Some examples:</p>
<ul>
<li>wrapping content in another class / query (IE, retina, etc)</li>
<li><a href="http://bourbon.io/docs/#placeholder">placeholders</a></li>
<li>avoiding browser prefixes new CSS3 properties, such as:
<ul>
<li><a href="http://bourbon.io/docs/#animation">animations</a></li>
<li><a href="http://bourbon.io/docs/#transitions">transitions</a></li>
<li><a href="http://bourbon.io/docs/#flexbox">flexbox</a></li>
</ul>
</li>
</ul>
</div>
<div class="col">
{% highlight scss %}{% include css/includes_extends.scss %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-comments">
<div class="col">
<h3>Comments</h3>
<p>Code is written and maintained by people. Ensure your code is descriptive, well commented, and approachable by others. Great code comments convey context or purpose. Do not simply reiterate a component or class name.</p>
<p>Be sure to write in complete sentences for larger comments and succinct phrases for general notes.</p>
</div>
<div class="col">
{% highlight css %}{% include css/comments.css %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-media-queries">
<div class="col">
<h3>Media query placement</h3>
<p>Place media queries inside their respective selector. Don't have entire blocks of code dedicated to a single media query.</p>
<p>Feel free to create a media query mixin to simplify modifying your queries.</p>
</div>
<div class="col">
{% highlight scss %}{% include css/media-queries.scss %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-single-declarations">
<div class="col">
<h3>Single declarations</h3>
<p>In instances where a rule set includes <strong>only one declaration</strong>, consider removing line breaks for readability and faster editing. Any rule set with multiple declarations should be split to separate lines.</p>
<p>The key factor here is error detection—e.g., a CSS validator stating you have a syntax error on Line 183. With a single declaration, there's no missing it. With multiple declarations, separate lines is a must for your sanity.</p>
</div>
<div class="col">
{% highlight css %}{% include css/single-declarations.css %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-shorthand">
<div class="col">
<h3>Shorthand notation</h3>
<p>Strive to limit use of shorthand declarations to instances where you must explicitly set all the available values. Common overused shorthand properties include:</p>
<ul>
<li><code>padding</code></li>
<li><code>margin</code></li>
<li><code>font</code></li>
<li><code>background</code></li>
<li><code>border</code></li>
<li><code>border-radius</code></li>
</ul>
<p>Often times we don't need to set all the values a shorthand property represents. For example, HTML headings only set top and bottom margin, so when necessary, only override those two values. Excessive use of shorthand properties often leads to sloppier code with unnecessary overrides and unintended side effects.</p>
<p>The Mozilla Developer Network has a great article on <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties">shorthand properties</a> for those unfamiliar with notation and behavior.</p>
</div>
<div class="col">
{% highlight css %}{% include css/shorthand.css %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-classes">
<div class="col">
<h3>Class names</h3>
<ul>
<li>Keep classes lowercase and use dashes (not underscores or camelCase). Dashes serve as natural breaks in related class (e.g., <code>.btn</code> and <code>.btn-danger</code>).</li>
<li><a href="http://markdotto.com/2012/02/16/scope-css-classes-with-prefixes/">Scope CSS classes with prefixes</a>.</li>
<li>Avoid excessive and arbitrary shorthand notation. <code>.btn</code> is useful for <em>button</em>, but <code>.s</code> doesn't mean anything.</li>
<li>Keep classes as short and succinct as possible.</li>
<li>Use meaningful names; use structural or purposeful names over presentational.</li>
<li>Use <code>.js-*</code> classes to denote behavior (as opposed to style), but keep these classes out of your CSS.</li>
</ul>
</div>
<div class="col">
{% highlight css %}{% include css/class-names.css %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-organization">
<div class="col">
<h3>Organization</h3>
<p>Thanks to compilation and compression, we're able to organize styles into many small files without impacting the end user. Rules should be organized into small sets corresponding to the elements they style. Styles of unrelated elements should never be in the same file.</p>
<ul>
<li>Organize sections of code by component.</li>
<li>Develop a consistent commenting hierarchy.</li>
</ul>
</div>
</div>
<div class="section" id="sass-maintainability">
<div class="col">
<h3>Maintainability</h3>
<p>Consider the example on the right.</p>
<p>This rule obviously hides something, but it's not clear what it's hiding, or why. This code is unmaintainable, because its purpose is not obvious. Strive to write selectors and styles whose purpose and relationship is intuitive and obvious.</p>
</div>
<div class="col">
{% highlight scss %}{% include css/maintainability.scss %}{% endhighlight %}
</div>
</div>
<div class="section" id="sass-declaration-order">
<div class="col">
<h3>Declaration order</h3>
<p><strong>Recommended</strong> only. During the course of development this might not be realistic. Try to keep the following recommendations in mind.</p>
<p>Related property declarations should be grouped together following the order:</p>
<ol>
<li>Positioning</li>
<li>Box model</li>
<li>Typographic</li>
<li>Visual</li>
</ol>
<p>Positioning comes first because it can remove an element from the normal flow of the document and override box model related styles. The box model comes next as it dictates a component's dimensions and placement.</p>
<p>Everything else takes place <em>inside</em> the component or without impacting the previous two sections, and thus they come last.</p>
<p>For a complete list of properties and their order, please see <a href="http://twitter.github.com/recess">Recess</a>.</p>
</div>
<div class="col">
{% highlight css %}{% include css/declaration-order.css %}{% endhighlight %}
</div>
</div>
<div class="heading" id="javascript">
<h2>JavaScript (ES6)</h2>
</div>
<div class="section" id="javascript-whitespace">
<div class="col">
<h3>Syntax</h3>
<p>Use spaces only, with <strong>2 spaces</strong> per indentation level. Never mix tabs and spaces.</p>
<p>Try your best to limit all lines to a maximum of 80 characters. Do not ever go over 120.</p>
<p>Do not include trailing whitespace on any lines.</p>
<p>Use only unix-style newlines. <code>\n</code> not <code>\r\n</code>.</p>
<p>Use UTF-8 as the source file encoding.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-1.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Place <strong>1</strong> space before the leading brace.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-2.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Place <strong>1</strong> space before the opening parenthesis in control statements (<code>if</code>, <code>while</code> etc.). Place no space before the argument list in function calls and declarations.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-3.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Set off operators with spaces.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-4.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>End files with a single newline character.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-5.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Leave a blank line after blocks and before the next statement.</p>
<p>Use a single blank line within the bodies of methods or functions in cases where this improves readability (e.g., for the purpose of delineating logical sections).</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-6.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Do not use leading commas.</p>
<p>Use additional trailing commas.</p>
<p>This leads to cleaner git diffs. Also, transpilers like Babel will remove the additional trailing comma in the transpiled code which means you don't have to worry about the <a href="https://github.com/airbnb/javascript/blob/master/es5/README.md#commas">trailing comma problem</a> in legacy browsers.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-7.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Always use explicit semicolons.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-8.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use braces with all multi-line blocks.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-9.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>If you're using multi-line blocks with if and else, put else on the same line as your if block's closing brace.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/whitespace-10.js %}{% endhighlight %}
</div>
</div>
<div class="section" id="javascript-variables">
<div class="col">
<h3>Variables</h3>
<p>Use <code>const</code> for all of your references; avoid using <code>var</code>.</p>
<p>This ensures that you can't reassign your references (mutation), which can lead to bugs and difficult to comprehend code.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/variables-1.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>If you must mutate references, use <code>let</code> instead of <code>var</code>.</p>
<p><code>let</code> is block-scoped rather than function-scoped like <code>var</code>.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/variables-2.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Note that both <code>let</code> and <code>const</code> are block-scoped.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/variables-3.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use one <code>const</code>/<code>let</code> declaration per variable.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/variables-4.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Group all your <code>const</code>s and then group all your <code>let</code>s.</p>
<p>This is helpful when later on you might need to assign a variable depending on one of the previous assigned variables.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/variables-5.js %}{% endhighlight %}
</div>
</div>
<div class="section" id="javascript-comparison">
<div class="col">
<h3>Comparison Operators & Equality</h3>
<p>Use <code>===</code> and <code>!==</code> over <code>==</code> and <code>!=</code>.</p>
<p>Conditional statements such as the if statement evaulate their expression using coercion with the <code>ToBoolean</code> abstract method and always follow these simple rules:</p>
<ul>
<li>Objects evaluate to <code>true</code></li>
<li>Undefined evaluates to <code>false</code></li>
<li>Null evaluates to <code>false</code></li>
<li>Booleans evaluate to the value of the boolean</li>
<li>Numbers evaluate to false if <code>+0</code>, <code>-0</code>, or <code>NaN</code>, otherwise <code>true</code></li>
<li>Strings evaluate to false if an empty string <code>''</code>, otherwise <code>true</code></li>
</ul>
</div>
<div class="col">
{% highlight js %}{% include javascript/comparison-1.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use shortcuts when possible.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/comparison-2.js %}{% endhighlight %}
</div>
</div>
<div class="section" id="javascript-typecasting">
<div class="col">
<h3>Type Casting & Coercion</h3>
<p>Strings:</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/typecasting-1.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use <code>parseInt</code> for Numbers and <strong>always with a radix</strong> for type casting.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/typecasting-2.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Booleans:</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/typecasting-3.js %}{% endhighlight %}
</div>
</div>
<div class="section" id="javascript-naming">
<div class="col">
<h3>Naming Conventions</h3>
<p>Avoid single letter names. Be descriptive with your naming.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/naming-1.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use camelCase when naming objects, functions, and instances.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/naming-2.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use PascalCase when naming constructors or classes.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/naming-3.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use a leading underscore <code>_</code> when naming private properties or methods.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/naming-4.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Don't save references to <code>this</code>. Use arrow functions or <code>Function#bind</code>.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/naming-5.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>If your file exports a single class, your filename should be exactly the name of the class.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/naming-6.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use camelCase when you export-default a function. Your filename should be identical to your function's name.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/naming-7.js %}{% endhighlight %}
</div>
</div>
<div class="section" id="javascript-comments">
<div class="col">
<h3>Comments</h3>
<p>Use <code>/** ... */</code> for multi-line comments. Include a description, specify types and values for all parameters and return values.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/comments-1.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Use <code>//</code> for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/comments-2.js %}{% endhighlight %}
</div>
</div>
<div class="section">
<div class="col">
<p>Prefixing your comments with <code>FIXME</code> or <code>TODO</code> helps other developers quickly understand if you're pointing out a problem that needs to be revisited, or if you're suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable.</p>
<p>Use <code>// FIXME:</code> to annotate problems.</p>
<p>Use <code>// TODO:</code> to annotate solutions to problems.</p>
</div>
<div class="col">
{% highlight js %}{% include javascript/comments-3.js %}{% endhighlight %}
</div>
</div>