{"componentChunkName":"component---src-pages-author-author-yaml-id-js","path":"/author/zakary-hughes/","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"id":"3ee87568-86e5-5245-8c7b-abd9f8531df6","html":"<p>Manipulating collections like arrays and objects can be a hassle with vanilla JS. Thankfully there are libraries like Underscore which offer some extremely useful low level utility functions.</p>\n<p>Underscore JS provides much of the array/collection/object manipulating functionality similar to what you may have seen in other languages such as Ruby. As for calling the methods if you're familiar with JQuery, Underscore is identical except instead of \"$\" we use the library's namesake \"_\" to access the methods.</p>\n<p>Underscore has over 100 functions that can be used on collections, arrays, objects and functions (you read that right, function functions). I'm going to be discussing a few of the functions that work on collections, but definitely check out what else <a href=\"http://underscorejs.org/\">Underscore has to offer</a>.</p>\n<p>Once you know how to re-create the same output with Underscore syntax, you'll never want to go back to plain old JS and using nested for loops. One of the most helpful tools Underscore provides for accomplishing this is...</p>\n<h2 id=\"_each\" style=\"position:relative;\"><a href=\"#_each\" aria-label=\"_each permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>_.each</h2>\n<p>The _each method does exactly what it sounds like. It works on collections (arrays or objects), and will iterate over each element in the collection invoking the function you specified with 3 arguments (value, index, list) with index being replaced by key if used on an object. It's also worth noting _.each returns the list if you want chain some more manipulation after calling _.each.</p>\n<p>Here's a quick example showing how it can be used and what's available to you when you call it.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">someArray</span><span class=\"mtk1\"> = [</span><span class=\"mtk8\">&quot;a&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;b&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;c&quot;</span><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">_</span><span class=\"mtk1\">.</span><span class=\"mtk11\">each</span><span class=\"mtk1\">(</span><span class=\"mtk12\">someArray</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">element</span><span class=\"mtk1\">, </span><span class=\"mtk12\">index</span><span class=\"mtk1\">, </span><span class=\"mtk12\">list</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;value: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">element</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&quot; index: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">index</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&quot; list: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">list</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// outputs</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">value: </span><span class=\"mtk12\">a</span><span class=\"mtk1\"> index: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> list: </span><span class=\"mtk12\">a</span><span class=\"mtk1\">,</span><span class=\"mtk12\">b</span><span class=\"mtk1\">,</span><span class=\"mtk12\">c</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">value: </span><span class=\"mtk12\">b</span><span class=\"mtk1\"> index: </span><span class=\"mtk7\">1</span><span class=\"mtk1\"> list: </span><span class=\"mtk12\">a</span><span class=\"mtk1\">,</span><span class=\"mtk12\">b</span><span class=\"mtk1\">,</span><span class=\"mtk12\">c</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">value: </span><span class=\"mtk12\">c</span><span class=\"mtk1\"> index: </span><span class=\"mtk7\">2</span><span class=\"mtk1\"> list: </span><span class=\"mtk12\">a</span><span class=\"mtk1\">,</span><span class=\"mtk12\">b</span><span class=\"mtk1\">,</span><span class=\"mtk12\">c</span></span></code></pre>\n<p>With that out of the way, let's think about what this means in terms of cleaning up our code. To do the above normally we would write a little for loop like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">for</span><span class=\"mtk1\"> ( </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> &</span><span class=\"mtk12\">lt</span><span class=\"mtk1\">; </span><span class=\"mtk12\">someArray</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;value: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">someArray</span><span class=\"mtk1\">[</span><span class=\"mtk12\">i</span><span class=\"mtk1\">] + </span><span class=\"mtk8\">&quot; index: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&quot; list: &quot;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">someArray</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Admittedly these two aren't all that different, but let's imagine we have a function defined elsewhere that will deal with handling the arguments passed in on each iteration. We can replace that same functionality with a significantly less verbose solution.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">_</span><span class=\"mtk1\">.</span><span class=\"mtk11\">each</span><span class=\"mtk1\">(</span><span class=\"mtk12\">someArray</span><span class=\"mtk1\">, </span><span class=\"mtk12\">doStuff</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>To quote Antoine de Saint Exupéry: \"It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove.\" While it may not be perfection, there are certainly arguments to be made about performance, I think you would be hard pressed to find anything further simplify this code.</p>\n<h2 id=\"_map\" style=\"position:relative;\"><a href=\"#_map\" aria-label=\"_map permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>_.map</h2>\n<p>While _.each will return the original list you input, _.map will allow you to manipulate or otherwise transform the input as you please and then returns the new array. Map needs a minimum of 2 arguments, first the collection and then the function to be executed on each iteratee and also accepts a third argument which dictates the context for the iterating function.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">numbersObject</span><span class=\"mtk1\"> = {</span><span class=\"mtk7\">1</span><span class=\"mtk12\">:</span><span class=\"mtk7\">1</span><span class=\"mtk1\">, </span><span class=\"mtk7\">2</span><span class=\"mtk12\">:</span><span class=\"mtk7\">4</span><span class=\"mtk1\">, </span><span class=\"mtk7\">3</span><span class=\"mtk12\">:</span><span class=\"mtk7\">9</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">productArray</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">_</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">numbersObject</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">value</span><span class=\"mtk1\">, </span><span class=\"mtk12\">key</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\"> * </span><span class=\"mtk12\">key</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//proudctArray is now</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">[</span><span class=\"mtk7\">1</span><span class=\"mtk1\">, </span><span class=\"mtk7\">8</span><span class=\"mtk1\">, </span><span class=\"mtk7\">27</span><span class=\"mtk1\">]</span></span></code></pre>\n<p>Before you go writing some functions to pass as an argument to _.map be sure to take a peek at the other methods available in Underscore. Map is a little bit like having the Lego blocks to build whatever you want, but if you already have a pre-packaged Batcave available, it might not be the best use of your time building it from scratch.</p>\n<h2 id=\"_pluck\" style=\"position:relative;\"><a href=\"#_pluck\" aria-label=\"_pluck permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>_.pluck</h2>\n<p>To illustrate my childhood toy analogy let's talk about _.pluck. Pluck is basically just a refined version of _.map made for a specific use case. That's not to say there aren't ways of combining the two to achieve something a little more complex, but if standard _.pluck behaviour is all you're after then don't go re-inventing the wheel.</p>\n<p>Often with data objects we're interested in the values of a specific key, for example let's say we have an array of movies.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">movies</span><span class=\"mtk1\"> = [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Dracula&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">genre:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Horror&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">star:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Nosferatu&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Cast Away&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">genre:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Drama&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">star:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Wilson&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">title:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Airplane&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">genre:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Comedy&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">star:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Leslie Nielsen&quot;</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">];</span></span></code></pre>\n<p>Now we want to just have an array of the titles of these movies.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">titlesArray</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">_</span><span class=\"mtk1\">.</span><span class=\"mtk11\">pluck</span><span class=\"mtk1\">(</span><span class=\"mtk12\">movies</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;title&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//titlesArray is now</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;Dracula&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;Cast Away&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;Airplane&quot;</span><span class=\"mtk1\">]</span></span></code></pre>\n<p>Not much else to say about it, it works on collections and is extremely handy for a very common task.</p>\n<h2 id=\"_filter\" style=\"position:relative;\"><a href=\"#_filter\" aria-label=\"_filter permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>_.filter</h2>\n<p>Another example of a more refined _.map function that comes in handy often enough. Aptly named this method will return an array of only the things that make it through your test.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">numbers</span><span class=\"mtk1\"> = [</span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span><span class=\"mtk7\">33</span><span class=\"mtk1\">,</span><span class=\"mtk7\">6</span><span class=\"mtk1\">,</span><span class=\"mtk7\">24</span><span class=\"mtk1\">,</span><span class=\"mtk7\">8</span><span class=\"mtk1\">,</span><span class=\"mtk7\">21</span><span class=\"mtk1\">,</span><span class=\"mtk7\">11</span><span class=\"mtk1\">,</span><span class=\"mtk7\">22</span><span class=\"mtk1\">];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lessThanTen</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">_</span><span class=\"mtk1\">.</span><span class=\"mtk11\">filter</span><span class=\"mtk1\">(</span><span class=\"mtk12\">numbers</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">number</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">number</span><span class=\"mtk1\"> &</span><span class=\"mtk12\">lt</span><span class=\"mtk1\">; </span><span class=\"mtk7\">10</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//lessThanTen is now</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">[</span><span class=\"mtk7\">1</span><span class=\"mtk1\">, </span><span class=\"mtk7\">6</span><span class=\"mtk1\">, </span><span class=\"mtk7\">8</span><span class=\"mtk1\">]</span></span></code></pre>\n<p>Works on collections and kitchen sink faucets.</p>\n<h2 id=\"_conclusion\" style=\"position:relative;\"><a href=\"#_conclusion\" aria-label=\"_conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>_.conclusion</h2>\n<p>Just kidding there's no _.conclusion method.</p>\n<p>I hope by now that you get the idea that if what you need to do isn't already a method, Underscore's _.map is a powerful tool for accomplishing whatever obscure collection manipulation your heart desires.</p>\n<p>So get out there, take a look through Underscore JS and start writing less obfuscated (nested) for loops with the help of _.each.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n</style>","frontmatter":{"title":"Be More Manipulative with Underscore JS","author":{"id":"Zakary Hughes","github":null,"avatar":null},"date":"February 16, 2016","updated_date":null,"tags":["JavaScript","UnderscoreJs"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/11ed52d59476d63d8b5a6688fb02bdb9/ee604/underscore.png","srcSet":"/static/11ed52d59476d63d8b5a6688fb02bdb9/69585/underscore.png 200w,\n/static/11ed52d59476d63d8b5a6688fb02bdb9/497c6/underscore.png 400w,\n/static/11ed52d59476d63d8b5a6688fb02bdb9/ee604/underscore.png 800w,\n/static/11ed52d59476d63d8b5a6688fb02bdb9/f3583/underscore.png 1200w,\n/static/11ed52d59476d63d8b5a6688fb02bdb9/e4d72/underscore.png 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}}},"fields":{"authorId":"Zakary Hughes","slug":"/engineering/be-more-manipulative-with-underscore-js/"}}},{"node":{"id":"ea653944-e648-5e66-8478-0c1673fe198f","html":"<p>If you're not familiar with Angular I'd highly recommend heading over to the <a href=\"https://angularjs.org/\">Angular JS</a> resource site and checking out what all the fuss is about. Once you've got a basic understanding of Angular and how to get it up and running this tutorial will show you some of the basic, but awesome features supported by Angular.</p>\n<p>Today I'm going to be building out a roster for my fantasy football team. If that's not your cup of tea then by all means feel free to substitute the content for whatever floats your boat.</p>\n<h2 id=\"players-array\" style=\"position:relative;\"><a href=\"#players-array\" aria-label=\"players array permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Players Array</h2>\n<p>There might not be an I in team, but there are certainly players, so before we do anything in the HTML we'll have to make all the necessary components in the controller. First up let's make an array of all the players we want to include (initially at least) on our team.</p>\n<p>Every player is a special little snowflake, and our player objects should reflect that! With this in mind we will make each player an object with his or her own properties like: name, position and team. Here's an example of what our array might look like.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">players</span><span class=\"mtk1\"> = [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Tom Brady&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">position:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;QB&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">team:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Patriots&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Tony Romo&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">position:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;QB&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">team:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Cowboys&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Peyton Manning&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">position:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;QB&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">team:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Broncos&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Rob Gronkowsi&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">position:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;TE&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">team:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Patriots&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;JJ Watt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">position:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;DE&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">team:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Texans&quot;</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Lavonte David&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">position:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;LB&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">team:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Buccaneers&quot;</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">];</span></span></code></pre>\n<h2 id=\"repetitive-department-of-repetition\" style=\"position:relative;\"><a href=\"#repetitive-department-of-repetition\" aria-label=\"repetitive department of repetition permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Repetitive department of repetition</h2>\n<p>Now that we have our roster we can go back to the HTML and make use of Angular's ng-repeat directive. We put the ng-repeat on the element we want to be repeated, keeping in mind that all of its children will also get repeated.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {{</span><span class=\"mtk12\">player</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk1\">}} - {{</span><span class=\"mtk12\">player</span><span class=\"mtk1\">.</span><span class=\"mtk12\">position</span><span class=\"mtk1\">}}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>Okay so if you're new to Angular there's a couple of things going on here. First like I said we've got the ng-repeat placed on the li (the thing we want repeated) which will create a new li for each player in the players array we defined earlier in the controller. Next up the data binding is being implemented here with each player name as well as position being used as the values for the list item.</p>\n<p>While we're on the topic of data binding, let's throw this in just for fun. Pretty simple, it will calculate the length of your roster and keep it updated as any changes are made.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span><span class=\"mtk12\">You</span><span class=\"mtk1\"> </span><span class=\"mtk12\">have</span><span class=\"mtk1\"> {{</span><span class=\"mtk12\">players</span><span class=\"mtk1\">.</span><span class=\"mtk12\">length</span><span class=\"mtk1\">}} </span><span class=\"mtk12\">on</span><span class=\"mtk1\"> </span><span class=\"mtk12\">your</span><span class=\"mtk1\"> </span><span class=\"mtk12\">roster</span><span class=\"mtk1\">.--&gt;</span></span></code></pre>\n<h2 id=\"easiest-search-functionality-of-your-life\" style=\"position:relative;\"><a href=\"#easiest-search-functionality-of-your-life\" aria-label=\"easiest search functionality of your life permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Easiest Search Functionality of Your Life</h2>\n<p>Next let's add some search functionality to our list. Sounds like a lot of work, probably have to iterate over the array elements, match them to the argument being passed in and... just kidding. With Angular it's a breeze.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{{</span><span class=\"mtk12\">player</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk1\">}} - {{</span><span class=\"mtk12\">player</span><span class=\"mtk1\">.</span><span class=\"mtk12\">position</span><span class=\"mtk1\">}}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>Donezo.</p>\n<h2 id=\"the-shape-of-italy\" style=\"position:relative;\"><a href=\"#the-shape-of-italy\" aria-label=\"the shape of italy permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The shape of Italy</h2>\n<p>Let's imagine one of our fantasy players isn't performing too well (ahem Peyton...) and we want to give him the boot (get it now?).</p>\n<p>We'll add a little delete button beside each of our players' names, and since we're doing it for each of them guess how we're going to implement it? That's right with ng-repeat we already have on the list items!</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--{{</span><span class=\"mtk12\">player</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk1\">}} - {{</span><span class=\"mtk12\">player</span><span class=\"mtk1\">.</span><span class=\"mtk12\">position</span><span class=\"mtk1\">}}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ×</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>I'll also tack on a little button with an \"x\" as the content (as a side note, when you want to do this use × instead of \"x\" it looks much nicer). Then we'll attach an ng-click with a delete function where we pass in $index.</p>\n<p>$index is a neat little feature available with certain Angular directives, and ng-repeat is one of them. It will be assigned the index value (starting at 0) of the position it holds within the array being used with the ng-repeat.</p>\n<p>That's all we need in the HTML, so now back in the controller we create a $scope function by the same name used in the HTML and give it a parameter of index. The body of the function is a single line which makes use of the array.splice method where we pass in the index of the item we want to delete, and then 1 to denote that it's only 1 item we want removed.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk11\">delete</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">index</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">players</span><span class=\"mtk1\">.</span><span class=\"mtk11\">splice</span><span class=\"mtk1\">(</span><span class=\"mtk12\">index</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<h2 id=\"acquisitions\" style=\"position:relative;\"><a href=\"#acquisitions\" aria-label=\"acquisitions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Acquisitions</h2>\n<p>Now since we just cut someone from the team, we've gotta find their replacement. Let's chuck a few text inputs in there, give them all a respective ng-model to bind with their value and finally another button with an ng-click but this time calling an addPlayer function.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Name:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Position:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Team:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Add</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Player</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>This one's a lil' different from delete, but still super simple. Working from the inside out, we will create a new player object which gets the name, position and team properties from the ng-models on the HTML and then push that object to the players array. After that we clear those values just for some good housekeeping practice.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk11\">add</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> () {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">players</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">new_name</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">position:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">new_position</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">team:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">new_team</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">new_name</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">new_position</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$scope</span><span class=\"mtk1\">.</span><span class=\"mtk12\">new_team</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<h2 id=\"nothing-lasts-forever\" style=\"position:relative;\"><a href=\"#nothing-lasts-forever\" aria-label=\"nothing lasts forever permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nothing Lasts Forever</h2>\n<p>Now since this was all done purely on the front end, and didn't make use of cookies, localstorage, or sessionstorage none of this will persist (aka be saved). For that kind of support you'd need some sort of back end, which is beyond the scope of this article.</p>\n<p>This was a very rudimentary example of what's possible with Angular JS, so if this interested you at all please dig a little deeper and play around with Angular some more!</p>\n<p>That brings us to the end of this tutorial. Feel free to check out the finished (yet unstyled) product <a href=\"https://codepen.io/anon/pen/pgoJwq\">here on Codepen</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"title":"Angular Roster Tutorial","author":{"id":"Zakary Hughes","github":null,"avatar":null},"date":"January 12, 2016","updated_date":null,"tags":["Engineering","AngularJS","PlayersArray","Array","Search"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/2773860898be140904449814ad319431/ee604/roster-angularjs-1.png","srcSet":"/static/2773860898be140904449814ad319431/69585/roster-angularjs-1.png 200w,\n/static/2773860898be140904449814ad319431/497c6/roster-angularjs-1.png 400w,\n/static/2773860898be140904449814ad319431/ee604/roster-angularjs-1.png 800w,\n/static/2773860898be140904449814ad319431/40ffe/roster-angularjs-1.png 960w","sizes":"(max-width: 800px) 100vw, 800px"}}}},"fields":{"authorId":"Zakary Hughes","slug":"/engineering/angular-roster-tutorial/"}}},{"node":{"id":"6c1bd964-4f8e-5fd9-a592-2ffefd86b4bd","html":"<p>What's one thing virtually every website has? If you said navigation (you did) you're absolutely right! Go ahead and enjoy that wonderful feeling of being right for a moment... and now that we're feeling like a champ, let's get to it.</p>\n<p>Navigation buttons, depending on your site of course, are likely going to be some of the most commonly used items on your web site. Typically they're found near the top so people can quickly and easily... well navigate of course! With this in mind it's worth it to make sure your navigation is both visually appealing and provides an enjoyable user experience.</p>\n<p>A common featured for navigation menus is the drop down functionality for displaying sub options. This can be achieved through Javascript if you really feel like it (you don't), but why bother with that when CSS3 offers a much more elegant solution!</p>\n<p>First we start out building a simple un-ordered list, and give it some list items each of which contain a link that point nowhere in particular.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 67.30158730158729%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABIUlEQVQoz42R4U7FIAyF9xaupUBp2dhYFnO3GX/4/u9l0Ru9U3OvDSGHhI9zWroyzdtUXrMkcomoB2cLAQGwtx3RVN9ftTtXV2tl5pV5yTLluA6kCYh9ZMoJYkTHXhglYQwOz9XNtS7j+JKF2TPjIKAJXfSB2ysxNJ0iGv8HvKzrolpHSYWLwqCOiCwzfsaGm9iAP+F928h7U7NI4mh9D5rGsWTV6Ok3cIKP/YghAMCsatmd0JB1LCXnHL2/y2K3bVtoMFYRMWdrVZKR7RQC3ocvl0v4uDTdwC2EqiZ+AB/HYfBTD7MxKVLrWa3nxlqih7ANqkiyeXvnkJC+yrkHztu+P8/z2zi4Ntur033Db1izWmx/9vgvbGPy9iXwz/unegd3qFlcbCazsAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen1\"\n        title=\"dropdownscreen1\"\n        src=\"/static/4d73eddb787ac320f85c2e9a1d005f82/f058b/dropdownScreen1.png\"\n        srcset=\"/static/4d73eddb787ac320f85c2e9a1d005f82/f058b/dropdownScreen1.png 630w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>By the way, if you're on Sublime Text there's a great shortcut for making lists: ul>li+li+li+li and then \"Tab\" creates an un-ordered list with 4 list item tags inside of it. For more excellent Sublime tips check out my amigo Lucius' <a href=\"/beginners-guide-for-sublime-text/\">blog post</a> on the topic.</p>\n<p>Now that we've got the bare bones, let's give this skeleton a spine. We're now going to put another ul inside of those list items, and once again more list items inside of those lists which contain, you guessed it, links to nowhere.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 556px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 119.78417266187051%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAAAsTAAALEwEAmpwYAAACkUlEQVQ4y5VUCW7jMAz0KxrdB0VJvh0njuO47e7/f7W0e6Bo0l0sEQSwKB4zHKqo66aryt8pVNa0RltjuRBSSrEbF99NfrGiadsIMHiXrfHeZqucURRLPiWFUttP7h9qOxQfaTcruq5z3pfOnZ2FCC2qJssKmULrUFeRZeQKtA26Rp6Qg1ef7RRVXbc5P0fQ6JzlwXPvpVLyW7dbwPczUYzjiABoTaqwRI2egaVzxZjk94i/BV+vs3PuwDhBK513ZdCVO3VpmZtxqKkb/nOO4nK5eO8F54xv16oI56Ysj9ie7DqP0+U6HYdTmZOz7C5LMU2T944cWuscIDlnqGcpGLWutDaGhme0VlI+qLwHe8aYt7bDIJxWTsbgAwRKqqUkF/uh9WKeZwomLxM8aKItQBP6FpYZp7HKMVJVu1fmjzF/sPLEWPRuqSocU+zdeplu68vLMs9t3QS4r/5WeQtWSiWACjxoI62SRoAj+fgYI5B+jLkHXSzLQjcOjNGNY0LptbAigsdAmMFbw9jhaYct/tI2uR0VrzH16TTiuuD13LbNpnywlvTOH4nk+kYYif/AebBmTtn2GFq7nE/z9XabL5embhB+IGzH/BZfgu8RCTpke+y7vh8GWp2cavDibtTFdN5FQnM2tovotaYlIIhPB35g/1D3+5x3hakGwCSvs+mreDrWTZPR2jc6+A+L8Y6Z3KSEnGDoymYMx8mul2E8nYe27WIkLh5oe13XT8JoJFRqLSs/ZhzgZbmuz6+/ntdb35FqHlS+3W40i/fKSmXwHaIvAUp7pEF1/XEY2pRK7x48BsS2s9ujR3qqQyAlbXn4x99fKSuu85xi7GgZ99zsn8/H1+DzeWqq6jUh7pRI8R/2B+Ses911k0eEAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen2\"\n        title=\"dropdownscreen2\"\n        src=\"/static/8f8aecc68ec3595359bda468281df807/96638/dropdownScreen2.png\"\n        srcset=\"/static/8f8aecc68ec3595359bda468281df807/96638/dropdownScreen2.png 556w\"\n        sizes=\"(max-width: 556px) 100vw, 556px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>That's all the HTML we have to write for this example, so now we move on to the CSS.</p>\n<p>The first few things on the ul's and links are just to remove some default styles that I don't care for.</p>\n<p>The first actually relevant style is the inline-block display property on the list items to make them spread out horizontally. If you're unfamiliar with using inline-block for positioning I highly recommend reading up on it because it's an awesome alternative to floats or sometimes even flex-box. Next up we give these list items a relative position, so that the later absolutely positioned sub menu will use this as a reference point.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 403px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 44.91315136476427%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8ElEQVQoz4WRy3LDIAxF/RcJ6IGweRibAIntZrrI//9WyUyXraPR9s45uhpCCOuykBslRI0MLMAGjAViMIhM+v8Z5nmutYoI+wWnhH7FkNFnsg4Xa5KDk3CM8ZYzeyfBI4AC7KtBaQa4KnVVH8iPxwMQaT349pTUYswQxJRAhPp03uFSChNR2rm+bCrNWer8y1V3YzgNd+1Wq3UOppGsAL5xoJTuwpdP2r2t4zhABHKT+jRhBS+YHaaJ13E6L+x+v+/b1mGUNm4vLt+cbtwa1rLGcQ8TMyv1N3/Y9+3rOH5f5RK6hazB2cJs2dve/snZPxwTQeyg3DYnAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen3\"\n        title=\"dropdownscreen3\"\n        src=\"/static/4d82753330425342c1f42b96cb22083d/045fd/dropdownScreen3.png\"\n        srcset=\"/static/4d82753330425342c1f42b96cb22083d/045fd/dropdownScreen3.png 403w\"\n        sizes=\"(max-width: 403px) 100vw, 403px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>To quote every MTV cribs star ever, here's where the magic happens. We put a max-height (that is at least as tall as all of the list items on the sub menu) and a height of auto on the sub menu. Note the ul li:hover, meaning these styles only apply when the first level of list items are hovered over. This might seem weird now, but it'll hopefully make sense with the styles we make use of in a bit.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 77.99607072691552%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABoklEQVQoz41TCY7iMBDML+Lbbt+E3CGBJAMz/3/VNqyEdnZXA21L7avULle5+Nh3CJ7Vg5pPchr9MUx9dHUUnLNXUSzLYsFIX0lf8+BVBEMZo9jYG+B5sTFwH6R1gjFNmeFcCM7eAV9vN9BKNKsev8ZD+mrcFJ0S8q3K5/PZOSdtFD6qDLIFpiUpyVuVz8g5eO6daCp5TJA8d1qCxj3+eLMfCBTrtuG1abXk3K5I3koGkitBCKGPwETIc/aNTbFtu9EK2stxvOzJjykqbYw2AGCdA2OCUjg25nc338Af16u1Frerqsp1u6/bclq6vhuGcd+v8zjeUjhNp3meu66fpklK+axfrOtqjeah4XmUhynXyVVBCCm4wHNSoGqoHI4xc1zgf5jnDvY5qRhExu5YNCoYJFg+2LK7X9iT7d+cL+sFrBWHXvWLams1HCEmy3nSSgtBX9rzoTOaLFMIFLwwNoPpUvTGEPoT/H5t/Bj8cFRdXTV+aJLVqiSk/EeY/4Bvn5/eggy1iK2LOXSVcRZh75i7GPoBpWKUMPQkJWVJXhZ8xi9mK3cU9EyKPQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen4\"\n        title=\"dropdownscreen4\"\n        src=\"/static/1d5e9e4972575f8d4caad87fa0fc90d1/71554/dropdownScreen4.png\"\n        srcset=\"/static/1d5e9e4972575f8d4caad87fa0fc90d1/71554/dropdownScreen4.png 509w\"\n        sizes=\"(max-width: 509px) 100vw, 509px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Next up we just give the links some padding, which is highly preferable to giving the list item padding because then you can end up with a small hitbox for the actual link and a bunch of dead space around it. Only other thing to note here is the display block on the link which is required for the absolute positioning used later.</p>\n<p>The .sub-menu styles are pretty basic, just give it a position of absolute and then top: 100%, left: 0 and width: 100% to make it sit flush below the first level of list items. Finally throw on a transition to really allow the animation to shine, and fine tune the timing if you'd like.</p>\n<p>Still on the .sub-menu we give it a max-height of 0 and overflow: hidden. What this does is it hides the element from our view, similar to display:none or visibility:hidden... but for our animation we have to do it this way!</p>\n<p>Lastly we give the sub menu list items and links a display of block and some colors because pretty.</p>\n<p>That's it, you've now got a simple dropdown navigation with a neat little animation! You can add a height of 0 to the ul .sub-menu as well for a slightly different effect, or play around with the transition time and effect. Much to the same effect, increasing the value of the max-height on the sub menu hover will have an effect on the time it takes the dropdowns to make it to the end.</p>\n<p><a href=\"https://codepen.io/anon/pen/bVKEwK\">Check it out on Codepen.</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"title":"CSS/HTML Animated Dropdown Navigation","author":{"id":"Zakary Hughes","github":null,"avatar":null},"date":"December 15, 2015","updated_date":null,"tags":["HTML","CSS","UI","CSS Animation"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/501f7fa9187224569eb6e51827f87931/630fb/drop-anim-300x300.png","srcSet":"/static/501f7fa9187224569eb6e51827f87931/69585/drop-anim-300x300.png 200w,\n/static/501f7fa9187224569eb6e51827f87931/630fb/drop-anim-300x300.png 300w","sizes":"(max-width: 300px) 100vw, 300px"}}}},"fields":{"authorId":"Zakary Hughes","slug":"/engineering/csshtml-animated-dropdown-navigation/"}}},{"node":{"id":"124b521c-6628-59b5-8268-c5380c73f6a3","html":"<p>As a preface to this article: preprocessors can be used for a variety of file types, but this article is going to focus solely on CSS preprocessors. Additonally I'm going to try and avoid my personal bias and give a very generic description of CSS preprocessors rather than my preferred preprocessor.</p>\n<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>First off what is a preprocessor? To give you a simple analogy think of speaking with someone, in a language you understand, who has a strong accent or is speaking in a different dialect. They're technically speaking the same language as you, but actually understanding what they're saying can be next to impossible.</p>\n<p>In the context of CSS, the \"normal\" or unaccented language would be CSS and the accented version would be the preprocessor! What this means in practice is that you're writing out expressions that resemble standard CSS, but with some very distinct differences with regards to its syntax.</p>\n<p>As with regular spoken language, there's not a whole lot we can do with something we can't understand. Luckily there are translators, and the same is true of preprocessors. The preprocessor code can be processed (there are a number of different ways to accomplish this), and then out pops an understandable standard-syntax CSS file ready to be used.</p>\n<p>Now why would we want to write CSS in some weird way you might ask? An excellent question! Because our nonsense can be translated into regular CSS, this allows us to write some very robust and even dynamic CSS expressions.</p>\n<h2 id=\"new-toys\" style=\"position:relative;\"><a href=\"#new-toys\" aria-label=\"new toys permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>New Toys</h2>\n<p>With preprocessors we've got a bundle of features now available to be used along with all the standard CSS rules we're accustomed to writing.</p>\n<p>To name a few features supported by preprocessors we've got: functions, mixins, math, variables, operators, conditionals, iteration and more to help you be more organized and write less overall.</p>\n<h3 id=\"variables\" style=\"position:relative;\"><a href=\"#variables\" aria-label=\"variables permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variables</h3>\n<p>Variables increase your maintainability drastically by making it so you only have to change a value in one place to affect it everywhere it was used. Imagine for example you want to add a Halloween theme to your site's colors.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.elementOne</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">orange</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.elementOne</span><span class=\"mtk1\"> </span><span class=\"mtk6\">p</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">black</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.elementTwo</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">orange</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">h3</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">black</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">a:hover</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color</span><span class=\"mtk1\">:</span><span class=\"mtk8\">orange</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Changing them back would require you to go and change each instance of black or orange. However; with variables you can do something like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">$</span><span class=\"mtk4\">theme-color-1</span><span class=\"mtk1\">: orange;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">$</span><span class=\"mtk4\">theme-color-2</span><span class=\"mtk1\">: black;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.elementOne</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: $theme-color-1;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.elementOne</span><span class=\"mtk1\"> </span><span class=\"mtk6\">p</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: $theme-color-2;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.elementTwo</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: $theme-color-1;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">h3</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: $theme-color-2;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">a:hover</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: $theme-color-1;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Define the value of the variable in one place, and everywhere it gets used will be a reference to that value. Want to change all instances of black back to grey? Just change the variable definition and you're done.</p>\n<h3 id=\"functions--friends\" style=\"position:relative;\"><a href=\"#functions--friends\" aria-label=\"functions  friends permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Functions &#x26; Friends</h3>\n<p>Another one of the biggest features would be functions. With these you can set up one well written function definition and then sit back and let it do all the heavy lifting for you!</p>\n<p>Functions combined with math, variables, iteration, and conditionals allows you to write some very dynamic style rules. Think of sprite sheets where the value of the background position is being incremented with each statement. Instead of writing out each one by hand, make a function that uses math and iteration to change the background position.</p>\n<p>That's a very simple example, but I've seen some truly impressive and complicated designs created with the use of functions!</p>\n<h3 id=\"selectors\" style=\"position:relative;\"><a href=\"#selectors\" aria-label=\"selectors permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Selectors</h3>\n<p>One of my favorite features of preprocessors are the new selectors. The parent reference (&#x26;) allows you to group your rules so that everything pertaining to a specific element can be grouped together nicely.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.someElement</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    some-rule: some-value;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    &amp;:hover {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">color</span><span class=\"mtk1\">: some-color;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Compiles to...</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.someElement</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    some-rule: some-value;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.someElement:hover</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: some-color;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The parent selector takes whatever follows it immediately and tacks it on to the parent that it is nested under. In this case hover will be appended to .someElement. Another great one to check out is the root reference!</p>\n<h2 id=\"nesting-and-general-aesthetic\" style=\"position:relative;\"><a href=\"#nesting-and-general-aesthetic\" aria-label=\"nesting and general aesthetic permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nesting and General Aesthetic</h2>\n<p>CSS's default format is ugly as sin. An endless tide of barely indented rules, hopefully organized in some meaningful way. With CSS preprocessors nesting is an awesome feature that helps your rules become more intuitive/logically grouped and increases readability. Nesting can give your CSS a much more distinct visual hierarchy not unlike HTML.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.someElement</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    some-rule: some-value;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .someOtherElement {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        some-rule: another-value</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Compiles to...</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.someElement</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    some-rule: some-value;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.someElement</span><span class=\"mtk1\"> </span><span class=\"mtk6\">.someOtherElement</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    some-rule: another-value;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Full disclosure, your resulting CSS file will still likely look like someone dropped their bowl of Alphaghetti in their bowl of Alphabits and then threw that bowl at a wall. However; the file you actually work in will be considerably prettier, and that's all we care about.</p>\n<p>Some people have beef with preprocessors because of over done selectors which are a result of going a little too hard with nesting. An easy way to avoid this is by limiting your nesting to 3 levels deep. Any further than that gets pretty ugly, but hey I'm not your supervisor... if you feel it's necessary then you do what you gotta do.</p>\n<h2 id=\"processing-dependant\" style=\"position:relative;\"><a href=\"#processing-dependant\" aria-label=\"processing dependant permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Processing dependant</h2>\n<p>Now depending on how you choose to have your preprocessor code processed these features may or may not be more/less accessible. That being said I still feel they are worth mentioning.</p>\n<p>Auto updating the page you're working on is a small perk but I remember being quite happy to find out I could just save my project and not have to spam F5 like my little sister trying to buy front row Justin Bieber tickets online. Just save and it will update your project automatically.</p>\n<p>Another one is vendor prefixes. There are a handful of ways to stop writing these things out by hand each time. Whether it's via mixins, functions or a built in feature of the processor itself you can avoid writing out these dreadfully monotonous prefixes for good.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>At first it might seem like a bunch of new stuff you have to learn and implement... but really if you already know CSS you're over halfway there. All you need to do is learn the specific syntax and familiarize yourself with the new features available to you with the preprocessor of your choice. It's a gentle learning curve with a surplus of benefits to integrate preprocessors into your workflow.</p>\n<p>This article is by no means all encompassing, but rather a sampler to create enough interest to try it out and learn more about preprocessors.</p>\n<p>On that note there are <a href=\"http://csspre.com/compile/\">resources</a> for comparing the preprocessors as well as trying them online. Each one has its own perks so try 'em out and find the one that fits your style!</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n</style>","frontmatter":{"title":"The truth about CSS preprocessors and how they can help you","author":{"id":"Zakary Hughes","github":null,"avatar":null},"date":"November 17, 2015","updated_date":null,"tags":["CSS"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/06a5f244323a7617c371dd411e68c861/6d161/desdev-150x150.png","srcSet":"/static/06a5f244323a7617c371dd411e68c861/6d161/desdev-150x150.png 150w","sizes":"(max-width: 150px) 100vw, 150px"}}}},"fields":{"authorId":"Zakary Hughes","slug":"/engineering/the-truth-about-css-preprocessors-and-how-they-can-help-you/"}}}]},"authorYaml":{"id":"Zakary Hughes","bio":"Zak is our resident front end development and design intern. He studied web design and development at the Northern Alberta Institute of Technology. One of his passions, outside of work, is fitness. Legend has it that he once ate a two-bite brownie in a single bite.","github":null,"stackoverflow":null,"linkedin":null,"medium":null,"twitter":null,"avatar":null}},"pageContext":{"id":"Zakary Hughes","__params":{"id":"zakary-hughes"}}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}