-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.html
1385 lines (1356 loc) · 128 KB
/
index.html
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<title>Rapid Workflow: Using modern tools to build modern webapps - </title>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style type="text/css">
q { quotes: "“" "”" "‘" "’"; }
</style>
<style type="text/css">
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
</style>
<link rel="stylesheet" href="stylesheets/screen.css">
<link href='http://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<header>
<h1 class="tagline letterpress"><strong class="uppercase">Rapid</strong> Workflow</h1>
<h1 class='sub-tagline'>Using modern tools to build modern <strong class="uppercase tagline-accent">webapps</strong></h1>
</header>
<div id="menu">
<a href="#">Github</a>
<a href="#">How To Code</a>
</div>
<nav id="TOC">
<ul>
<li><a href="#preface">Preface</a></li>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#setting-up">Setting up</a><ul>
<li><a href="#what-is-a-css-preprocessor">What is a CSS preprocessor?</a></li>
<li><a href="#why-use-a-css-preprocessor">Why use a CSS preprocessor?</a></li>
<li><a href="#what-is-sass">What is Sass?</a></li>
<li><a href="#what-is-compass">What is Compass?</a></li>
<li><a href="#twitter-bootstrap-not-just-a-css-framework">Twitter Bootstrap: Not just a CSS framework!</a></li>
<li><a href="#setting-up-for-development">Setting Up For Development</a><ul>
<li><a href="#installing-ruby">Installing Ruby</a></li>
<li><a href="#installing-compass-and-sass">Installing Compass and Sass</a></li>
<li><a href="#installing-twitter-bootstrap">Installing Twitter Bootstrap</a></li>
<li><a href="#alternate-install">Alternate Install</a></li>
</ul></li>
<li><a href="#workflow-alternatives">Workflow Alternatives</a><ul>
<li><a href="#give-me-a-gui-please">Give me a GUI please!</a></li>
<li><a href="#scout">Scout</a></li>
<li><a href="#commercial-gui">Commercial GUI</a></li>
</ul></li>
<li><a href="#yeoman">Yeoman</a></li>
<li><a href="#exercises">Exercises</a></li>
<li><a href="#summary">Summary</a></li>
</ul></li>
<li><a href="#introduction-to-compass-and-sass">Introduction to Compass and Sass</a><ul>
<li><a href="#using-compass-to-create-a-project">Using Compass to Create a Project</a></li>
<li><a href="#a-sandbox-to-play-in">A Sandbox to Play In</a></li>
<li><a href="#compass-configuration">Compass Configuration</a></li>
<li><a href="#sass">Sass</a><ul>
<li><a href="#variables">Variables</a></li>
<li><a href="#nesting">Nesting</a></li>
<li><a href="#mixins">Mixins</a></li>
<li><a href="#placeholders">Placeholders</a></li>
<li><a href="#structure">Structure</a><ul>
<li><a href="#partials-and-imports">Partials and Imports</a></li>
<li><a href="#what-are-partials">What are partials?</a></li>
</ul></li>
</ul></li>
<li><a href="#summary-1">Summary</a></li>
</ul></li>
<li><a href="#yeoman-1">Yeoman</a><ul>
<li><a href="#what-is-yeoman">What is Yeoman?</a></li>
<li><a href="#yo">Yo</a><ul>
<li><a href="#installing-generators">Installing Generators</a></li>
</ul></li>
<li><a href="#grunt">Grunt</a><ul>
<li><a href="#package.json">package.json</a></li>
<li><a href="#gruntfile">Gruntfile</a></li>
<li><a href="#grunt-init">Grunt Init</a></li>
<li><a href="#image-optimization">Image Optimization</a></li>
<li><a href="#going-further">Going Further</a></li>
</ul></li>
<li><a href="#bower">Bower</a><ul>
<li><a href="#finding-and-installing-packages">Finding and installing packages</a></li>
</ul></li>
</ul></li>
<li><a href="#yeoman-custom-generators">Yeoman Custom Generators</a><ul>
<li><a href="#yeomans-chain-of-execution">Yeoman’s <q>chain of execution</q></a></li>
<li><a href="#another-simple-generator">Another Simple Generator</a><ul>
<li><a href="#code-walkthrough">Code Walkthrough</a></li>
</ul></li>
<li><a href="#generator-tests">Generator Tests</a></li>
</ul></li>
<li><a href="#unicorn">Unicorn</a></li>
</ul>
</nav>
<section class="level1" id="preface">
<h1><a href="#TOC">Preface</a></h1>
<p>In this book we’ll be covering rapid workflows that utilize modern tooling from the perspective of the front-end developer, or <em>rapid prototyper</em> (although designers, managers, and anyone who needs to build web sites efficiently might want to read too). This approach uses cutting edge front-end tooling to achieve amazingly rapid developer workflow. While we respect that you’ve likely aready developed you’re own personal favorite workflow rituals, we will attempt to persuade you that there may be sexier approaches you should add to your repetoire.</p>
<p>The pace of the book will be quite fast as we’ll favor brevity over long winded explanations so we can dig deeper in to <q>doing</q>. Therefore, we’ll be making heavy use of web links to places to get more detailed coverage on topics we might seem to breeze past.</p>
<p><strong>Programming Language and Syntaxes</strong></p>
<p>Most of the examples will use some type of language or syntax familiar to many front-end developers:</p>
<ul>
<li>HTML, CSS, JavaScript, etc.</li>
<li>Command line</li>
</ul>
<p>But we will also be using some tool-specific syntaxes like:</p>
<ul>
<li><a href="http://compass-style.org/">Compass</a> and <a href="sass-lang.com">Sass</a> (the .scss version)</li>
<li>Tool specific syntaxes (e.g. <a href="http://gruntjs.com/">Grunt</a>, <a href="http://bower.io/">Bower</a>, <a href="http://yeoman.io/">Yeoman</a>, etc.)</li>
</ul>
<p><strong>Assumptions</strong></p>
<p>This book assumes experience with core web technologies like HTML, CSS, and JavaScript.</p>
<p><strong>Resources</strong></p>
<p>I’ve generally listed any resources as clickable web links that you can learn more from, or, as links to where you might purchase the book that I’m referencing.</p>
<p><strong>Line breaks in code</strong></p>
<p>I’ve taken the liberty of purposely wrapping long lines that won’t fit within the width of the page.</p>
<p><strong>Contributions</strong></p>
<p>I am definitely open to collaborative authorship (hey, I did put it on github!), provided that other authors follow the general style and spirit of the book. At some point, I’ll try to define this all in a more concrete way. If you do want to contribute, you’ll probably want to have a good look at the commented Makefile, and also notice the use of <q>extra lines</q> between code samples. I’ve managed to find workarounds for the somewhat finicky pandoc/docbook tool-chain (and I’m thankful that it works at all since these tools really make life so much easier!)</p>
<p><strong>Special acknowledgement</strong></p>
<p><a href="http://addyosmani.com/blog/">Addy Osmani</a> has made many community contributions in the area developer education and has encouraged others to do the same. His contributions are generally open source, and, for example, I looked at the build process he used in his <a href="http://addyosmani.com/resources/essentialjsdesignpatterns/book/">Essential JS Design Patterns</a> book, and shamelessly <em>lifted</em> the pandoc build process we’re using for this book!</p>
<a id="introduction"></a>
</section>
<section class="level1" id="introduction">
<h1><a href="#TOC">Introduction</a></h1>
<p><strong>What is <q>Rapid Workflow</q>?</strong></p>
<p>Rapid Workflow encompasses all of the activities that allow you to rapidly develop the front-end of a web site or SPA (single-page app for the uninitiated).</p>
<p>Frameworks like <a href="http://html5boilerplate.com/">HTML5 Boilerplate</a>, <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>, and Zurb’s <a href="http://foundation.zurb.com/">Foundation</a> make it ridiculously easy to quickly put together acceptable <q>first draft</q> web pages. Even more full-blown workflow tools like <a href="http://yeoman.io/">Yeoman</a> can help us to—not just rapidly author web pages—but also update libraries, perform image optimizations, compression, minification, deployment, etc.</p>
<p>Once we’ve got an initial version of our web site, we can choose to iterate further, fully customizing it, or, scrap the whole idea and go back to the drawing board. The ability for lean start-ups to <a href="http://www.canrockventures.com/fail-often-fail-fast-fail-cheap/"><q>fail-fast</q></a>, pivot, adapt, get to market fast, etc., are all <a href="http://www.businessweek.com/stories/2007-06-24/fail-fast-fail-cheap">key</a> factors to success. The rapid workflow approach we’re about to discuss provides guidance on how to use modern tooling to cope with the time sensitive realities of today.</p>
<p><strong>Other Information on Rapid Workflow</strong></p>
<p>While we’ll be looking specifically at modern tooling for the front-end developer, there are some interesting and related resources regarding the general notion of improved development workflow that you might want to look at:</p>
<ul>
<li><p>Erica Heinz gave a nice presentation on utilizing rapid prototyping which is quite persuasive. Here are her <a href="https://speakerdeck.com/ericaheinz/rapid-prototyping-rough-to-ready">slides</a>. Rapid prototyping is akin to the rapid workflow approach we’ll be discussing, and so many of her points are applicable.</p></li>
<li><p>Jeff Gothelf and Josh Seiden are advocating an approach to UX which they call <a href="http://uxdesign.smashingmagazine.com/2011/03/07/lean-ux-getting-out-of-the-deliverables-business/">LeanUX</a>. Also see these <a href="http://www.slideshare.net/jgothelf/lean-ux-getting-out-of-the-deliverables-business">slides</a>.</p></li>
<li><p>Here’s a nice <a href="http://www.slideshare.net/jjeffryes/rapid-and-responsive-skip-the-wireframe">slide-deck</a> which proposes ditching wireframing altogether to instead use <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a> to prototype a responsive web site.</p></li>
<li><p>The blogs of <a href="http://addyosmani.com/blog/">Addy Osmani</a> and <a href="http://www.paulirish.com/">Paul Irish</a> both have a large number of articles related to improved developer workflow.</p></li>
</ul>
<p><strong>Standing on the shoulders of giants</strong></p>
<p>Every front-end developer has that perfect combination of tools and libraries that he or she already uses to improve their workflow. Sometimes its that special combination of plugins to trick out their favorite editor or IDE (e.g. the perfect Vim, Sublime Text, or WebStorm set up); sometimes its an assortment of custom shell scripts; sometimes its a certain combination of libraries that all projects get started with, etc. As we continue to learn of new tools, libraries, and best practices, we further pepper our set ups. But it turns out to be <em>really hard</em> to keep up with what <q>the cool kids</q> are using at any given point in time. This is why <em>opinionated tools</em> such as Yeoman and Grunt can help us out so much. We’re provided an assortment of battle-tested developer tools that help us maintain best practices and speed up workflow.</p>
<p>In this book we’ll discuss the following tools that will help us to achieve rapid workflow:</p>
<p>TODO: We need to work out exactly what goes on this bullet list</p>
<ul>
<li>Compass/Sass</li>
<li>Twitter Bootstrap</li>
<li>Yo, Grunt, and Bower</li>
<li>Unicorn</li>
<li>Modernizr</li>
<li>RequireJS</li>
<li>JSHint</li>
</ul>
<p>Once you’ve got a handle on these core tools, you may later choose to, say, swap Zurb Foundation in place of Twitter Bootstrap, LESS for Sass, etc. But the general philosophy and approach will be close enough to what you’ve learned that you’ll be able to do so confidently.</p>
<p><em>Please be forwarned that we won’t be going extremely <q>deep</q> on these tools but, rather, we will provide enough of an introduction to gain a general understanding of what the tool does and how to get started with it. You should plan to consult each tool’s documentation for in depth coverage.</em></p>
<a id="setting_up"></a>
</section>
<section class="level1" id="setting-up">
<h1><a href="#TOC">Setting up</a></h1>
<p>In this chapter we’ll briefly introduce CSS preprocessors (<a href="http://compass-style.org/">Compass</a>, <a href="sass-lang.com">Sass</a>, <a href="http://lesscss.org/">LESS</a>, etc.), <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>, and end with a look at the workflow power-tool <a href="http://yeoman.io/">Yeoman</a>. We’ll answer these questions:</p>
<ul>
<li>What is a CSS preprocessor and why should I use one?</li>
<li>What are Compass and Sass?</li>
<li>What is Twitter Bootstrap and how can I benefit from it?</li>
<li>What is Yeoman, and how can I use it to improve my workflow?</li>
</ul>
<p>Let’s discuss some of the core tools we’ll be using throughout the remainder of this book…</p>
<section class="level3" id="what-is-a-css-preprocessor">
<h3><a href="#TOC">What is a CSS preprocessor?</a></h3>
<p>A CSS preprocessor is simply a tool that takes text you’ve written in the preprocessor’s language (usually a super-set of CSS), and converts it into valid CSS. Because the preprocessor language is, essentially a super-set of CSS, it adds useful mechanisms such as variables, nesting, mixins, basic math, etc.</p>
<p>Just taking the variable feature, for example, you might define a color variable in one place and then reference it later as needed:</p>
<pre class="sourceCode css"><code class="sourceCode css">$dark<span class="dv">:</span> <span class="fl">#333</span>;
<span class="fl">...</span>
<span class="fl">.foo</span> <span class="kw">{</span> <span class="kw">background-color:</span> $dark <span class="kw">}</span>
<span class="fl">.bar</span> <span class="kw">{</span> <span class="kw">background-color:</span> $dark <span class="kw">}</span>
<span class="fl">.baz</span> <span class="kw">{</span> <span class="kw">background-color:</span> $dark <span class="kw">}</span></code></pre>
<p>Later, if you decide you’d like $dark to be, well, a bit darker, you could simply redefine the initial declaration like so:</p>
<pre class="sourceCode css"><code class="sourceCode css">$dark<span class="dv">:</span> <span class="fl">#191919</span>;</code></pre>
<p>Now, <code>.foo</code>, <code>.bar</code>, and <code>.baz</code> will all be updated to use the new background-color the next time your .scss file is converted to CSS.</p>
<p>I’d be remiss not to mention that the three most popular CSS preprocessors today are LESS, Sass, and Stylus. All have their <a href="http://www.scottlogic.co.uk/2013/03/less-vs-sass-vs-stylus/">merits</a> but we’ll primarily be using Sass in this book.</p>
</section>
<section class="level3" id="why-use-a-css-preprocessor">
<h3><a href="#TOC">Why use a CSS preprocessor?</a></h3>
<p>If you’ve done much web development, you’re already aware that CSS can get unruly fast! Using a preprocessor affords a nice means of keeping CSS organized and maintainable. This point is best proven by example—so let’s move on to discussing Sass.</p>
</section>
<section class="level3" id="what-is-sass">
<h3><a href="#TOC">What is Sass?</a></h3>
<p>Sass is an open source tool that allows its metalanguage—also called Sass—to be interpreted into CSS. It has two syntaxes, <code>.sass</code> and <code>.scss</code>. We’ll only be covering the <code>.scss</code> syntax which is a super set of CSS that provides conveniences such as: variables, nesting, mixins, selector inheritance, and much more. <a href="http://en.wikipedia.org/wiki/Sass_(stylesheet_language)">[1]</a> In a bit, we’ll examine exactly what those mechanisms are and how they work. But for now, let’s take a look at Sass’s complimentary technology Compass. <a href="http://www.manning.com/netherland/SaCiA_meap_ch01.pdf">[2]</a></p>
</section>
<section class="level3" id="what-is-compass">
<h3><a href="#TOC">What is Compass?</a></h3>
<p>Compass is a combination of things. It’s a workflow tool for Sass that sets up relative paths (such as the relative path to your images via the image_url property; it does this via a config.rb configuration file). It then <q>watches</q> changes you make in your .scss files compiling those in to valid CSS. Compass also provides is a vast library of reusable Sass mixins for grids, tables, lists, CSS3, and more. Lastly, Compass is a full scope platform for building frameworks and extensions. <a href="http://chriseppstein.github.io/blog/2009/09/30/what-is-compass/">[3]</a></p>
<p>Again, we’ll be going over how to use Compass in more detail soon, but first let’s have a quick look at Twitter Bootstrap…</p>
</section>
<section class="level3" id="twitter-bootstrap-not-just-a-css-framework">
<h3><a href="#TOC">Twitter Bootstrap: Not just a CSS framework!</a></h3>
<p><a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a> is an open source framework that contains a set of CSS boiler plate templates for typography, buttons, charts, forms, tables, navigation and layout, etc. This CSS depends on a small set of HTML class name conventions such that any web author can <q>hook into</q> these styles by simply providing the proper markup. It also features a 12-column responsive grid so your site can adapt to different devices. It’s currently the most popular GitHub project and used by big hitters such as NASA and MSNBC. <a href="http://builtwithbootstrap.com/post/15403007616/code-nasa-from-the-real-nasa-via">[4]</a></p>
<p>In addition to interface components, the Bootstrap framework provides a plethora of JavaScript plugins that support dynamic UI components such as Modal, Tab, Tooltip, Popover, Alert, Carousel, Typeahead, Dropdown, and more. It’s only real dependency is <a href="http://jquery.com/">jQuery</a>.</p>
<p>We’ll be diving in to using Twitter Bootstrap for what it’s best at: prototyping. Whether using Bootstrap in production applications is up for debate (in our opinion it adds a lot of weight once you start wanting to override its defaults), so we’ll also show you some viable alternatives like Zurb Foundation and Unicorn.</p>
</section>
<section class="level2" id="setting-up-for-development">
<h2><a href="#TOC">Setting Up For Development</a></h2>
<p>In this section we will be setting the stage for things to come by installing Compass/Sass, Twitter Bootstrap and any other dependencies along the way. We’ll first show how you to set up some of the tools individually, and then show how you can do it all at once with <a href="http://yeoman.io/">Yeoman</a>. If you’re already sure you want to use <a href="http://yeoman.io/">Yeoman</a> feel free to skip to that section (but first ensure you have <a href="http://git-scm.com/downloads">Git</a> and <a href="http://www.ruby-lang.org/en/downloads/">Ruby</a> installed).</p>
<p><em>Since hard-disk space is so cheap these days, we feel it’s worth creating a <code>labs</code> directory for experimentation, so you can work with each tool individually before leveraging it through Yeoman. This will give you the essential background for that tool to fully benefit when using Yeoman.</em></p>
<p>In this section we’ll cover:</p>
<ul>
<li>Installing Compass and Sass</li>
<li>Installing Twitter Bootstrap</li>
</ul>
<section class="level3" id="installing-ruby">
<h3><a href="#TOC">Installing Ruby</a></h3>
<p>In order to use Compass and Sass you’ll need to first install Ruby. If you’re on OS X you already have it. For Linux users I’m going to assume you’re adept enough on the command line to get Ruby installed yourself. Windows users can download an <a href="http://www.ruby-lang.org/en/downloads/">executable installer</a>.</p>
</section>
<section class="level3" id="installing-compass-and-sass">
<h3><a href="#TOC">Installing Compass and Sass</a></h3>
<p>With that done, you should be able to open a command line and use the <code>gem</code> command. If you install Compass you get Sass installed for free. You’ll need to use the command line terminal.</p>
<p><strong>Windows</strong></p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ gem <span class="kw">install</span> compass</code></pre>
<p><strong>Linux / OS X</strong></p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">sudo</span> gem <span class="kw">install</span> compass</code></pre>
<p><strong>OS X GUI Installer</strong></p>
<p>If you’re on a Mac, you can optionally use Chris Eppstein’s <a href="https://github.com/chriseppstein/compass/downloads">graphical installer package</a></p>
<p><strong>Sass Only</strong></p>
<p>If for some reason don’t want to install Compass you can install Sass individually as follows:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ gem <span class="kw">install</span> sass</code></pre>
</section>
<section class="level3" id="installing-twitter-bootstrap">
<h3><a href="#TOC">Installing Twitter Bootstrap</a></h3>
<p>If you already have extensive experience with Bootstrap and just want to get on with using Sass to customize Bootstrap, you may choose to skip (or perhaps skim) this section.</p>
<p>Before combining technologies such as Bootstrap and Sass, it’s useful to play with them in isolation to get a better understanding of how they work. In that spirit, let’s download a <q>vanilla version</q> of Bootstrap (not adapted for Sass) and have some fun. <em>Don’t worry, we’ll soon get to using things like Yeoman, sass-bootstrap, etc.</em></p>
<p>There are a couple ways to get Bootstrap. One is simply to go to their site and download the zip:</p>
<ul>
<li>Go to <a href="http://twitter.github.com/bootstrap/">http://twitter.github.com/bootstrap/</a></li>
<li>Click the huge <strong>Download Bootstrap</strong> button</li>
<li>Extract the downloaded file and ensure you see the <code>css</code>, <code>img</code>, and <code>js</code> directories</li>
<li>Go to the Twitter Bootstrap <a href="http://twitter.github.io/bootstrap/getting-started.html#examples">examples page</a></li>
<li>Right-click any of the examples you’d like to play with and <q>Save Link As</q></li>
<li>Save the .html file to the top level of the same directory you extracted Bootstrap to</li>
<li>Open the .html file in an editor and search for: <code>../assets/</code> and replace with empty string (empty string…as in blank!)</li>
</ul>
<p>This should have found any link or src tags with relative paths like:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><link</span><span class="ot"> href=</span><span class="st">"../assets/css/bootstrap-responsive.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span></code></pre>
<p>and replaced them with relative paths that look like:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><link</span><span class="ot"> href=</span><span class="st">"css/bootstrap-responsive.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="kw">></span></code></pre>
<p>Now double click that file and it should look as it did when you previewed it on their web site. If you’re unfamiliar with Twitter Bootstrap, feel free to start hacking away off that static file now, or skip to the exercises section below.</p>
</section>
<section class="level3" id="alternate-install">
<h3><a href="#TOC">Alternate Install</a></h3>
<p>If you’re more of the command line type you’ve probably already cloned their repo, but if not try this (you’ll need to have and internet connection and <a href="http://nodejs.org/">Node.js</a> and <a href="http://git-scm.com/downloads">Git</a> installed):</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ git clone git://github.com/twitter/bootstrap.git <span class="kw">&&</span> <span class="kw">cd</span> bootstrap <span class="kw">&&</span> npm <span class="kw">install</span> <span class="kw">&&</span> grunt <span class="kw">test</span></code></pre>
<p>That will clone the Bootstrap repository, put you in the cloned directory, install all the node packages that Bootstrap requires, build Bootstrap’s LESS files, compile it’s documentation, etc., and run the full test suite…whew!</p>
<p>Alternatively, if you happen to have <a href="http://nodejs.org/">nodejs</a> and Twitter’s package manager <a href="http://bower.io/">Bower</a> installed you might just do:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ bower <span class="kw">install</span> bootstrap .</code></pre>
<p>If you’ve elected to use one of these command line methods to download Bootstrap, you should still go download an example .html file from the Twitter Bootstrap Examples page and ensure you can get it to render properly on your local system by replacing any invalid relative paths. Then do the exercises at the end of this chapter.</p>
</section>
</section>
<section class="level2" id="workflow-alternatives">
<h2><a href="#TOC">Workflow Alternatives</a></h2>
<p>This section will discuss some GUI workflow alternatives, and of course Yeoman for our command line lovers.</p>
<section class="level3" id="give-me-a-gui-please">
<h3><a href="#TOC">Give me a GUI please!</a></h3>
<p>Here are some GUI alternatives you might consider adding to your workflow. We feel that using command line tools such as Yeoman is, ultimately, more productive. But there’s nothing wrong with combining the powers of GUI and CLI if your prefer.</p>
<a id="scout"></a>
</section>
<section class="level3" id="scout">
<h3><a href="#TOC">Scout</a></h3>
<p><a href="http://mhs.github.io/scout-app/">Scout</a> is a simple GUI that sits on top of <a href="http://get.adobe.com/air/">Adobe Air</a>. Download the Scout <a href="http://mhs.github.io/scout-app/">installer</a> for either OS X or Windows and simply follow the instructions to get it installed. Start a new project by opening up Scout and clicking the plus sign on the lower left, then navigate to the directory you’d like to create your project in. Once you’ve selected a directory and clicked <q>Open</q>, you’re new project will show up in Scout on the left side.</p>
<figure>
<img src="img/Scout-App2.png" title="Opening a project in Scout " alt="Opening a project in Scout"><figcaption>Opening a project in Scout</figcaption>
</figure>
<p>Above, I’ve created a folder called <q>Scout</q>. As you can see, we’re required to select the input and output folders. However, we haven’t set those yet…let’s do so.</p>
<p>In your project directory (the <code>Scout</code> directory in the above example), manually create the following directory structure and files (you’ll use <code>compass create</code> to do much the same later but let’s do it manually for now):</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">|</span>-- css
<span class="kw">|</span>-- index.html
<span class="kw">|</span>-- sass
<span class="kw">|</span>-- style.scss</code></pre>
<p>Above we have two directories <code>css</code> and <code>sass</code> and two files <code>index.html</code> and <code>sass/style.scss</code>. The <code>index.html</code> file should contain:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="er"><</span>!doctype html>
<span class="kw"><head><title></span>Compass Sass Sandbox<span class="kw"></title></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"css/style.css"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="ot"> type=</span><span class="st">"text/css"</span> <span class="kw">/></span>
<span class="kw"></head></span>
<span class="kw"><body></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"test"</span><span class="kw">></span>This is a test.<span class="kw"></div></span>
<span class="kw"></body></span>
<span class="kw"></html></span></code></pre>
<p>And the <code>sass/style.scss</code> file should contain:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="dv">@import</span> <span class="st">"compass/reset"</span><span class="dv">;</span>
$testColor<span class="dv">:</span> <span class="fl">#008080</span>;
<span class="fl">.test</span> <span class="kw">{</span>
<span class="kw">color:</span> $testColor<span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>It should be self-evident in the above <code>.scss</code> file that we’re importing Compass’s reset module, defining a color variable, and then using that variable on the <code>.test</code> class we defined earlier in our markup.</p>
<p>Now go back to the Scout application. For the <q>Input Folder</q> click the <q>Choose</q> button and find the <code>sass</code> directory we defined earlier; now do the same for the <q>Output Folder</q> but this time choose the <code>css</code> directory. The idea here is that the input files will get fetched from the <code>sass</code> directory (where we have our <code>.scss</code> files), get converted to proper CSS, and then output as <code>.css</code> files to the our output directory.</p>
<p>Once you’ve set up the input and output folders, simply click the big <q>play button</q> beside your project name to start Scout <q>watching</q> for file modifications. The first time I did this it took several seconds before I actually saw the output on the log tab showing that the style.scss file was detected and the style.css file was created:</p>
<figure>
<img src="img/Scout-Compiled2.png" title="Scout can convert your .scss files to .css files" alt="Scout can convert your .scss files to .css files"><figcaption>Scout can convert your .scss files to .css files</figcaption>
</figure>
<p>If for some reason you don’t see this try re-saving your style.scss file to force Scout to compile it.</p>
<p>At this point you should be able to double click on the project’s index.html file and see <q>This is a test in teal</q>. Not too exciting yet—I know—but we’ve now seen a simple Compass/Sass workflow using Scout. Try making a few more edits to the .scss file and you’ll see that Scout detects them and recompiles a new modified .css file for you. Nice!</p>
<p>While your at it, be sure to have a quick look at the generated CSS file. Now try removing the Compass reset import line and see what’s generated. You should see all of the boiler-plate reset CSS was removed (as expected), and just see the changes made on the <code>.test</code> class. Our Sass changes are reflected immediately in the corresponding CSS file.</p>
</section>
<section class="level3" id="commercial-gui">
<h3><a href="#TOC">Commercial GUI</a></h3>
<p>If you’re willing to fork out a small sum of money for slightly more aestetically pleasing interfaces and features, you might want to take a look at the following alternatives: <a href="http://incident57.com/codekit/">CodeKit</a>, <a href="http://compass.handlino.com/">Compass.app</a>, or <a href="http://livereload.com/">LiveReload</a>. Keep in mind, though, that <a href="http://yeoman.io/">Yeoman</a>, the tool we’ll be discussing next, will also give you this sort of <em>watch</em> functionality and it’s free!</p>
<a id="yeoman_setup"></a>
</section>
</section>
<section class="level2" id="yeoman">
<h2><a href="#TOC">Yeoman</a></h2>
<p>If you’re a CLI junky looking to fully optimize your front-end set up, you might want to take a look at <a href="http://yeoman.io/">Yeoman</a>. Yeoman is spearheaded by none other than <a href="http://www.paulirish.com/">Paul Irish</a>, <a href="http://addyosmani.com/blog/">Addy Osmani</a>, and <a href="https://github.com/sindresorhus">Sindre Sorhus</a>. Yeoman bundles <a href="http://gruntjs.com/">Grunt</a>, <a href="http://gruntjs.com/">Bower</a>, <a href="http://modernizr.com/">Modernizr</a> (and much more) in to one very convenient to use command line tool. It is still in BETA, but the author has had success using Yeoman since version 1.0 was released a few months before writing this book. We’ll be using Yeoman to do all our heavy lifting through-out the remainder of this book.</p>
<p>If you have <a href="http://nodejs.org/">Node.js</a>, <a href="http://git-scm.com/downloads">Git</a>, <a href="http://www.ruby-lang.org/en/downloads/">Ruby</a> and <a href="http://compass-style.org/">Compass</a> already installed, you should be able to get Yeoman up and running with the following commands (only do this if you have an Internet connection!):</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">mkdir</span> myproject <span class="kw">&&</span> <span class="kw">cd</span> <span class="ot">$_</span> <span class="co"># $_ is last argument of previous command</span>
$ npm <span class="kw">install</span> -g yo <span class="kw">&&</span> npm <span class="kw">install</span> -g generator-webapp
$ yo webapp <span class="co"># answer questions choosing Bootstrap for sass and hit ENTER</span>
$ grunt server</code></pre>
<p>At this point, you’ll have a fully prepared web app scaffolded and should be previewing your web app in a web browser. The following screen capture shows how it look when I ran this (however, since this is always changing and improving library, there’s a good chance it will look different by the time you read this):</p>
<figure>
<img src="img/yeoman-start-page.png" title="Grunt server loads the default project start page" alt="Grunt server loads the default project start page"><figcaption>Grunt server loads the default project start page</figcaption>
</figure>
<p>When you ran the <code>yo webapp</code> command, one of the questions you were asked should have looked something like:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">Out of the box I include HTML5 Boilerplate and jQuery.
[?] What <span class="kw">more</span> would you like? <span class="kw">(</span>Press <span class="kw"><</span>space<span class="kw">></span> to <span class="kw">select)</span></code></pre>
<p>With a drop down of choices immediately following. We want the Bootstrap for Sass which sets up the Twttier Bootstrap port to Sass for us.</p>
<p>We’ll soon be seeing how you can further adapt a project like this using one of the primary Yeoman tools which consist of:</p>
<ul>
<li>Yo—the tool for customizing projects and generating scaffolding (we just used it earlier)</li>
<li>Grunt—you can use Grunt to create custom workflows for testing, deployment, coding standards verification, etc.</li>
<li>Bower—use Bower to install and/or updated your front-end packages</li>
</ul>
<p>The <code>yo webapp</code> line in our earlier Yeoman project initialization is, in Yeoman parlance, called a <em>generator</em>. The <code>webapp</code> generator was installed when we did <code>npm install -g generator-webapp</code>. Other generators you might want to use also require you to install them yourself. You can do that via <a href="https://npmjs.org/">npm</a> (that stands for <em>node package manager</em> and it’s bundled with <a href="http://nodejs.org/">Node.js</a>).</p>
<p>New generators are being added all the time, but at the time of writing this, the Yeoman docs list the following <a href="https://github.com/yeoman/generator">officially supported generators</a> (again, this is always changing so expect a larger and/or different list by the time you read this!):</p>
<ul>
<li>Web App (the one we installed earlier)</li>
<li>AngularJS</li>
<li>Backbone</li>
<li>BBB (Backbone Boilerplate)</li>
<li>Chrome Apps Basic Boilerplate</li>
<li>Ember</li>
<li>Jasmine</li>
<li>Mocha</li>
<li>Karma</li>
</ul>
<p>Here’s another example of installing a generator:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ npm <span class="kw">install</span> -g generator-bbb <span class="co"># -g installs the bbb generator globally</span>
$ <span class="kw">mkdir</span> myproject <span class="kw">&&</span> <span class="kw">cd</span> <span class="ot">$_</span> <span class="kw">&&</span> yo bbb
<span class="co"># answer any questions at prompt</span>
$ grunt <span class="kw">&&</span> grunt <span class="kw">test</span> <span class="kw">&&</span> grunt server</code></pre>
<p>That would install the <a href="http://backboneboilerplate.com/">Backbone Boilerplate</a> generator, create a project, and then build, test, and preview it.</p>
<p>The above example workflows are just a couple ways you might use Yeoman to scaffold out a web app. Visit the <a href="http://yeoman.io/">Yeoman site</a> (or the author’s <a href="http://www.youtube.com/playlist?list=PL56psyY4UDqNPWpTwpqtuIqNZwyQVBByb">How To Code</a> Youtube channel which has several tutorials on using Yeoman) to get more information on this lovely tool.</p>
</section>
<section class="level2" id="exercises">
<h2><a href="#TOC">Exercises</a></h2>
<p>Here are some easy exercises to get yourself familiarized with Bootstrap:</p>
<ul>
<li>Have a quick read through of the Twitter Bootstrap documentation which is only a half dozen pages or so. Don’t worry about memorizing every last detail; just try to get a general feel for where they cover what, what’s available, conventions they use, etc.—you’ll be visiting these docs frequently</li>
</ul>
<p>If you haven’t already used Twitter Bootstrap before also do the following:</p>
<ul>
<li>Take the skeleton app we created above (in the <a href="#scout">section on Scout</a>), and add jQuery and Bootstrap (in that order). The goal is to get a simple static page assembled with a form, table, and perhaps a navigation bar. Alternatively, if you’ve installed <a href="http://compass-style.org/">Compass</a> you can create a similar file structure with the command: <code>compass create</code>. You will still have to create the <code>index.html</code> file though, so again, refer to the Scout section above for that.</li>
</ul>
<p>For guidance on how to refactor the simple index.html page example, first have a look at the <a href="http://twitter.github.io/bootstrap/getting-started.html#examples">Getting Started</a> page.</p>
<ul>
<li>Also have a a look at the Layouts section for guidance on how to control your widths and flow</li>
<li>See the Base CSS section for guidance on forms and tables</li>
<li>See the Navbar docs for guidance on the navigation bar</li>
</ul>
<p><em>If you’re more of a visual learner see the author’s <a href="http://www.youtube.com/watch?v=YEpMzpieTBg">video</a> on combining Yeoman and Twitter Bootstrap to rapidly prototype a simple web page</em></p>
<ul>
<li>If you’ve installed Yeoman and/or Compass, and you’re adventurous, try adding a few <code>mixins</code> as described in <a href="http://culttt.com/2013/02/18/getting-started-with-compass/">this tutorial</a> on getting started with Compass.</li>
</ul>
</section>
<section class="level2" id="summary">
<h2><a href="#TOC">Summary</a></h2>
<p>In this chapter we’ve:</p>
<ul>
<li>Discovered CSS preprocessors</li>
<li>Discovered and installed Compass and Sass</li>
<li>Discovered and installed Twitter Bootstrap</li>
<li>Saw some Compass and Sass GUI alternatives</li>
<li>Played a bit with Yeoman</li>
</ul>
<p>It’s now time to delve in to the syntax of Compass and Sass. Let’s go get our hands dirty, shall we!</p>
<a id="introduction_to_compass_and_sass"></a>
</section>
</section>
<section class="level1" id="introduction-to-compass-and-sass">
<h1><a href="#TOC">Introduction to Compass and Sass</a></h1>
<p>This chapter will serve as a short introduction to Sass and go over the basic syntax, workflow, etc., and will additionally introduce the advantages of incorporating Compass in to your Sass workflow. This will be a whirlwind tour (not for the feint of heart); if you’d like a more gentle and complete introduction to Compass and Sass do have a look at <a href="http://www.amazon.com/Sass-Compass-Designers-Ben-Frain/dp/1849694540">Sass and Compass for Designers</a> by <a href="http://benfrain.com/">Ben Frain</a>.</p>
<p>Topics covered:</p>
<ul>
<li>Compass/Sass Workflow
<ul>
<li>Compass Essentials: config.rb, watch, and CSS3 mixins</li>
</ul></li>
<li>A sandbox to play in (setting up a test script)</li>
<li>Variables</li>
<li>Nesting</li>
<li>Mixins</li>
<li>Placeholders</li>
<li>Structure
<ul>
<li>@import</li>
<li>Utilizing partials</li>
</ul></li>
</ul>
<section class="level2" id="using-compass-to-create-a-project">
<h2><a href="#TOC">Using Compass to Create a Project</a></h2>
<p>Remember in the last chapter how we manually created a directory structure like:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">|</span>-- css
<span class="kw">|</span>-- index.html
<span class="kw">|</span>-- sass
<span class="kw">|</span>-- style.scss</code></pre>
<p>Well, don’t be mad, but with Compass with can create all of that less the index.html page with the following simple command:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">$ compass create --css-dir <span class="st">"css"</span></code></pre>
<p>The only reason we needed the <code>--css-dir "css"</code> part was to force Compass to use the directory name <q>css</q> (instead of <q>stylesheets</q> which is the default). You can also pass options for where to find your JavaScript and images like <code>--javascripts-dir "path_to_your_javascript"</code> and <code>--images-dir "path_to_your_images"</code>. These get used to build the config.rb file that we’ll be looking at in a bit.</p>
<p>What happens upon issuing the above command is Compass scaffolds out a minimal project for you that looks like:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">|</span>-- config.rb
<span class="kw">|</span>-- css
<span class="kw">|</span>-- ie.css
<span class="kw">|</span>-- print.css
<span class="kw">|</span>-- screen.css
<span class="kw">|</span>-- sass
<span class="kw">|</span>-- ie.scss
<span class="kw">|</span>-- print.scss
<span class="kw">|</span>-- style.scss</code></pre>
<p>Notice that this is essentially what we did manually before with the added benefit that they’ve added the IE and print files as well (we’ll be ignoring the IE stylesheet for the time being). What we had previously named <code>sass/style.scss</code> is now <code>sass/screen.scss</code>. If you look at the config.rb file you’ll notice that our CSS and Sass directories are where you’d expect:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">css_dir = <span class="st">"css"</span>
sass_dir = <span class="st">"sass"</span></code></pre>
<p>No surprises there.</p>
</section>
<section class="level2" id="a-sandbox-to-play-in">
<h2><a href="#TOC">A Sandbox to Play In</a></h2>
<p>As Compass is really only concerned with stylesheet related things, we didn’t get an index.html page so let’s create that now:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="er"><</span>!doctype html>
<span class="kw"><head></span>
<span class="kw"><title></span>Compass Sass Sandbox<span class="kw"></title></span>
<span class="kw"><link</span><span class="ot"> href=</span><span class="st">"css/screen.css"</span><span class="ot"> media=</span><span class="st">"screen, projection"</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="ot"> type=</span><span class="st">"text/css"</span> <span class="kw">/></span>
<span class="kw"></head></span>
<span class="kw"><body></span>
<span class="kw"><div</span><span class="ot"> class=</span><span class="st">"test"</span><span class="kw">></span>This is a test.<span class="kw"></div></span>
<span class="kw"></body></span>
<span class="kw"></html></span></code></pre>
<p>Above, we’ve included our <code>screen.css</code> which will hold the styles for this exercise.</p>
</section>
<section class="level2" id="compass-configuration">
<h2><a href="#TOC">Compass Configuration</a></h2>
<p>Let’s take the <code>config.rb</code> configuration file section by section:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">http_path = <span class="st">"/"</span>
css_dir = <span class="st">"stylesheets"</span>
sass_dir = <span class="st">"sass"</span>
images_dir = <span class="st">"images"</span>
javascripts_dir = <span class="st">"javascripts"</span></code></pre>
<p>This should be fairly self-evident but the <code>http_path</code> sets the root HTTP directory of the project from which all other paths will be relative to. If you wanted to add fonts too you might add the line:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">fonts_dir = <span class="st">"fonts"</span></code></pre>
<p>Let’s have a look at the output style line:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># output_style = :expanded or :nested or :compact or :compressed</span></code></pre>
<p>Let’s assume we have the following defined in an .scss file:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">.test</span> <span class="kw">{</span>
<span class="kw">color:</span> <span class="dt">#ddd</span><span class="kw">;</span>
<span class="er">.</span><span class="kw">klass:</span> {
color: <span class="dt">#aaa</span><span class="kw">;</span>
<span class="kw">}</span>
}</code></pre>
<p>By default, the output style will look something like this:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="co">/* line 7, ../sass/screen.scss */</span>
<span class="fl">.test</span> <span class="kw">{</span>
<span class="kw">color:</span> <span class="dt">#ddd</span><span class="kw">;</span>
<span class="er">.</span><span class="kw">klass-color:</span> <span class="dt">#aaa</span><span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>Notice that nothing’s changed other than we have a comment that identifies the line and file. Changing the output_style to <code>:nested</code> we get:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="co">/* line 7, ../sass/screen.scss */</span>
<span class="fl">.test</span> <span class="kw">{</span>
<span class="kw">color:</span> <span class="dt">#ddd</span><span class="kw">;</span>
<span class="er">.</span><span class="kw">klass-color:</span> <span class="dt">#aaa</span><span class="kw">;</span> <span class="kw">}</span></code></pre>
<p>Notice that resulting css is nested. Now let’s try <code>:compact</code></p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="co">/* line 7, ../sass/screen.scss */</span>
<span class="fl">.test</span> <span class="kw">{</span> <span class="kw">color:</span> <span class="dt">#ddd</span><span class="kw">;</span> <span class="er">.</span><span class="kw">klass-color:</span> <span class="dt">#aaa</span><span class="kw">;</span> <span class="kw">}</span></code></pre>
<p>Notice that the CSS was all put on one line. Last let’s finally try <code>:compressed</code></p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">.test</span><span class="kw">{color:</span><span class="dt">#ddd</span><span class="kw">;</span><span class="er">.</span><span class="kw">klass-color:</span><span class="dt">#aaa</span><span class="kw">}</span></code></pre>
<p>Notice that the comment was removed along with all white space.</p>
<p>I’d suggest just leaving this parameter alone for the time-being as it will be easier to debug. Before generating production code you’d likely want to use <code>:compressed</code> to ensure speedy delivery. While there are more configuration options available, this should be enough for our purposes. If you need more detail have a look at the <a href="http://compass-style.org/reference/compass/">Compass Reference documentation</a> which covers the options in detail.</p>
<a id="sass"></a>
</section>
<section class="level2" id="sass">
<h2><a href="#TOC">Sass</a></h2>
<p>Now that we’re properly utilizing Compass to help us with our Sass workflow, let’s dive in to the Sass syntax itself. We’ll cover just enough of the features to get you started (as always, for more detailed coverage we suggest you go the the reference documentation).</p>
<p>We’re going to use a simple navigation bar to go over a few Sass syntax concepts. Let’s go ahead and replace the content within our <code><body></code> tags from:</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="kw"><div</span><span class="ot"> class=</span><span class="st">"test"</span><span class="kw">></span>This is a test.<span class="kw"></div></span></code></pre>
<p>to the following navigation markup:</p>
<pre class="sourceCode html"><code class="sourceCode html"> <span class="kw"><ul</span><span class="ot"> id=</span><span class="st">"nav"</span><span class="kw">></span>
<span class="kw"><li></span>
<span class="kw"><a</span><span class="ot"> href=</span><span class="st">"#"</span><span class="kw">></span>Products<span class="kw"></a></span>
<span class="kw"><a</span><span class="ot"> href=</span><span class="st">"#"</span><span class="kw">></span>Services<span class="kw"></a></span>
<span class="kw"><a</span><span class="ot"> href=</span><span class="st">"#"</span><span class="kw">></span>About Us<span class="kw"></a></span>
<span class="kw"><a</span><span class="ot"> href=</span><span class="st">"#"</span><span class="kw">></span>FAQ<span class="kw"></a></span>
<span class="kw"></li></span>
<span class="kw"></ul></span></code></pre>
<p>At this point you should have something very plain like:</p>
<figure>
<img src="img/navbar-wip1.png" title="Navigation bar work in progress" alt="Navigation bar work in progress"><figcaption>Navigation bar work in progress</figcaption>
</figure>
<p>Now let’s go to <a href="http://flatuicolors.com/">http://flatuicolors.com/</a> and grab some colors for our navigation bar (feel free to use your own colors…I’ve chosen blue colors). Since you’re probably already familiar with CSS, let’s go ahead and show how we might style the navigation bar with vanilla CSS.</p>
<p>Place the following CSS in <code>sass/screen.scss</code>:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#3498db</span><span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> <span class="dt">#ccc</span><span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> <span class="dt">#ccc</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">#nav</span> li a <span class="kw">{</span>
<span class="kw">display:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> <span class="dt">#fff</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">#nav</span> li a<span class="dv">:hover</span> <span class="kw">{</span>
<span class="kw">color:</span> <span class="dt">#fafafa</span><span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#4aa3df</span><span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>As you can see, this is plain old CSS. As Sass’s <code>.scss</code> syntax is just a super-set of CSS, we can use any valid CSS within a Sass <code>.scss</code> file.</p>
<p>Now go ahead and either run <code>compass compile</code>, or, better yet, start a <em>watch</em> on our Sass files by issuing: <code>compass watch</code>. You should do this from another terminal tab in the same project directory so changes get immediately detected and compiled to CSS.</p>
<p>You should see something like the following (this will be our, ahem, amazing end result for the exercise):</p>
<figure>
<img src="img/navbar-wip2.png" title="Navigation bar end result using CSS" alt="Navigation bar end result using CSS"><figcaption>Navigation bar end result using CSS</figcaption>
</figure>
<p>Ok, so now that we have a working example of a pleasant (if extremely simple) navigation bar using CSS. Let’s now see how we might <em>refactor</em> this CSS using Sass to make our lives easier.</p>
<section class="level3" id="variables">
<h3><a href="#TOC">Variables</a></h3>
<p>If you look at the CSS we have at this point, you should notice that we have some <em>duplication</em> in our hex colors (e.g. <code>#ccc</code> is repeated twice, and <code>#fff</code> and <code>#fafafa</code> are definitely related). We can do better.</p>
<p>You’ve already seen in an earlier chapter that we can define variables in Sass using <code>$variable_name</code>. Let’s do that by adding a <code>$white</code> and <code>$grey</code> at the top of the <code>sass/screen.scss</code> file, and then reference those variables as needed:</p>
<pre class="sourceCode css"><code class="sourceCode css">$grey<span class="dv">:</span> <span class="fl">#ccc</span>;
$white<span class="dv">:</span> <span class="fl">#fff</span>;
<span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#3498db</span><span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">#nav</span> li a <span class="kw">{</span>
<span class="kw">display:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">#nav</span> li a<span class="dv">:hover</span> <span class="kw">{</span>
<span class="kw">color:</span> darken($white, <span class="dt">2%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#4aa3df</span><span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p><em><code>darken</code> towards the bottom should be fairly self-evident, but it’s what is called a <q>mixin</q> (something we’ll talk about shortly); for now, just now that it will darken the white by 2% leaving us with the <code>#fafafa</code> we had earlier.</em></p>
<p>Let’s go ahead and do a bit more by replacing our <code>background-color</code> with a <code>$blue</code> variable. This time we’ll be using the <code>lighten</code> mixin which does the inverse of <code>darken</code>:</p>
<pre class="sourceCode css"><code class="sourceCode css">// Base Colors
$grey<span class="dv">:</span> <span class="fl">#ccc</span>;
$white<span class="dv">:</span> <span class="fl">#fff</span>;
$blue<span class="dv">:</span> <span class="fl">#3498DB</span>;//peter-river blue
<span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">background-color:</span> $blue<span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">#nav</span> li a <span class="kw">{</span>
<span class="kw">display:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">#nav</span> li a<span class="dv">:hover</span> <span class="kw">{</span>
<span class="kw">color:</span> darken($white, <span class="dt">2%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> lighten($blue, <span class="dt">5%</span>)<span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>So we now have some color variables defined which can be used throughout the rest of our project as it grows. The next thing we can work on is the structure.</p>
</section>
<section class="level3" id="nesting">
<h3><a href="#TOC">Nesting</a></h3>
<p>In our CSS so far, we have a lot of repetition of the <code>#nav</code> selector. Let’s use Sass’s nesting feature to organize that into a more readable structure:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">background-color:</span> $blue<span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="er">li</span> <span class="er">a</span> <span class="er">{</span>
<span class="kw">display:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="er">&:hover</span> <span class="er">{</span>
<span class="kw">color:</span> darken($white, <span class="dt">2%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> lighten($blue, <span class="dt">5%</span>)<span class="kw">;</span>
<span class="kw">}</span>
}
}</code></pre>
<p>Most of this should be self-evident, but what’s happening, is that Sass is smart enough to take that nested structure and convert it in to valid CSS. In fact, here’s the CSS that’s created from the above <code>.scss</code> file:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="co">/* line 5, ../sass/screen.scss */</span>
<span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#3498db</span><span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> <span class="dt">#cccccc</span><span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> <span class="dt">#cccccc</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="co">/* line 12, ../sass/screen.scss */</span>
<span class="fl">#nav</span> li a <span class="kw">{</span>
<span class="kw">display:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> <span class="dt">white</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="co">/* line 18, ../sass/screen.scss */</span>
<span class="fl">#nav</span> li a<span class="dv">:hover</span> <span class="kw">{</span>
<span class="kw">color:</span> <span class="dt">#fafafa</span><span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#4aa3df</span><span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>It looks pretty much like what we had before as the nested <code>#nav</code> blocks have been properly converted for CSS, and of course, our variables have been evaluated and converted to their actual hex values.</p>
<p>What’s that <code>&:hover {</code> bit you say? Let’s break that down:</p>
<ul>
<li>The <code>&</code> means <q>insert my parent selector here</q></li>
<li>So the <code>&</code> will essentially be replaced with an <code>a</code></li>
<li>the <code>:hover</code> is just a plain old <code>:hover</code> pseudo-class, so this will be turned in to: <code>a:hover</code>.</li>
</ul>
<p>Just remember that anytime you see that <code>&</code>, you can say in your head <q>insert parent selector here</q>.</p>
<p><em>Caution: This nesting feature, while attractive from an organizational and aestetic perspective, can be a bit dangerous. You should avoid too many levels of nesting (perhaps 4). Read more information on why at this article on the <a href="http://thesassway.com/beginner/the-inception-rule"><q>Inception Rule</q></a>.</em></p>
</section>
<section class="level3" id="mixins">
<h3><a href="#TOC">Mixins</a></h3>
<p>Mixins are a feature of Sass that allow you to create re-usable CSS. To define a mixin you must use the <code>@mixin</code> directive followed by the mixin’s name and any arguments it accepts in paranthesis. This is all followed by a CSS block containing the contents of the mixin. An example should make this all a bit clearer:</p>
<pre class="sourceCode css"><code class="sourceCode css">@mixin box-shadow($def) <span class="kw">{</span>
<span class="kw">-moz-box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">-webkit-box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>Above we have the <code>@mixin</code> directive followed by the name <code>box-shadow</code> followed by a parameter list of just one <code>$def</code> argument. This is all followed by the block which defines the CSS rules (in this case it’s just some convenience for dealing with vendor prefixes).</p>
<p>To use this mixin we might do:</p>
<pre class="sourceCode css"><code class="sourceCode css"> @include box-shadow(0px 4px 5px $grey);</code></pre>
<p>In fact, let’s add this to our navigation bar with the following in <code>sass/screen.scss</code>:</p>
<pre class="sourceCode css"><code class="sourceCode css">// Base Colors
$grey<span class="dv">:</span> <span class="fl">#ccc</span>;
$white<span class="dv">:</span> <span class="fl">#fff</span>;
$blue<span class="dv">:</span> <span class="fl">#3498DB</span>;//peter-river blue
@mixin box-shadow($def) <span class="kw">{</span>
<span class="kw">-moz-box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">-webkit-box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">background-color:</span> $blue<span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="er">@include</span> <span class="kw">box-shadow</span><span class="er">(0px</span> <span class="er">4px</span> <span class="er">5px</span> <span class="er">$grey);</span>
<span class="er">li</span> <span class="er">a</span> <span class="er">{</span>
<span class="er">display</span><span class="kw">:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="er">&:hover</span> <span class="er">{</span>
<span class="kw">color:</span> darken($white, <span class="dt">2%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> lighten($blue, <span class="dt">5%</span>)<span class="kw">;</span>
<span class="kw">}</span>
}
}</code></pre>
<p>Our navigation bar now has a not so subtle shadow:</p>
<figure>
<img src="img/navbar-wip3.png" title="Navigation bar with box-shadow added" alt="Navigation bar with box-shadow added"><figcaption>Navigation bar with box-shadow added</figcaption>
</figure>
<p>While this is not an extremely impressive use of mixins, it does provide an example of how they work. <em>It just so turns out, that Compass provides its own box-shadow mixin that we’ll be levaraging later.</em></p>
<p>The possibilities with mixins are truly endless as we can see by this next example refactoring where we’ve moved out the horizontal navigation CSS in to it’s own mixin and then included that in our <code>#nav</code> rule:</p>
<pre class="sourceCode css"><code class="sourceCode css">@mixin horizontal-navbar <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="er">li</span> <span class="er">a</span> <span class="er">{</span>
<span class="kw">display:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="er">&:hover</span> <span class="er">{</span>
<span class="kw">color:</span> darken($white, <span class="dt">2%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> lighten($blue, <span class="dt">5%</span>)<span class="kw">;</span>
<span class="kw">}</span>
}
}
<span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">background-color:</span> $blue<span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="er">@include</span> <span class="kw">box-shadow</span><span class="er">(0px</span> <span class="er">4px</span> <span class="er">5px</span> <span class="er">$grey);</span>
<span class="er">@include</span> <span class="er">horizontal-navbar;</span>
<span class="er">}</span></code></pre>
<p>Mixins aren’t all perfect though. Anytime you use a mixin using the <code>@include</code> directive, keep in mind that the rules in your mixin’s block will all get copied over potentially causing duplication. This isn’t always a problem, but if it concerns you, you’ll be happy to hear that we have an alternative feature in Sass called <em>placeholders</em> which circumnavigate this issue alltogether.</p>
</section>
<section class="level3" id="placeholders">
<h3><a href="#TOC">Placeholders</a></h3>
<p>Placeholders look like class and id selectors but instead use <code>%</code> before the name. They work in tandem with the <code>@extend</code> directive which allows a selector to inherit from another.</p>
<pre class="sourceCode css"><code class="sourceCode css">%button <span class="kw">{</span>
<span class="kw">padding:</span> <span class="dt">.5em</span> <span class="dt">1.2em</span><span class="kw">;</span>
<span class="kw">font-size:</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="kw">background-color:</span> $green<span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">border:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="er">@include</span> <span class="kw">box-shadow</span><span class="er">(0px</span> <span class="er">2px</span> <span class="er">4px</span> <span class="er">$grey);</span>
<span class="er">&</span><span class="kw">:</span>hover {
color: darken($white, <span class="dt">5%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> lighten($green, <span class="dt">10%</span>)<span class="kw">;</span>
<span class="kw">}</span>
}
<span class="fl">.button</span> <span class="kw">{</span>
<span class="er">@extend</span> <span class="er">%button;</span>
<span class="kw">}</span>
<span class="fl">.rounded-button</span> <span class="kw">{</span>
<span class="er">@extend</span> <span class="er">%button;</span>
<span class="er">@include</span> <span class="kw">border-radius</span><span class="er">(5px);</span>
<span class="er">}</span></code></pre>
<p>The way <code>@extend</code> works is that Sass uses CSS inheritance to re-use the block so duplication is avoided. For example, the above <code>.scss</code> code gets converted to the following CSS (pay attention to the first line indicating that the <code>.button</code> and <code>.rounded-button</code> inherit the same rules):</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">.button</span>, <span class="fl">.rounded-button</span> <span class="kw">{</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1.2em</span><span class="kw">;</span>
<span class="kw">font-size:</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">color:</span> <span class="dt">white</span><span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#2ecc71</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">border:</span> <span class="dt">1px</span> <span class="dt">solid</span> <span class="dt">#cccccc</span><span class="kw">;</span>
<span class="kw">-moz-box-shadow:</span> <span class="dt">0px</span> <span class="dt">2px</span> <span class="dt">4px</span> <span class="dt">#cccccc</span><span class="kw">;</span>
<span class="kw">-webkit-box-shadow:</span> <span class="dt">0px</span> <span class="dt">2px</span> <span class="dt">4px</span> <span class="dt">#cccccc</span><span class="kw">;</span>
<span class="kw">box-shadow:</span> <span class="dt">0px</span> <span class="dt">2px</span> <span class="dt">4px</span> <span class="dt">#cccccc</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">.button</span><span class="dv">:hover</span>, <span class="fl">.rounded-button</span><span class="dv">:hover</span> <span class="kw">{</span>
<span class="kw">color:</span> <span class="dt">#f2f2f2</span><span class="kw">;</span>
<span class="kw">background-color:</span> <span class="dt">#54d98c</span><span class="kw">;</span>
<span class="kw">}</span>
<span class="fl">.rounded-button</span> <span class="kw">{</span>
<span class="kw">-moz-border-radius:</span> <span class="dt">5px</span><span class="kw">;</span>
<span class="kw">-webkit-border-radius:</span> <span class="dt">5px</span><span class="kw">;</span>
<span class="kw">-ms-border-radius:</span> <span class="dt">5px</span><span class="kw">;</span>
<span class="kw">border-radius:</span> <span class="dt">5px</span><span class="kw">;</span>
<span class="kw">}</span></code></pre>
<figure>
<img src="img/navbar-buttons.png" title="Buttons using placeholders" alt="Buttons using placeholders"><figcaption>Buttons using placeholders</figcaption>
</figure>
<p>As you can see, the two buttons share the CSS they have in common with only the border-radius being additionally added to <code>.rounded-button</code>. It’s easy to imagine adding some text shadow, linear gradients, etc., to have a nice <code>%button</code> that all of you’re project’s buttons can <code>@extend</code> from.</p>
</section>
<section class="level3" id="structure">
<h3><a href="#TOC">Structure</a></h3>
<p>If you’ve been following along with the code changes, you should notice that our <code>sass/screen.scss</code> has become a bit of a hodgepodge of variables, mixins, etc. Fortunately, we can use Sass’s <em>partials</em> and <code>@import</code> directives to create a more modular project structure. While our little experiment is still pretty small, it should be evident that as a project grows, keeping things organized is of paramount importance. Let’s go ahead and do this refactoring now.</p>
<section class="level4" id="partials-and-imports">
<h4><a href="#TOC">Partials and Imports</a></h4>
<p>In this section we’re only going to look at the basics of using partials and imports, for more detailed guidance have a look at some various opinions on how to best structure your project:</p>
<ul>
<li><a href="http://thesassway.com/beginner/how-to-structure-a-sass-project">The Sass Way article on how to structure Sass projects</a>—a great overview of how to organize your Sass based projects</li>
<li><a href="http://compass-style.org/help/tutorials/best_practices/">Compass best practices</a>—some great suggestions from the Compass team</li>
<li><a href="http://railslove.com/blog/2012/03/28/smacss-and-sass-the-future-of-stylesheets/">SMACSS and Sass project structure</a>—shows how one might use a <a href="http://smacss.com/">SMACSS</a> approach to organizing Sass based projects</li>
</ul>
<p>Since our project is just a pedantic exercise and I don’t want you to get <q>bogged down</q> in details, let’s not worry too much about using the absolute perfect project structure. Instead, let’s aim to simply move meaningful chunks of CSS code in to <em>partials</em> that make intuitive sense. Even this small organizational improvement will head us in the right direction.</p>
</section>
<section class="level4" id="what-are-partials">
<h4><a href="#TOC">What are partials?</a></h4>
<p>Partials are files that have Sass code that only pertains to one particular area of your project (e.g. colors, typography, etc.).</p>
<p>In our little experiment, we already have CSS for colors, buttons, navigation bar, mixins and placeholders. <em>In a more complete project we’d also have typography, reset, etc., but we’ll purposely omit those for now to keep this simple</em>.</p>
<p>Let’s go ahead and move these chunks of code in to partials now. In order to use partials with Compass and Sass we want to abide by the naming convention <code>directory/_name.scss</code>, and then we can <em>import</em> the partial dropping off the underscore and file extension like:</p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="dv">@import</span> <span class="st">"directory/name"</span></code></pre>
<p>The following shows our experiment converted to use partials.</p>
<p><em>Note that we’ll show each file and then it’s code like:</em></p>
<p><code>path/to/file</code></p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">.foo</span> <span class="kw">{</span>
<span class="kw">color:</span> <span class="dt">red</span><span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>So just to be clear, once we create these partials our sass directory will look something like:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">|</span>-- ie.scss
<span class="kw">|</span>-- print.scss
<span class="kw">|</span>-- screen.scss
<span class="kw">|</span>-- base
<span class="kw">|</span>---- _colors.scss
<span class="kw">|</span>---- _mixins.scss
<span class="kw">|</span>---- _placeholders.scss
<span class="kw">|</span>-- layout
<span class="kw">|</span>---- _nav.scss
<span class="kw">|</span>-- modules
<span class="kw">|</span>---- _buttons.scss</code></pre>
<p><em>Here are the contents for these new files…</em></p>
<p><code>sass/screen.scss</code></p>
<pre class="sourceCode css"><code class="sourceCode css">// Partials imports
// note that in a <span class="st">"real"</span>
// project we<span class="st">'d also have</span>
<span class="st">// resets, typography, etc.</span>
<span class="st">@import "base/colors";</span>
<span class="st">@import "base/mixins";</span>
<span class="st">@import "base/placeholders";</span>
<span class="st">@import "modules/buttons";</span>
<span class="st">@import "layout/nav";</span></code></pre>
<p><code>sass/base/_colors.scss</code></p>
<pre class="sourceCode css"><code class="sourceCode css">// Base Colors
$grey<span class="dv">:</span> <span class="fl">#ccc</span>;
$white<span class="dv">:</span> <span class="fl">#fff</span>;
$blue<span class="dv">:</span> <span class="fl">#3498DB</span>;//peter-river blue
$green<span class="dv">:</span> <span class="fl">#2ecc71</span>;</code></pre>
<p><code>sass/base/_mixins.scss</code></p>
<pre class="sourceCode css"><code class="sourceCode css">@mixin box-shadow($def) <span class="kw">{</span>
<span class="kw">-moz-box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">-webkit-box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">box-shadow:</span> $def<span class="kw">;</span>
<span class="kw">}</span>
// Example of using default
// as a fallback
$default-radius<span class="dv">:</span> 5px !default;
@mixin border-radius($radius<span class="dv">:</span> $default-radius) <span class="kw">{</span>
<span class="kw">-moz-border-radius:</span> $radius<span class="kw">;</span>
<span class="kw">-webkit-border-radius:</span> $radius<span class="kw">;</span>
<span class="kw">-ms-border-radius:</span> $radius<span class="kw">;</span>
<span class="kw">border-radius:</span> $radius<span class="kw">;</span>
<span class="kw">}</span>
@mixin horizontal-navbar <span class="kw">{</span>
<span class="kw">margin:</span> <span class="dt">0</span> <span class="dt">auto</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0</span><span class="kw">;</span>
<span class="kw">list-style:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="er">li</span> <span class="er">a</span> <span class="er">{</span>
<span class="kw">display:</span> <span class="dt">inline-block</span><span class="kw">;</span>
<span class="kw">padding:</span> <span class="dt">0.5em</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">font-weight:</span> <span class="dt">normal</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="er">&:hover</span> <span class="er">{</span>
<span class="kw">color:</span> darken($white, <span class="dt">2%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> lighten($blue, <span class="dt">5%</span>)<span class="kw">;</span>
<span class="kw">}</span>
}
}</code></pre>
<p><code>sass/base/_placeholders.scss</code></p>
<pre class="sourceCode css"><code class="sourceCode css">%button <span class="kw">{</span>
<span class="kw">padding:</span> <span class="dt">.5em</span> <span class="dt">1.2em</span><span class="kw">;</span>
<span class="kw">font-size:</span> <span class="dt">1em</span><span class="kw">;</span>
<span class="kw">color:</span> $white<span class="kw">;</span>
<span class="kw">background-color:</span> $green<span class="kw">;</span>
<span class="kw">text-decoration:</span> <span class="dt">none</span><span class="kw">;</span>
<span class="kw">border:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="er">@include</span> <span class="kw">box-shadow</span><span class="er">(0px</span> <span class="er">2px</span> <span class="er">4px</span> <span class="er">$grey);</span>
<span class="er">&</span><span class="kw">:</span>hover {
color: darken($white, <span class="dt">5%</span>)<span class="kw">;</span>
<span class="kw">background-color:</span> lighten($green, <span class="dt">10%</span>)<span class="kw">;</span>
<span class="kw">}</span>
}</code></pre>
<p><code>sass/modules/_buttons.scss</code></p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">.button</span> <span class="kw">{</span>
<span class="er">@extend</span> <span class="er">%button;</span>
<span class="kw">}</span>
<span class="fl">.rounded-button</span> <span class="kw">{</span>
<span class="er">@extend</span> <span class="er">%button;</span>
<span class="er">@include</span> <span class="kw">border-radius</span><span class="er">(5px);</span>
<span class="er">}</span></code></pre>
<p><code>sass/layout/_nav.scss</code></p>
<pre class="sourceCode css"><code class="sourceCode css"><span class="fl">#nav</span> <span class="kw">{</span>
<span class="kw">background-color:</span> $blue<span class="kw">;</span>
<span class="kw">border-bottom:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="kw">border-top:</span> <span class="dt">1px</span> <span class="dt">solid</span> $grey<span class="kw">;</span>
<span class="er">@include</span> <span class="kw">box-shadow</span><span class="er">(0px</span> <span class="er">4px</span> <span class="er">5px</span> <span class="er">$grey);</span>
<span class="er">@include</span> <span class="er">horizontal-navbar;</span>
<span class="er">margin-bottom</span><span class="kw">:</span> <span class="dt">2em</span><span class="kw">;</span>
<span class="kw">}</span></code></pre>
<p>As you can see, not much has actually changed and we’ve simply restructured our Sass. But by using partials as we have (using th<code>@import</code> directive) we’ve moved our Sass code into much more managable modules that will make our lives much easier as the project grows.</p>
</section>
</section>
</section>
<section class="level2" id="summary-1">
<h2><a href="#TOC">Summary</a></h2>
<p>So we’ve now seen the power of Compass and Sass combined and have a better understanding of the basic syntax that’s used to author Sass <code>.scss</code> files. We’ve purposely used these tools in isolation to get a better understanding of how they work on their own.</p>
<a id="yeoman"></a>
</section>
</section>
<section class="level1" id="yeoman-1">
<h1><a href="#TOC">Yeoman</a></h1>
<p>In this chapter we’ll be having a look at the workhorse workflow tool <a href="http://yeoman.io/">Yeoman</a>. Yeoman’s core consists of three tools: <a href="https://github.com/yeoman/yo">Yo</a>, <a href="http://gruntjs.com/">Grunt</a>, and <a href="http://bower.io/">Bower</a>. We will go over each in depth.</p>
<p><em>If you haven’t read the <strong>Setting Up</strong> chapter, go read that and ensure you’re properly set up to use Yeoman.</em></p>
<section class="level2" id="what-is-yeoman">
<h2><a href="#TOC">What is Yeoman?</a></h2>
<p>At its heart, Yeoman is a workflow power-tool that provides a suite of popular front-end tools to facilitate developing with best practices and efficient workflow. It’s pioneers, <a href="http://addyosmani.com/blog/">Addy Osmani</a> and <a href="http://www.paulirish.com/">Paul Irish</a>, are deeply commited to making the modern web development process better and faster. While there are a ton of tools available in the Yeoman eco-system, its imperative to learn its core tools first. Let’s dig in.</p>
</section>
<section class="level2" id="yo">
<h2><a href="#TOC">Yo</a></h2>
<p>The first core tool we’ll look at is Yo, Yeoman’s scaffolding tool that helps you to efficiently bootstrap projects. It not only scaffolds out your app, but also gives you sensible default configuration files that get you up and running quickly.</p>
<p>With Yo, there are three main things to learn:</p>
<ul>
<li>How to use Yo to bootstrap a project</li>
<li>How to install custom generators</li>
<li>How to create your own custom generators</li>
</ul>
<p>We’ll put off learning how to build a custom generator for a later chapter and now have a look at common <code>Yo</code> use.</p>
<section class="level3" id="installing-generators">
<h3><a href="#TOC">Installing Generators</a></h3>
<p>Perhaps you’d like to use the venerable <a href="http://backboneboilerplate.com/">Backbone Boilerplate</a> via Yeoman. To do so you would first need to install the generator:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">npm <span class="kw">install</span> -g generator-bbb</code></pre>
<p><em>This assumes you’ve installed node.js (which bundles <code>npm</code>).</em></p>
<p>Next you would simply create a project directory and issue the <code>yo bbb</code> command as follows:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">mkdir</span> project <span class="kw">&&</span> <span class="kw">cd</span> <span class="ot">$_</span> <span class="kw">&&</span> yo bbb</code></pre>
<p>As usual, you can build and preview your Yeoman project using grunt as follows:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">grunt server</code></pre>
<p>As you may have noticed, we’ve installed the <code>generator-bbb</code>, but used <code>bbb</code> when issuing the <code>yo</code> command. This seems to be an undocumented idiom as <code>generator-angular</code> would be triggered with <code>yo angular</code>, etc.</p>
</section>
</section>
<section class="level2" id="grunt">
<h2><a href="#TOC">Grunt</a></h2>
<p>The next core tool we’ll have a look at is Yeoman’s build tool extraordinaire <a href="http://gruntjs.com/">Grunt</a> authored by <q>Cowboy</q> <a href="http://benalman.com/">Ben Alman</a>. Grunt allows you to efficiently build and deploy your application, run tests, and preview your changes instantaneously. It’s used by Twitter, jQuery, and <a href="http://gruntjs.com/who-uses-grunt">many other high-profile projects</a>. Grunt has a mountain of features and plugins available and we’ll only be covering some of them here; of course you can always reference their <a href="http://gruntjs.com/getting-started">docs</a> once you’re comfortable with the basics.</p>
<p><em>Note that Grunt’s sweet-spot is task-based configuration management (much like Ant or Make but in JavaScript/Node.js), where you’re files are built as appropriately for production, testing, development environments, etc. As such, much of the documentation and tutorials you’ll find on Grunt will already address these sorts of tasks. In order to get a more general understanding of Grunt, we’ll be using much simpler if not slightly pedantic examples. Using this basic knowledge as a point of departure, you should then be able to utilize Grunt for more practical purposes.</em></p>
<p>The basics of how Grunt’s command line system works are as follows:</p>
<ul>
<li>you run the Grunt CLI in a project directory that contains a <code>Gruntfile.js</code></li>
<li>the Grunt CLI runner loads the grunt library</li>
<li>using the configurations found in that <code>Gruntfile.js</code> it then executes the task(s) as you’ve requested</li>
</ul>
<p><em>If you’re in a project directory and its dependencies have not yet been loaded, you’ll need to do so with</em>:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">npm <span class="kw">install</span></code></pre>
<p>However, before we get in to usage, let’s have a quick look at some of the parts of Grunt.</p>
<section class="level3" id="package.json">
<h3><a href="#TOC">package.json</a></h3>
<p>The <code>package.json</code> file is just a simple JSON file that declaratively specifies which dependencies should be included in your Grunt based project. See Grunt’s documentation on the <a href="http://gruntjs.com/getting-started#package.json">package.json</a> for more information and an example on how this works. Luckily, when using Yeoman, we get a nice default <code>package.json</code> which can serve as a starting point for further customization.</p>
<p>Besides hand editing the <code>package.json</code> file itself, you can choose to install new packages with the following general syntax:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">npm <span class="kw">install</span> PACKAGE --save-dev</code></pre>
<p>(where <code>PACKAGE</code> is grunt plugin you want to install. Obviously, the plugin comes as an <code>npm</code> package). This will both install the package and add it to your <code>package.json</code> configuration file.</p>
</section>
<section class="level3" id="gruntfile">
<h3><a href="#TOC">Gruntfile</a></h3>
<p>The <code>Gruntfile.js</code> is simply a JavaScript file that contains your project’s configuration and tasks. What’s a task? A task is a single chunk of work you need to get something done. For example, one task might be to compress certain types of images, another to copy files from one directory to another, etc. We’ll learn more about these by example so hold tight and it will all make more sense.</p>
<p>This <code>Gruntfile.js</code> should be placed at the root directory of your project (as with the <code>package.json</code> file discussed earlier). Taking a very high-level look at the contents of a typical <code>Gruntfile.js</code> we will find the following components:</p>
<ul>
<li>An outer <q>wrapper</q> function</li>
</ul>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">module</span>.<span class="fu">exports</span> = <span class="kw">function</span>(grunt) {
<span class="co">// ...</span>
};</code></pre>
<ul>
<li>An initial configuration section:</li>
</ul>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">grunt</span>.<span class="fu">initConfig</span>({
<span class="co">// ...</span>
});</code></pre>
<p>If you’re familiar with JavaScript (and you better be for this book), you’ll notice that <code>initConfig</code> is passed an <em>object literal</em>. That object literal represents a <q>configuration object</q> that will thereafter be available throughout the <code>Gruntfile.js</code> as <code>grunt.config</code>. The general purpose of this section is to set up any global initialization or bootstrapping required by your Grunt tasks.</p>
<ul>
<li>Default task</li>
</ul>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">grunt</span>.<span class="fu">registerTask</span>(<span class="ch">'default'</span>, [<span class="ch">'task1'</span>, <span class="ch">'task2'</span>]);</code></pre>
<p>The <code>registerTask</code> method is a general purpose means for registering Grunt tasks. It just so happens that here we’ve specified <q>default</q> task which will be run by Grunt when we issue <code>grunt</code> without specifying any additional arguments.</p>
<p>Another example of using <code>registerTask</code>, can be seen from the boiler-plate generated by Yeoman when you run <code>yo webapp</code>. If you look at that generated <code>Gruntfile.js</code> it will contain something like:</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"> <span class="kw">grunt</span>.<span class="fu">registerTask</span>(<span class="ch">'test'</span>, [
<span class="ch">'clean:server'</span>,
<span class="ch">'concurrent:test'</span>,
<span class="ch">'connect:test'</span>,
<span class="ch">'mocha'</span>
]);</code></pre>
<p>In this case, the task name is called <code>test</code>, and will, in turn, run a set of test related tasks.</p>
<p>We’ll learn more about the power of registering tasks later, but this should suffice for having an initial understanding of what’s going on. You may want to take a quick break and try the following from an arbitrary directory of your choosing:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">mkdir</span> tmp <span class="kw">&&</span> <span class="kw">cd</span> <span class="ot">$_</span> <span class="kw">&&</span> yo webapp
<span class="kw">cat</span> Gruntfile.js <span class="co"># or just open in an editor</span></code></pre>
<p>Using your editor or <q>grep-fu</q>, find all the places in that file that use <code>grunt.registerTask</code>. It should be contextually evident what going on. Congratulations! You’ve now got a bit more of an idea what task Yeoman is helping you with out of the box.</p>
</section>
<section class="level3" id="grunt-init">
<h3><a href="#TOC">Grunt Init</a></h3>
<p>Let’s now perform the obligatory <em>Hello World</em> using Grunt.</p>
<p>As Grunt 0.4 onwards has completely modularized the Grunt system, each component is installed independently. Let’s grab some convenient packages for Gruntfile authoring:</p>
<pre class="sourceCode bash"><code class="sourceCode bash">git clone https://github.com/gruntjs/grunt-init-gruntfile.git ~/.grunt-init/gruntfile
npm <span class="kw">install</span> -g grunt-init
<span class="kw">mkdir</span> myproject <span class="kw">&&</span> <span class="kw">cd</span> <span class="ot">$_</span>
grunt-init gruntfile</code></pre>
<p>For this exercise go ahead and answer No for all of Grunt init’s questions. This should place a boiler-plate <code>Gruntfile.js</code> file in your <code>myproject</code> directory.</p>
<figure>
<img src="img/grunt-init.png" title="Initializing an empty Grunt project" alt="Initializing an empty Grunt project"><figcaption>Initializing an empty Grunt project</figcaption>
</figure>
<p>As you can see, we’ve used <code>grunt-init gruntfile</code> to scaffold out an initial <code>Gruntfile.js</code>. Let’s remove everything in the file for this exercise except for the following <q>wrapper</q> function:</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="ch">'use strict'</span>;
<span class="kw">module</span>.<span class="fu">exports</span> = <span class="kw">function</span>(grunt) {
};</code></pre>
<p>Now create a package.json with the following:</p>