<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Flavio Copes on Medium]]></title>
        <description><![CDATA[Stories by Flavio Copes on Medium]]></description>
        <link>https://medium.com/@flaviocopes?source=rss-fe1c14f6cde------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*c8VnTj6yTsSXRe5mFQuU5Q.jpeg</url>
            <title>Stories by Flavio Copes on Medium</title>
            <link>https://medium.com/@flaviocopes?source=rss-fe1c14f6cde------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 22:44:31 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@flaviocopes/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Git, what if you forgot to add a file to a commit?]]></title>
            <link>https://medium.com/@flaviocopes/git-what-if-you-forgot-to-add-a-file-to-a-commit-b60768e4773d?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/b60768e4773d</guid>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Thu, 18 Apr 2024 05:00:56 GMT</pubDate>
            <atom:updated>2024-04-19T17:25:08.090Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>This post is part of my pre-launch series for my upcoming course <a href="https://flaviocopes.com/courses"><strong>Get Really Good at Git</strong></a> launching Summer 2024. If this post helps you, the course will be a great fit for you, to help you get a much better understanding of Git, reduce your frustrations with it, and figure out the good parts of this incredibly useful tool</blockquote><p>This is common, you commit something but realize you forgot to include a specific file, maybe because you forgot to run git add to stage it.</p><p>No worries — you can use git commit --amend to take the previous commit, &quot;undo&quot; it, apply all that&#39;s currently staged, and then commit again:</p><pre>git add file-forgotten.txt<br>git commit --amend</pre><p>If you need, you can also change the commit message while you’re adding the file, using the -m option:</p><pre>git commit --amend -m &quot;New commit message&quot;</pre><p>As with any operation that rewrites the history, I would only use it if you are working on a local branch, or if you are 100% sure no one else is working on the same branch.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b60768e4773d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Git, detached HEAD]]></title>
            <link>https://medium.com/@flaviocopes/git-detached-head-02ced94220e7?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/02ced94220e7</guid>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Wed, 17 Apr 2024 05:00:32 GMT</pubDate>
            <atom:updated>2024-04-19T17:25:29.855Z</atom:updated>
            <content:encoded><![CDATA[<blockquote><em>This post is part of my pre-launch series for my upcoming course </em><a href="https://flaviocopes.com/courses"><strong><em>Get Really Good at Git</em></strong></a><em> launching </em>Summer 2024<em>. If this post helps you, the course will be a great fit for you, to help you get a much better understanding of Git, reduce your frustrations with it, and figure out the good parts of this incredibly useful tool</em></blockquote><p>One of the states in which your Git repository can end up is “detached HEAD”.</p><p>Sounds scary.</p><p>Two words: detached (not attached?) and HEAD.</p><p>HEAD is the current commit.</p><p>When you create a repository, HEAD points to the first commit. If you do a second commit, HEAD points to the new commit.</p><p>If you switch branch, HEAD points to the latest commit in that branch.</p><p>That’s what’s normal 90% of the time: HEAD points to the latest commit in the currently selected branch. To Git, that&#39;s what it means HEAD being <em>attached</em>.</p><p>Our problem is HEAD being <em>detached</em>.</p><p>This happens when you checkout a commit that’s not the latest in the branch, and basically means HEAD is not pointing to a branch, but at a commit.</p><p>It’s not a situation that’s too unusual. Perhaps you are debugging an issue and you’re trying to figure out in which commit the issue was introduced, so you check out individual commits (using git checkout &lt;commit&gt;) until you find where the code was working.</p><p>In this case, when you’re done, you can checkout a branch, for example main, using git checkout main</p><p>One thing you can do however is end up in this situation: you are in a detached HEAD state (checked out a commit) and you create a new commit. One or more.</p><p>In this case, you need to create a branch before you switch to another branch, otherwise your changes might be lost.</p><p>Do so by creating a branch at this commit using:</p><pre>git branch &lt;new-branch-name&gt;</pre><p>and then switching to that branch (important):</p><pre>git checkout &lt;new-branch-name&gt;</pre><p>Or, with a single command:</p><pre>git checkout -b &lt;new-branch-name&gt;</pre><blockquote><em>This post is part of my pre-launch series for my upcoming course </em><a href="https://flaviocopes.com/courses"><strong><em>Get Really Good at Git</em></strong></a><em> launching on May 21. If this post helps you, the course will be a great fit for you, to help you get a much better understanding of Git, reduce your frustrations with it, and figure out the good parts of this incredibly useful tool</em></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=02ced94220e7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Git, rebase vs merge]]></title>
            <link>https://medium.com/@flaviocopes/git-rebase-vs-merge-f969bd0866a4?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/f969bd0866a4</guid>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Tue, 16 Apr 2024 05:00:20 GMT</pubDate>
            <atom:updated>2024-04-19T17:25:26.562Z</atom:updated>
            <content:encoded><![CDATA[<blockquote><em>This post is part of my pre-launch series for my upcoming course </em><a href="https://flaviocopes.com/courses"><strong><em>Get Really Good at Git</em></strong></a><em> launching </em>Summer 2024<em>. If this post helps you, the course will be a great fit for you, to help you get a much better understanding of Git, reduce your frustrations with it, and figure out the good parts of this incredibly useful tool</em></blockquote><p>One of the tweets you can post to get engagement is “do you use merge or rebase” and you’re guaranteed some solid engagement farming. It’s just an endless debate.</p><p>This is because Git provided us 2 different ways to perform more or less the same result, and this just puts the topic in “opinion land”.</p><p>With this premise, I’ll share my opinion.</p><p>You use <strong>both</strong>.</p><p>When working on a feature branch, and you’re ready to merge the branch into main (or another branch, but I&#39;m simplifying), you <strong>rebase the feature branch upon main</strong>.</p><p>This means, all the changes that were committed to main are now being applied to the feature branch, then all the changes committed to the feature branch are applied after them.</p><p>Even if work continued on main and we have changes that we didn&#39;t have before when the feature branch was created.</p><p>Even if:</p><ol><li>you created the feature branch from main 3 days ago</li><li>committed 10 changes on the feature branch 2 days ago</li><li>yesterday you added to main some commits</li></ol><p>…after you rebase the feature branch upon main, it&#39;ll be like the commmits made to main yesterday were done before you even created the feature branch.</p><p>You resolve any conflicts during this rebase.</p><p>Then once you are ready, assuming no more changes were made to `main` (otherwise rebase again), you can merge the feature branch into main, doing what we call “fast-forward merge”.</p><p>Doing so will prevent the infamous <em>merge commit</em>, which is one of the main reasons why we do not just use git merge right away, but first we rebase the branch we want to merge.</p><p>Other reasons include not mixing commits from different branches in the history, and having a cleaner git log.</p><p>I want to highlight this, if there is something you should get from this tutorial, is that <strong>you never rebase </strong><strong>main</strong>, because that would rewrite the history of the main branch and assuming other people use it as the base of their work, it&#39;s not going to have an happy ending.</p><p>It’s possible, but I’d not do it.</p><p>I’d only rebase feature branches upon main.</p><blockquote><em>This post is part of my pre-launch series for my upcoming course </em><a href="https://flaviocopes.com/courses"><strong><em>Get Really Good at Git</em></strong></a><em> launching on May 21. If this post helps you, the course will be a great fit for you, to help you get a much better understanding of Git, reduce your frustrations with it, and figure out the good parts of this incredibly useful tool</em></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f969bd0866a4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Git, squashing vs not squashing]]></title>
            <link>https://medium.com/@flaviocopes/git-squashing-vs-not-squashing-af5009f47d9e?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/af5009f47d9e</guid>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Mon, 15 Apr 2024 05:00:40 GMT</pubDate>
            <atom:updated>2024-04-19T17:25:23.166Z</atom:updated>
            <content:encoded><![CDATA[<blockquote><em>This post is part of my pre-launch series for my upcoming course </em><a href="https://flaviocopes.com/courses"><strong><em>Get Really Good at Git</em></strong></a><em> launching </em>Summer 2024<em>. If this post helps you, the course will be a great fit for you, to help you get a much better understanding of Git, reduce your frustrations with it, and figure out the good parts of this incredibly useful tool</em></blockquote><p>In Git, there are 2 things:</p><ol><li><strong>concepts</strong>: facts, principles, fundamentals that never change and there’s no debate over them</li><li><strong>opinions</strong>: things that are left to us to decide and there’s debate over them all of the time</li></ol><p>An example of case 1 is commits, branches, merging, rebasing.</p><p>An example of case 2 is “rebase vs merge”.</p><p>Let’s talk about <strong>squashing</strong>.</p><p>As a concept, squashing is simple: we can take 2 or more commits we already committed to a branch, and squash them together.</p><p>As an opinion, the question is “when should you squash commits?” But also, “should you even squash commits at all”?</p><p>In Git many things are opinions, and depending on the context you can have your own opinion, for example when you’re working on your own on your private Git repository.</p><p>Other times you have conventions and decisions that have been taken by a project manager and you just follow them.</p><p>There’s endless discussion but no right or wrong, but we can point out advantages and disadvantages depending on the situation.</p><p>Being in “opinions” space, here I’ll show my own opinions.</p><h3>Case 1: working on your own</h3><p>Let’s say you’re working on your own repo, or perhaps a branch you haven’t pushed yet to remote, you can squash commits together as you prefer. I do this all the time, when working on my projects. In this case you got complete freedom. Maybe you committed something, then realized you had a bug, then tried some other solutions until you got it working, and now you just want a cleaner history that says “Implemented feature X” instead of a list of commits that shows you the process.</p><p>After all what matters is the end result.</p><p>Go ahead.</p><p>You don’t <em>need</em> to squash commits, but it’s not a big deal and if this gives you a better taste when looking at your branch history, then go ahead.</p><h3>Case 2: working on a feature branch on your own</h3><p>Let’s say you are working on a feature branch. Before merging to main you should rebase all your commits upon main (another opinion), but you can also squash commits together, so that instead of looking at a long big list of commits you did to implement the feature, you just have a single commit.</p><p>The benefit of doing so is that you can very easily revert changes by reverting a single commit. It feels cleaner.</p><p>It’s so useful that GitHub offers this option in the workflow when you merge a Pull Request.</p><p>The downside is more philosophical and emotional: you worked so hard for 2 weeks on a feature branch adding a ton of commits with nice commit messages and descriptions, and now all of that work is going away because you’ll have a single commit in the Git history, which by its nature will never be as detailed and descriptive as many individual commits, unless of course you craft a well prepared Pull Request description on GitHub (assuming you use GitHub).</p><p>Perhaps the real work you did was trying 10 different changes to an algorithm to make it faster, and the solution is like 2 lines of code. Squashing doesn’t show you all the work you did before, so the “proof” (so to speak) of your work is now gone.</p><p>If you’re one of those people that likes to see their GitHub “streak” graph full of commits, squashing and then merging into main and then deleting the feature branch will delete a ton of activity. Vanity metrics, I know, perhaps you don’t care (&lt;be-honest-david-beckham.gif&gt;), but perhaps this is really motivating to make you “show up every day” and do the work day in day out.</p><p>In this case what I would do is squashing commits along the way if needed, using a good commit “schedule” and writing descriptive commit messages, but when it’s time to merge into the main branch, leave the history intact to keep the progress visible.</p><p>To easily revert to a state before the feature branch was merged, use tags.</p><h3>Case 3: working on a feature branch with team members</h3><p>Expanding on the previous case, suppose you and 2 other team members work on a feature branch for a week, you each write 10 commits, perhaps someone worked even more than you, but you get to do the squashing.</p><p>Now it seems like you did all the work, because there’s just one commit with your name attached.</p><p>I don’t think this is right.</p><p>First, it’s important for everyone to have their contribution “set in stone”, so to say.</p><p>But also, tools like git blame can be very useful down the line, months or years from now, to say &quot;person X did this, let me talk to them why they chose this approach&quot; and find information that sometimes is not written in a comment or documented anywhere else.</p><p>By squashing, they’d ask you, but you have no idea, since all you did was squashing someone else’s commits.</p><h3>Case 4: squashing on a remote branch</h3><p>While you <em>can</em> squash commits on a remote branch, I think this is one of the things you should not do even if Git makes them technically possible, to prevent possible issues.</p><p>Especially if you know other people work on the same branch as well, and they already pulled the code to work on it.</p><p>Unless you absolutely need to, for some reason.</p><p>But if you did something wrong (perhaps you meant to squash before but then realized you didn’t), or someone else did something wrong (perhaps a junior team member on their 1st day on the job), learn the lesson for the future and find ways to prevent this from happening again</p><p>Imho.</p><h3>Conclusion</h3><p>Squashing can be really useful a lot of times. Use with judgment and caution though, as different scenarios can have different ideal solutions.</p><blockquote>This post is part of my pre-launch series for my upcoming course <a href="https://flaviocopes.com/courses">Get Really Good at Git</a> launching on May 21. If this post helps you, the course will be a great fit for you, to help you get a much better understanding of Git, reduce your frustrations with it, and figure out the good parts of this incredibly useful tool</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af5009f47d9e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How I fixed some trouble importing types in .d.ts files]]></title>
            <link>https://medium.com/@flaviocopes/how-i-fixed-some-trouble-importing-types-in-d-ts-files-1064b8e2ed48?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/1064b8e2ed48</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Sat, 06 Apr 2024 06:23:25 GMT</pubDate>
            <atom:updated>2024-04-06T06:23:25.513Z</atom:updated>
            <content:encoded><![CDATA[<h3>How I fixed some trouble importing types in .d.ts files</h3><p>I had some trouble making something work in my Astro site.</p><p>I used <a href="https://flaviocopes.com/using-astro-locals/">Astro locals</a> and I had to type a variable I shared using locals.</p><p>So I went and added that to the src/env.d.ts, <a href="https://docs.astro.build/en/guides/middleware/#middleware-types">as the docs say</a>.</p><p>But my types weren’t picked up.</p><p>My code looked like this:</p><pre>/// &lt;reference types=&quot;astro/client&quot; /&gt;<br>import { sometype } from &#39;somelib&#39;<br><br>declare namespace App {<br>  interface Locals {<br>    somevariable: sometype<br>  }<br>}</pre><p>What I discovered thanks to <a href="https://stackoverflow.com/a/51114250">this SO answer</a> is, we can’t do imports like this in .d.ts files.</p><p>So I imported the type in another file, and then I imported the type from that file, like this:</p><blockquote>typesforenvdts.ts</blockquote><pre>import { sometype } from &#39;somelib&#39;<br><br>export { sometype }</pre><blockquote>env.d.ts</blockquote><pre>/// &lt;reference types=&quot;astro/client&quot; /&gt;<br><br>declare namespace App {<br>  interface Locals {<br>    somevariable: import(&#39;./typesforenvdts&#39;).sometype<br>  }<br>}</pre><p>Don’t ask me why, but now it works.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1064b8e2ed48" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Unregister service workers in Safari]]></title>
            <link>https://medium.com/@flaviocopes/unregister-service-workers-in-safari-5a6d70028c58?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/5a6d70028c58</guid>
            <category><![CDATA[safari-browser]]></category>
            <category><![CDATA[service-worker]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Fri, 05 Apr 2024 08:05:10 GMT</pubDate>
            <atom:updated>2024-04-05T08:05:10.456Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9E2ZYIKPoGCD8vdB" /><figcaption>Photo by <a href="https://unsplash.com/@maria_shalabaieva?utm_source=medium&amp;utm_medium=referral">Mariia Shalabaieva</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>You can easily unregister a <a href="https://flaviocopes.com/service-workers/">service worker</a> in Chrome, from the Application tab in the <a href="https://flaviocopes.com/browser-dev-tools/">DevTools</a>, but in Safari on macOS there’s no button to do so.</p><p>So to unregister a service worker, run this JS in the <a href="https://flaviocopes.com/console-api/">browser console</a>:</p><pre>navigator.serviceWorker.getRegistrations()<br>  .then(registrations =&gt; {<br>    registrations.map(r =&gt; {<br>      r.unregister()<br>    }) <br>  })</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5a6d70028c58" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fix “Too many redirects” error after enabling Cloudflare Proxy]]></title>
            <link>https://medium.com/@flaviocopes/fix-too-many-redirects-error-after-enabling-cloudflare-proxy-7fb94fe98989?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/7fb94fe98989</guid>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[cloudflare]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Fri, 05 Apr 2024 08:01:03 GMT</pubDate>
            <atom:updated>2024-04-05T08:01:03.394Z</atom:updated>
            <content:encoded><![CDATA[<p>I had an Astro site on Railway and since I manage my DNS using Cloudflare, I figured I could take advantage of everything Cloudflare offers if I proxy the requests through it, instead of just using it as a DNS.</p><p>I changed my CNAME record that points to the Railway app from “DNS only” to “Proxied” but the app was not served any more by the browser, with an error saying “Too many redirects”.</p><p>The reason is that by default Cloudflare in proxy mode sends unencrypted HTTP request to the server, behind the scenes, but the app on Railway was configured to use HTTPS automatically and this caused an infinite loop of redirects.</p><p>The problem was <a href="https://developers.cloudflare.com/ssl/troubleshooting/too-many-redirects/">well documented</a> on Cloudflare’s docs.</p><p>The solution was to go in the SSL/TLS settings on that domain on Cloudflare, and switch the encryption mode from Flexible (the default) to Full.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NdPQ66AzJs10zYw8LNaNGA.png" /></figure><p>Then everything worked as expected.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7fb94fe98989" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The CSS Handbook: a handy guide to CSS for developers]]></title>
            <link>https://medium.com/free-code-camp/the-css-handbook-a-handy-guide-to-css-for-developers-b56695917d11?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/b56695917d11</guid>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[ux]]></category>
            <category><![CDATA[css]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Wed, 24 Apr 2019 15:51:53 GMT</pubDate>
            <atom:updated>2021-11-08T09:20:16.986Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aeXtrs9UI4WniMd1miDIDw.png" /></figure><p>I wrote this article to help you quickly learn CSS and get familiar with the advanced CSS topics.</p><blockquote>Before we go on: <a href="https://flaviocopes.com/page/ebooks/">download my 15 free ebooks about JavaScript, React, Python, Svelte, and much more!</a></blockquote><p>CSS is often quickly dismissed as an easy thing to learn by developers, or one thing you just pick up when you need to quickly style a page or app. Due to this reason, it’s often learned on-the-fly, or we learn things in isolation right when we have to use them. This can be a huge source of frustration when we find that the tool does not simply do what we want.</p><p>This article will help you get up to speed with CSS and get an overview of the main modern features you can use to style your pages and apps.</p><p>I hope to help you get comfortable with CSS and get you quickly up to speed with using this awesome tool that lets you create stunning designs on the Web.</p><p><a href="https://flaviocopes.com/page/css-handbook"><strong>Click here to get a PDF / ePub / Mobi version of this post to read offline</strong></a></p><p>CSS, a shorthand for Cascading Style Sheets, is one of the main building blocks of the Web. Its history goes back to the 90’s, and along with HTML it has changed a lot since its humble beginnings.</p><p>As I’ve been creating websites since before CSS existed, I have seen its evolution.</p><p>CSS is an amazing tool, and in the last few years it has grown a lot, introducing many fantastic features like CSS Grid, Flexbox and CSS Custom Properties.</p><p>This handbook is aimed at a vast audience.</p><p>First, the beginner. I explain CSS from zero in a succinct but comprehensive way, so you can use this book to learn CSS from the basics.</p><p>Then, the professional. CSS is often considered like a secondary thing to learn, especially by JavaScript developers. They know CSS is not a real programming language, they are programmers and therefore they should not bother learning CSS the right way. I wrote this book for you, too.</p><p>Next, the person that knows CSS from a few years but hasn’t had the opportunity to learn the new things in it. We’ll talk extensively about the new features of CSS, the ones that are going to build the web of the next decade.</p><p>CSS has improved a lot in the past few years and it’s evolving fast.</p><p>Even if you don’t write CSS for a living, knowing how CSS works can help save you some headaches when you need to understand it from time to time, for example while tweaking a web page.</p><p>Thank you for getting this ebook. My goal with it is to give you a quick yet comprehensive overview of CSS.</p><p>Flavio</p><p>You can reach me via email at <a href="mailto:flavio@flaviocopes.com">flavio@flaviocopes.com</a>, on Twitter <a href="https://twitter.com/flaviocopes">@flaviocopes</a>.</p><p>My website is <a href="https://flaviocopes.com/">flaviocopes.com</a>.</p><h4>Table of Contents</h4><ul><li><a href="https://medium.com/p/b56695917d11#633e">INTRODUCTION TO CSS</a></li><li><a href="https://medium.com/p/b56695917d11#e216">A BRIEF HISTORY OF CSS</a></li><li><a href="https://medium.com/p/b56695917d11#49c9">ADDING CSS TO AN HTML PAGE</a></li><li><a href="https://medium.com/p/b56695917d11#51ef">SELECTORS</a></li><li><a href="https://medium.com/p/b56695917d11#6c22">CASCADE</a></li><li><a href="https://medium.com/p/b56695917d11#bf89">SPECIFICITY</a></li><li><a href="https://medium.com/p/b56695917d11#44d8">INHERITANCE</a></li><li><a href="https://medium.com/p/b56695917d11#0211">IMPORT</a></li><li><a href="https://medium.com/p/b56695917d11#04a8">ATTRIBUTE SELECTORS</a></li><li><a href="https://medium.com/p/b56695917d11#c563">PSEUDO-CLASSES</a></li><li><a href="https://medium.com/p/b56695917d11#2533">PSEUDO-ELEMENTS</a></li><li><a href="https://medium.com/p/b56695917d11#d9f9">COLORS</a></li><li><a href="https://medium.com/p/b56695917d11#af8c">UNITS</a></li><li><a href="https://medium.com/p/b56695917d11#3694">URL</a></li><li><a href="https://medium.com/p/b56695917d11#5c49">CALC</a></li><li><a href="https://medium.com/p/b56695917d11#64b6">BACKGROUNDS</a></li><li><a href="https://medium.com/p/b56695917d11#8fe3">COMMENTS</a></li><li><a href="https://medium.com/p/b56695917d11#17bb">CUSTOM PROPERTIES</a></li><li><a href="https://medium.com/p/b56695917d11#4f57">FONTS</a></li><li><a href="https://medium.com/p/b56695917d11#cdc4">TYPOGRAPHY</a></li><li><a href="https://medium.com/p/b56695917d11#c857">BOX MODEL</a></li><li><a href="https://medium.com/p/b56695917d11#8bf9">BORDER</a></li><li><a href="https://medium.com/p/b56695917d11#f8b1">PADDING</a></li><li><a href="https://medium.com/p/b56695917d11#85d3">MARGIN</a></li><li><a href="https://medium.com/p/b56695917d11#cba2">BOX SIZING</a></li><li><a href="https://medium.com/p/b56695917d11#27a4">DISPLAY</a></li><li><a href="https://medium.com/p/b56695917d11#5916">POSITIONING</a></li><li><a href="https://medium.com/p/b56695917d11#12ca">FLOATING AND CLEARING</a></li><li><a href="https://medium.com/p/b56695917d11#2d01">Z-INDEX</a></li><li><a href="https://medium.com/p/b56695917d11#9443">CSS GRID</a></li><li><a href="https://medium.com/p/b56695917d11#5a96">FLEXBOX</a></li><li><a href="https://medium.com/p/b56695917d11#726b">TABLES</a></li><li><a href="https://medium.com/p/b56695917d11#5107">CENTERING</a></li><li><a href="https://medium.com/p/b56695917d11#e2b1">LISTS</a></li><li><a href="https://medium.com/p/b56695917d11#a366">MEDIA QUERIES AND RESPONSIVE DESIGN</a></li><li><a href="https://medium.com/p/b56695917d11#67b8">FEATURE QUERIES</a></li><li><a href="https://medium.com/p/b56695917d11#8af8">FILTERS</a></li><li><a href="https://medium.com/p/b56695917d11#6ed5">TRANSFORMS</a></li><li><a href="https://medium.com/p/b56695917d11#53c1">TRANSITIONS</a></li><li><a href="https://medium.com/p/b56695917d11#642d">ANIMATIONS</a></li><li><a href="https://medium.com/p/b56695917d11#8975">NORMALIZING CSS</a></li><li><a href="https://medium.com/p/b56695917d11#0623">ERROR HANDLING</a></li><li><a href="https://medium.com/p/b56695917d11#eca4">VENDOR PREFIXES</a></li><li><a href="https://medium.com/p/b56695917d11#79f2">CSS FOR PRINT</a></li><li><a href="https://medium.com/p/b56695917d11#d6ff">WRAPPING UP</a></li></ul><h3>INTRODUCTION TO CSS</h3><p><strong>CSS</strong> (an abbreviation of <strong>Cascading Style Sheets</strong>) is the language that we use to style an HTML file, and tell the browser how should it render the elements on the page.</p><blockquote><em>In this book I talk exclusively about styling HTML documents, although CSS can be used to style other things too.</em></blockquote><p>A CSS file contains several CSS rules.</p><p>Each rule is composed by 2 parts:</p><ul><li>the <strong>selector</strong></li><li>the <strong>declaration block</strong></li></ul><p>The selector is a string that identifies one or more elements on the page, following a special syntax that we’ll soon talk about extensively.</p><p>The declaration block contains one or more <strong>declarations</strong>, in turn composed by a <strong>property</strong> and <strong>value</strong>pair.</p><p>Those are all the things we have in CSS.</p><p>Carefully organising properties, associating them values, and attaching those to specific elements of the page using a selector is the whole argument of this ebook.</p><h4>How does CSS look like</h4><p>A CSS <strong>rule set</strong> has one part called <strong>selector</strong>, and the other part called <strong>declaration</strong>. The declaration contains various <strong>rules</strong>, each composed by a <strong>property</strong>, and a <strong>value</strong>.</p><p>In this example, p is the selector, and applies one rule which sets the value 20px to the font-size property:</p><pre>p {<br>  font-size: 20px;<br>}</pre><p>Multiple rules are stacked one after the other:</p><pre>p {<br>  font-size: 20px;<br>}</pre><pre>a {<br>  color: blue;<br>}</pre><p>A selector can target one or more items:</p><pre>p, a {<br>  font-size: 20px;<br>}</pre><p>and it can target HTML tags, like above, or HTML elements that contain a certain class attribute with .my-class, or HTML elements that have a specific id attribute with #my-id.</p><p>More advanced selectors allow you to choose items whose attribute matches a specific value, or also items which respond to pseudo-classes (more on that later)</p><h4>Semicolons</h4><p>Every CSS rule terminates with a semicolon. Semicolons are <strong>not</strong> optional, except after the last rule. But I suggest to always use them for consistency and to avoid errors if you add another property and forget to add the semicolon on the previous line.</p><h4>Formatting and indentation</h4><p>There is no fixed rule for formatting. This CSS is valid:</p><pre>p<br>      {<br>  font-size:           20px   ;<br>                      }</pre><pre>a{color:blue;}</pre><p>but a pain to see. Stick to some conventions, like the ones you see in the examples above: stick selectors and the closing brackets to the left, indent 2 spaces for each rule, have the opening bracket on the same line of the selector, separated by one space.</p><p>Correct and consistent use of spacing and indentation is a visual aid in understanding your code.</p><h3>A BRIEF HISTORY OF CSS</h3><p>Before moving on, I want to give you a brief recap of the history of CSS.</p><p>CSS was grown out of the necessity of styling web pages. Before CSS was introduced, people wanted a way to style their web pages, which looked all very similar and “academic” back in the day. You couldn’t do much in terms of personalisation.</p><p>HTML 3.2 introduced the option of defining colors inline as HTML element attributes, and presentational tags like center and font, but that escalated quickly into a far from ideal situation.</p><p>CSS let us move everything presentation-related from the HTML to the CSS, so that HTML could get back being the format that defines the structure of the document, rather than how things should look in the browser.</p><p>CSS is continuously evolving, and CSS you used 5 years ago might just be outdated, as new idiomatic CSS techniques emerged and browsers changed.</p><p>It’s hard to imagine the times when CSS was born and how different the web was.</p><p>At the time, we had several competing browsers, the main ones being Internet Explorer or Netscape Navigator.</p><p>Pages were styled by using HTML, with special presentational tags like bold and special attributes, most of which are now deprecated.</p><p>This meant you had a limited amount of customisation opportunities.</p><p>The bulk of the styling decisions were left to the browser.</p><p>Also, you built a site specifically for one of them, because each one introduced different non-standard tags to give more power and opportunities.</p><p>Soon people realised the need for a way to style pages, in a way that would work across all browsers.</p><p>After the initial idea proposed in 1994, CSS got its first release in 1996, when the CSS Level 1 (“CSS 1”) recommendation was published.</p><p>CSS Level 2 (“CSS 2”) got published in 1998.</p><p>Since then, work began on CSS Level 3. The CSS Working Group decided to split every feature and work on it separately, in modules.</p><p>Browsers weren’t especially fast at implementing CSS. We had to wait until 2002 to have the first browser implement the full CSS specification: IE for Mac, as nicely described in this CSS Tricks post: <a href="https://css-tricks.com/look-back-history-css/">https://css-tricks.com/look-back-history-css/</a></p><p>Internet Explorer implemented the box model incorrectly right from the start, which led to years of pain trying to have the same style applied consistently across browsers. We had to use various tricks and hacks to make browsers render things as we wanted.</p><p>Today things are much, much better. We can just use the CSS standards without thinking about quirks, most of the time, and CSS has never been more powerful.</p><p>We don’t have official release numbers for CSS any more now, but the CSS Working Group releases a “snapshot” of the modules that are currently considered stable and ready to be included in browsers. This is the latest snapshot, from 2018: <a href="https://www.w3.org/TR/css-2018/">https://www.w3.org/TR/css-2018/</a></p><p>CSS Level 2 is still the base for the CSS we write today, and we have many more features built on top of it.</p><h3>ADDING CSS TO AN HTML PAGE</h3><p>CSS is attached to an HTML page in different ways.</p><h4>1: Using the link tag</h4><p>The link tag is the way to include a CSS file. This is the preferred way to use CSS as it&#39;s intended to be used: one CSS file is included by all the pages of your site, and changing one line on that file affects the presentation of all the pages in the site.</p><p>To use this method, you add a link tag with the href attribute pointing to the CSS file you want to include. You add it inside the head tag of the site (not inside the body tag):</p><pre>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;myfile.css&quot;&gt;</pre><p>The rel and type attributes are required too, as they tell the browser which kind of file we are linking to.</p><h4>2: using the style tag</h4><p>Instead of using the link tag to point to separate stylesheet containing our CSS, we can add the CSS directly inside a style tag. This is the syntax:</p><pre>&lt;style&gt;<br>...our CSS...<br>&lt;/style&gt;</pre><p>Using this method we can avoid creating a separate CSS file. I find this is a good way to experiment before “formalising” CSS to a separate file, or to add a special line of CSS just to a file.</p><h4>3: inline styles</h4><p>Inline styles are the third way to add CSS to a page. We can add a style attribute to any HTML tag, and add CSS into it.</p><pre>&lt;div style=&quot;&quot;&gt;...&lt;/div&gt;</pre><p>Example:</p><pre>&lt;div style=&quot;background-color: yellow&quot;&gt;...&lt;/div&gt;</pre><h3>SELECTORS</h3><p>A selector allows us to associate one or more declarations to one or more elements on the page.</p><h4>Basic selectors</h4><p>Suppose we have a p element on the page, and we want to display the words into it using the yellow color.</p><p>We can <strong>target</strong> that element using this selector p, which targets all the element using the p tag in the page. A simple CSS rule to achieve what we want is:</p><pre>p {<br>  color: yellow;<br>}</pre><p>Every HTML tag has a corresponding selector, for example: div, span, img.</p><p>If a selector matches multiple elements, all the elements in the page will be affected by the change.</p><p>HTML elements have 2 attributes which are very commonly used within CSS to associate styling to a specific element on the page: class and id.</p><p>There is one big difference between those two: inside an HTML document you can repeat the same class value across multiple elements, but you can only use an id once. As a corollary, using classes you can select an element with 2 or more specific class names, something not possible using ids.</p><p>Classes are identified using the . symbol, while ids using the # symbol.</p><p>Example using a class:</p><pre>&lt;p class=&quot;dog-name&quot;&gt;<br>  Roger<br>&lt;/p&gt;</pre><pre>.dog-name {<br>  color: yellow;<br>}</pre><p>Example using an id:</p><pre>&lt;p id=&quot;dog-name&quot;&gt;<br>  Roger<br>&lt;/p&gt;</pre><pre>#dog-name {<br>  color: yellow;<br>}</pre><h4>Combining selectors</h4><p>So far we’ve seen how to target an element, a class or an id. Let’s introduce more powerful selectors.</p><h4>Targeting an element with a class or id</h4><p>You can target a specific element that has a class, or id, attached.</p><p>Example using a class:</p><pre>&lt;p class=&quot;dog-name&quot;&gt;<br>  Roger<br>&lt;/p&gt;</pre><pre>p.dog-name {<br>  color: yellow;<br>}</pre><p>Example using an id:</p><pre>&lt;p id=&quot;dog-name&quot;&gt;<br>  Roger<br>&lt;/p&gt;</pre><pre>p#dog-name {<br>  color: yellow;<br>}</pre><p>Why would you want to do that, if the class or id already provides a way to target that element? You might have to do that to have more specificity. We’ll see what that means later.</p><h4>Targeting multiple classes</h4><p>You can target an element with a specific class using .class-name, as you saw previously. You can target an element with 2 (or more) classes by combining the class names separated with a dot, without spaces.</p><p>Example:</p><pre>&lt;p class=&quot;dog-name roger&quot;&gt;<br>  Roger<br>&lt;/p&gt;</pre><pre>.dog-name.roger {<br>  color: yellow;<br>}</pre><h4>Combining classes and ids</h4><p>In the same way, you can combine a class and an id.</p><p>Example:</p><pre>&lt;p class=&quot;dog-name&quot; id=&quot;roger&quot;&gt;<br>  Roger<br>&lt;/p&gt;</pre><pre>.dog-name#roger {<br>  color: yellow;<br>}</pre><h4>Grouping selectors</h4><p>You can combine selectors to apply the same declarations to multiple selectors. To do so, you separate them with a comma.</p><p>Example:</p><pre>&lt;p&gt;<br>  My dog name is:<br>&lt;/p&gt;<br>&lt;span class=&quot;dog-name&quot;&gt;<br>  Roger<br>&lt;/span&gt;</pre><pre>p, .dog-name {<br>  color: yellow;<br>}</pre><p>You can add spaces in those declarations to make them more clear:</p><pre>p,<br>.dog-name {<br>  color: yellow;<br>}</pre><h4>Follow the document tree with selectors</h4><p>We’ve seen how to target an element in the page by using a tag name, a class or an id.</p><p>You can create a more specific selector by combining multiple items to follow the document tree structure. For example, if you have a span tag nested inside a p tag, you can target that one without applying the style to a span tag not included in a p tag:</p><pre>&lt;span&gt;<br>  Hello!<br>&lt;/span&gt;<br>&lt;p&gt;<br>  My dog name is:<br>  &lt;span class=&quot;dog-name&quot;&gt;<br>    Roger<br>  &lt;/span&gt;<br>&lt;/p&gt;</pre><pre>p span {<br>  color: yellow;<br>}</pre><p>See how we used a space between the two tokens p and span.</p><p>This works even if the element on the right is multiple levels deep.</p><p>To make the dependency strict on the first level, you can use the &gt; symbol between the two tokens:</p><pre>p &gt; span {<br>  color: yellow;<br>}</pre><p>In this case, if a span is not a first children of the p element, it&#39;s not going to have the new color applied.</p><p>Direct children will have the style applied:</p><pre>&lt;p&gt;<br>  &lt;span&gt;<br>    This is yellow<br>  &lt;/span&gt;<br>  &lt;strong&gt;<br>    &lt;span&gt;<br>      This is not yellow<br>    &lt;/span&gt;<br>  &lt;/strong&gt;<br>&lt;/p&gt;</pre><p>Adjacent sibling selectors let us style an element only if preceded by a specific element. We do so using the + operator:</p><p>Example:</p><pre>p + span {<br>  color: yellow;<br>}</pre><p>This will assign the color yellow to all span elements preceded by a p element:</p><pre>&lt;p&gt;This is a paragraph&lt;/p&gt;<br>&lt;span&gt;This is a yellow span&lt;/span&gt;</pre><p>We have a lot more selectors we can use:</p><ul><li>attribute selectors</li><li>pseudo class selectors</li><li>pseudo element selectors</li></ul><p>We’ll find all about them in the next sections.</p><h3>CASCADE</h3><p>Cascade is a fundamental concept of CSS. After all, it’s in the name itself, the first C of CSS — Cascading Style Sheets — it must be an important thing.</p><p>What does it mean?</p><p>Cascade is the process, or algorithm, that determines the properties applied to each element on the page. Trying to converge from a list of CSS rules that are defined in various places.</p><p>It does so taking in consideration:</p><ul><li>specificity</li><li>importance</li><li>inheritance</li><li>order in the file</li></ul><p>It also takes care of resolving conflicts.</p><p>Two or more competing CSS rules for the same property applied to the same element need to be elaborated according to the CSS spec, to determine which one needs to be applied.</p><p>Even if you just have one CSS file loaded by your page, there is other CSS that is going to be part of the process. We have the browser (user agent) CSS. Browsers come with a default set of rules, all different between browsers.</p><p>Then your CSS comes into play.</p><p>Then the browser applies any user stylesheet, which might also be applied by browser extensions.</p><p>All those rules come into play while rendering the page.</p><p>We’ll now see the concepts of specificity and inheritance.</p><h3>SPECIFICITY</h3><p>What happens when an element is targeted by multiple rules, with different selectors, that affect the same property?</p><p>For example, let’s talk about this element:</p><pre>&lt;p class=&quot;dog-name&quot;&gt;<br>  Roger<br>&lt;/p&gt;</pre><p>We can have</p><pre>.dog-name {<br>  color: yellow;<br>}</pre><p>and another rule that targets p, which sets the color to another value:</p><pre>p {<br>  color: red;<br>}</pre><p>And another rule that targets p.dog-name. Which rule is going to take precedence over the others, and why?</p><p>Enter specificity. <strong>The more specific rule will win</strong>. If two or more rules have the <strong>same specificity, the one that appears last wins</strong>.</p><p>Sometimes what is more specific in practice is a bit confusing to beginners. I would say it’s also confusing to experts that do not look at those rules that frequently, or simply overlook them.</p><h4>How to calculate specificity</h4><p>Specificity is calculated using a convention.</p><p>We have 4 slots, and each one of them starts at 0: 0 0 0 0 0. The slot at the left is the most important, and the rightmost one is the least important.</p><p>Like it works for numbers in the decimal system: 1 0 0 0 is higher than 0 1 0 0.</p><h4>Slot 1</h4><p>The first slot, the rightmost one, is the least important.</p><p>We increase this value when we have an <strong>element selector</strong>. An element is a tag name. If you have more than one element selector in the rule, you increment accordingly the value stored in this slot.</p><p>Examples:</p><pre>p {}                    /* 0 0 0 1 */<br>span {}                 /* 0 0 0 1 */<br>p span {}               /* 0 0 0 2 */<br>p &gt; span {}             /* 0 0 0 2 */<br>div p &gt; span {}         /* 0 0 0 3 */</pre><h4>Slot 2</h4><p>The second slot is incremented by 3 things:</p><ul><li>class selectors</li><li>pseudo-class selectors</li><li>attribute selectors</li></ul><p>Every time a rule meets one of those, we increment the value of the second column from the right.</p><p>Examples:</p><pre>.name {}                 /* 0 0 1 0 */<br>.users .name {}          /* 0 0 2 0 */<br>[href$=&#39;.pdf&#39;] {}        /* 0 0 1 0 */<br>:hover {}                /* 0 0 1 0 */</pre><p>Of course slot 2 selectors can be combined with slot 1 selectors:</p><pre>div .name {}             /* 0 0 1 1 */<br>a[href$=&#39;.pdf&#39;] {}       /* 0 0 1 1 */<br>.pictures img:hover {}   /* 0 0 2 1 */</pre><p>One nice trick with classes is that you can repeat the same class and increase the specificity. For example:</p><pre>.name {}              /* 0 0 1 0 */<br>.name.name {}         /* 0 0 2 0 */<br>.name.name.name {}    /* 0 0 3 0 */</pre><h4>Slot 3</h4><p>Slot 3 holds the most important thing that can affect your CSS specificity in a CSS file: the id.</p><p>Every element can have an id attribute assigned, and we can use that in our stylesheet to target the element.</p><p>Examples:</p><pre>#name {}                    /* 0 1 0 0 */<br>.user #name {}              /* 0 1 1 0 */<br>#name span {}               /* 0 1 0 1 */</pre><h4>Slot 4</h4><p>Slot 4 is affected by inline styles. Any inline style will have precedence over any rule defined in an external CSS file, or inside the style tag in the page header.</p><p>Example:</p><pre>&lt;p style=&quot;color: red&quot;&gt;Test&lt;/p&gt; /* 1 0 0 0 */</pre><p>Even if any other rule in the CSS defines the color, this inline style rule is going to be applied. Except for one case — if !important is used, which fills the slot 5.</p><h4>Importance</h4><p>Specificity does not matter if a rule ends with !important:</p><pre>p {<br>  font-size: 20px!important;<br>}</pre><p>That rule will take precedence over any rule with more specificity</p><p>Adding !important in a CSS rule is going to make that rule more important than any other rule, according to the specificity rules. The only way another rule can take precedence is to have !important as well, and have higher specificity in the other less important slots.</p><h4>Tips</h4><p>In general you should use the amount of specificity you need, but not more. In this way, you can craft other selectors to overwrite the rules set by preceding rules without going mad.</p><p>!important is a highly debated tool that CSS offers us. Many CSS experts advocate against using it. I find myself using it especially when trying out some style and a CSS rule has so much specificity that I need to use !important to make the browser apply my new CSS.</p><p>But generally, !important should have no place in your CSS files.</p><p>Using the id attribute to style CSS is also debated a lot, since it has a very high specificity. A good alternative is to use classes instead, which have less specificity, and so they are easier to work with, and they are more powerful (you can have multiple classes for an element, and a class can be reused multiple times).</p><h4>Tools to calculate the specificity</h4><p>You can use the site <a href="https://specificity.keegan.st/">https://specificity.keegan.st/</a> to perform the specificity calculation for you automatically.</p><p>It’s useful especially if you are trying to figure things out, as it can be a nice feedback tool.</p><h3>INHERITANCE</h3><p>When you set some properties on a selector in CSS, they are inherited by all the children of that selector.</p><p>I said <em>some</em>, because not all properties show this behaviour.</p><p>This happens because some properties make sense to be inherited. This helps us write CSS much more concisely, since we don’t have to explicitly set that property again on every single child.</p><p>Some other properties make more sense to <em>not</em> be inherited.</p><p>Think about fonts: you don’t need to apply the font-family to every single tag of your page. You set the body tag font, and every child inherits it, along with other properties.</p><p>The background-color property, on the other hand, makes little sense to be inherited.</p><h4>Properties that inherit</h4><p>Here is a list of the properties that do inherit. The list is non-comprehensive, but those rules are just the most popular ones you’ll likely use:</p><ul><li>border-collapse</li><li>border-spacing</li><li>caption-side</li><li>color</li><li>cursor</li><li>direction</li><li>empty-cells</li><li>font-family</li><li>font-size</li><li>font-style</li><li>font-variant</li><li>font-weight</li><li>font-size-adjust</li><li>font-stretch</li><li>font</li><li>letter-spacing</li><li>line-height</li><li>list-style-image</li><li>list-style-position</li><li>list-style-type</li><li>list-style</li><li>orphans</li><li>quotes</li><li>tab-size</li><li>text-align</li><li>text-align-last</li><li>text-decoration-color</li><li>text-indent</li><li>text-justify</li><li>text-shadow</li><li>text-transform</li><li>visibility</li><li>white-space</li><li>widows</li><li>word-break</li><li>word-spacing</li></ul><p>I got it from this <a href="https://www.sitepoint.com/css-inheritance-introduction/">nice Sitepoint article</a> on CSS inheritance.</p><h4>Forcing properties to inherit</h4><p>What if you have a property that’s not inherited by default, and you want it to, in a child?</p><p>In the children, you set the property value to the special keyword inherit.</p><p>Example:</p><pre>body {<br>    background-color: yellow;<br>}</pre><pre>p {<br>  background-color: inherit;<br>}</pre><h4>Forcing properties to NOT inherit</h4><p>On the contrary, you might have a property inherited and you want to avoid so.</p><p>You can use the revert keyword to revert it. In this case, the value is reverted to the original value the browser gave it in its default stylesheet.</p><p>In practice this is rarely used, and most of the times you’ll just set another value for the property to overwrite that inherited value.</p><h4>Other special values</h4><p>In addition to the inherit and revert special keywords we just saw, you can also set any property to:</p><ul><li>initial: use the default browser stylesheet if available. If not, and if the property inherits by default, inherit the value. Otherwise do nothing.</li><li>unset: if the property inherits by default, inherit. Otherwise do nothing.</li></ul><h3>IMPORT</h3><p>From any CSS file you can import another CSS file using the @import directive.</p><p>Here is how you use it:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css)</pre><p>url() can manage absolute or relative URLs.</p><p>One important thing you need to know is that @import directives must be put before any other CSS in the file, or they will be ignored.</p><p>You can use media descriptors to only load a CSS file on the specific media:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) all;<br><a href="http://twitter.com/import">@import</a> url(myfile-screen.css) screen;<br><a href="http://twitter.com/import">@import</a> url(myfile-print.css) print;</pre><h3>ATTRIBUTE SELECTORS</h3><p>We already introduced several of the basic CSS selectors: using element selectors, class, id, how to combine them, how to target multiple classes, how to style several selectors in the same rule, how to follow the page hierarchy with child and direct child selectors, and adjacent siblings.</p><p>In this section we’ll analyze attribute selectors, and we’ll talk about pseudo class and pseudo element selectors in the next 2 sections.</p><h4>Attribute presence selectors</h4><p>The first selector type is the attribute presence selector.</p><p>We can check if an element <strong>has</strong> an attribute using the [] syntax. p[id] will select all p tags in the page that have an id attribute, regardless of its value:</p><pre>p[id] {<br>  /* ... */<br>}</pre><h4>Exact attribute value selectors</h4><p>Inside the brackets you can check the attribute value using =, and the CSS will be applied only if the attribute matches the exact value specified:</p><pre>p[id=&quot;my-id&quot;] {<br>  /* ... */<br>}</pre><h4>Match an attribute value portion</h4><p>While = lets us check for exact value, we have other operators:</p><ul><li>*= checks if the attribute contains the partial</li><li>^= checks if the attribute starts with the partial</li><li>$= checks if the attribute ends with the partial</li><li>|= checks if the attribute starts with the partial and it&#39;s followed by a dash (common in classes, for example), or just contains the partial</li><li>~= checks if the partial is contained in the attribute, but separated by spaces from the rest</li></ul><p>All the checks we mentioned are <strong>case sensitive</strong>.</p><p>If you add an i just before the closing bracket, the check will be case insensitive. It&#39;s supported in many browsers but not in all, check <a href="https://caniuse.com/#feat=css-case-insensitive">https://caniuse.com/#feat=css-case-insensitive</a>.</p><h3>PSEUDO-CLASSES</h3><p>Pseudo classes are predefined keywords that are used to select an element based on its <strong>state</strong>, or to target a specific child.</p><p>They start with a <strong>single colon</strong> :.</p><p>They can be used as part of a selector, and they are very useful to style active or visited links, for example, change the style on hover, focus, or target the first child, or odd rows. Very handy in many cases.</p><p>These are the most popular pseudo classes you will likely use:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/792/1*i4FhtySXj2OkesaDsIJv-w.png" /></figure><p>Let’s do an example. A common one, actually. You want to style a link, so you create a CSS rule to target the a element:</p><pre>a {<br>  color: yellow;<br>}</pre><p>Things seem to work fine, until you click one link. The link goes back to the predefined color (blue) when you click it. Then when you open the link and go back to the page, now the link is blue.</p><p>Why does that happen?</p><p>Because the link when clicked changes state, and goes in the :active state. And when it&#39;s been visited, it is in the :visited state. Forever, until the user clears the browsing history.</p><p>So, to correctly make the link yellow across all states, you need to write</p><pre>a,<br>a:visited,<br>a:active {<br>  color: yellow;<br>}</pre><p>:nth-child() deserves a special mention. It can be used to target odd or even children with :nth-child(odd) and :nth-child(even).</p><p>It is commonly used in lists to color odd lines differently from even lines:</p><pre>ul:nth-child(odd) {<br>  color: white;<br>    background-color: black;<br>}</pre><p>You can also use it to target the first 3 children of an element with :nth-child(-n+3). Or you can style 1 in every 5 elements with :nth-child(5n).</p><p>Some pseudo classes are just used for printing, like :first, :left, :right, so you can target the first page, all the left pages, and all the right pages, which are usually styled slightly differently.</p><h3>PSEUDO-ELEMENTS</h3><h4>Pseudo-elements are used to style a specific part of an element.</h4><p>They start with a double colon ::.</p><blockquote><em>Sometimes you will spot them in the wild with a single colon, but this is only a syntax supported for backwards compatibility reasons. You should use 2 colons to distinguish them from pseudo-classes.</em></blockquote><p>::before and ::after are probably the most used pseudo-elements. They are used to add content before or after an element, like icons for example.</p><p>Here’s the list of the pseudo-elements:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/799/1*GBbcW2R1oyo1sD1zI1vG0g.png" /></figure><p>Let’s do an example. Say you want to make the first line of a paragraph slightly bigger in font size, a common thing in typography:</p><pre>p::first-line {<br>  font-size: 2rem;<br>}</pre><p>Or maybe you want the first letter to be bolder:</p><pre>p::first-letter {<br>  font-weight: bolder;<br>}</pre><p>::after and ::before are a bit less intuitive. I remember using them when I had to add icons using CSS.</p><p>You specify the content property to insert any kind of content after or before an element:</p><pre>p::before {<br>  content: url(/myimage.png);<br>}</pre><pre>.myElement::before {<br>    content: &quot;Hey Hey!&quot;;<br>}</pre><h3>COLORS</h3><p>By default an HTML page is rendered by web browsers quite sadly in terms of the colors used.</p><p>We have a white background, black color, and blue links. That’s it.</p><p>Luckily CSS gives us the ability to add colors to our designs.</p><p>We have these properties:</p><ul><li>color</li><li>background-color</li><li>border-color</li></ul><p>All of them accept a <strong>color value</strong>, which can be in different forms.</p><h4>Named colors</h4><p>First, we have CSS keywords that define colors. CSS started with 16, but today there is a huge number of colors names:</p><ul><li>aliceblue</li><li>antiquewhite</li><li>aqua</li><li>aquamarine</li><li>azure</li><li>beige</li><li>bisque</li><li>black</li><li>blanchedalmond</li><li>blue</li><li>blueviolet</li><li>brown</li><li>burlywood</li><li>cadetblue</li><li>chartreuse</li><li>chocolate</li><li>coral</li><li>cornflowerblue</li><li>cornsilk</li><li>crimson</li><li>cyan</li><li>darkblue</li><li>darkcyan</li><li>darkgoldenrod</li><li>darkgray</li><li>darkgreen</li><li>darkgrey</li><li>darkkhaki</li><li>darkmagenta</li><li>darkolivegreen</li><li>darkorange</li><li>darkorchid</li><li>darkred</li><li>darksalmon</li><li>darkseagreen</li><li>darkslateblue</li><li>darkslategray</li><li>darkslategrey</li><li>darkturquoise</li><li>darkviolet</li><li>deeppink</li><li>deepskyblue</li><li>dimgray</li><li>dimgrey</li><li>dodgerblue</li><li>firebrick</li><li>floralwhite</li><li>forestgreen</li><li>fuchsia</li><li>gainsboro</li><li>ghostwhite</li><li>gold</li><li>goldenrod</li><li>gray</li><li>green</li><li>greenyellow</li><li>grey</li><li>honeydew</li><li>hotpink</li><li>indianred</li><li>indigo</li><li>ivory</li><li>khaki</li><li>lavender</li><li>lavenderblush</li><li>lawngreen</li><li>lemonchiffon</li><li>lightblue</li><li>lightcoral</li><li>lightcyan</li><li>lightgoldenrodyellow</li><li>lightgray</li><li>lightgreen</li><li>lightgrey</li><li>lightpink</li><li>lightsalmon</li><li>lightseagreen</li><li>lightskyblue</li><li>lightslategray</li><li>lightslategrey</li><li>lightsteelblue</li><li>lightyellow</li><li>lime</li><li>limegreen</li><li>linen</li><li>magenta</li><li>maroon</li><li>mediumaquamarine</li><li>mediumblue</li><li>mediumorchid</li><li>mediumpurple</li><li>mediumseagreen</li><li>mediumslateblue</li><li>mediumspringgreen</li><li>mediumturquoise</li><li>mediumvioletred</li><li>midnightblue</li><li>mintcream</li><li>mistyrose</li><li>moccasin</li><li>navajowhite</li><li>navy</li><li>oldlace</li><li>olive</li><li>olivedrab</li><li>orange</li><li>orangered</li><li>orchid</li><li>palegoldenrod</li><li>palegreen</li><li>paleturquoise</li><li>palevioletred</li><li>papayawhip</li><li>peachpuff</li><li>peru</li><li>pink</li><li>plum</li><li>powderblue</li><li>purple</li><li>rebeccapurple</li><li>red</li><li>rosybrown</li><li>royalblue</li><li>saddlebrown</li><li>salmon</li><li>sandybrown</li><li>seagreen</li><li>seashell</li><li>sienna</li><li>silver</li><li>skyblue</li><li>slateblue</li><li>slategray</li><li>slategrey</li><li>snow</li><li>springgreen</li><li>steelblue</li><li>tan</li><li>teal</li><li>thistle</li><li>tomato</li><li>turquoise</li><li>violet</li><li>wheat</li><li>white</li><li>whitesmoke</li><li>yellow</li><li>yellowgreen</li></ul><p>plus tranparent, and currentColor which points to the color property, for example it’s useful to make the border-color inherit it.</p><p>They are defined in the <a href="https://www.w3.org/TR/css-color-4/">CSS Color Module, Level 4</a>. They are case insensitive.</p><p>Wikipedia has a <a href="https://en.wikipedia.org/wiki/Web_colors">nice table</a> which lets you pick the perfect color by its name.</p><p>Named colors are not the only option.</p><h3>RGB and RGBa</h3><p>You can use the rgb() function to calculate a color from its RGB notation, which sets the color based on its red-green-blue parts. From 0 to 255:</p><pre>p {<br>  color: rgb(255, 255, 255); /* white */<br>    background-color: rgb(0, 0, 0); /* black */<br>}</pre><p>rgba() lets you add the alpha channel to enter a transparent part. That can be a number from 0 to 1:</p><pre>p {<br>    background-color: rgb(0, 0, 0, 0.5);<br>}</pre><h4>Hexadecimal notation</h4><p>Another option is to express the RGB parts of the colors in the hexadecimal notation, which is composed by 3 blocks.</p><p>Black, which is rgb(0,0,0) is expressed as #000000 or #000 (we can shortcut the 2 numbers to 1 if they are equal).</p><p>White, rgb(255,255,255) can be expressed as #ffffff or #fff.</p><p>The hexadecimal notation lets us express a number from 0 to 255 in just 2 digits, since they can go from 0 to “15” (f).</p><p>We can add the alpha channel by adding 1 or 2 more digits at the end, for example #00000033. Not all browsers support the shortened notation, so use all 6 digits to express the RGB part.</p><h4>HSL and HSLa</h4><p>This is a more recent addition to CSS.</p><p>HSL = Hue Saturation Lightness.</p><p>In this notation, black is hsl(0, 0%, 0%) and white is hsl(0, 0%, 100%).</p><p>If you are more familiar with HSL than RGB because of your past knowledge, you can definitely use that.</p><p>You also have hsla() which adds the alpha channel to the mix, again a number from 0 to 1: hsl(0, 0%, 0%, 0.5)</p><h3>UNITS</h3><p>One of the things you’ll use every day in CSS are units. They are used to set lengths, paddings, margins, align elements and so on.</p><p>Things like px, em, rem, or percentages.</p><p>They are everywhere. There are some obscure ones, too. We’ll go through each of them in this section.</p><h4>Pixels</h4><p>The most widely used measurement unit. A pixel does not actually correlate to a physical pixel on your screen, as that varies, a lot, by device (think high-DPI devices vs non-retina devices).</p><p>There is a convention that make this unit work consistently across devices.</p><h4>Percentages</h4><p>Another very useful measure, percentages let you specify values in percentages of that parent element’s corresponding property.</p><p>Example:</p><pre>.parent {<br>  width: 400px;<br>}</pre><pre>.child {<br>  width: 50%; /* = 200px */<br>}</pre><h4>Real-world measurement units</h4><p>We have those measurement units which are translated from the outside world. Mostly useless on screen, they can be useful for print stylesheets. They are:</p><ul><li>cm a centimeter (maps to 37.8 pixels)</li><li>mm a millimeter (0.1cm)</li><li>q a quarter of a millimeter</li><li>in an inch (maps to 96 pixels)</li><li>pt a point (1 inch = 72 points)</li><li>pc a pica (1 pica = 12 points)</li></ul><h4>Relative units</h4><ul><li>em is the value assigned to that element&#39;s font-size, therefore its exact value changes between elements. It does not change depending on the font used, just on the font size. In typography this measures the width of the m letter.</li><li>rem is similar to em, but instead of varying on the current element font size, it uses the root element (html) font size. You set that font size once, and rem will be a consistent measure across all the page.</li><li>ex is like em, but inserted of measuring the width of m, it measures the height of the x letter. It can change depending on the font used, and on the font size.</li><li>ch is like ex but instead of measuring the height of x it measures the width of 0 (zero).</li></ul><h4>Viewport units</h4><ul><li>vw the <strong>viewport width unit</strong> represents a percentage of the viewport width. 50vw means 50% of the viewport width.</li><li>vh the <strong>viewport height unit</strong> represents a percentage of the viewport height. 50vh means 50% of the viewport height.</li><li>vmin the <strong>viewport minimum unit</strong> represents the minimum between the height or width in terms of percentage. 30vmin is the 30% of the current width or height, depending which one is smaller</li><li>vmax the <strong>viewport maximum unit</strong> represents the maximum between the height or width in terms of percentage. 30vmax is the 30% of the current width or height, depending which one is bigger</li></ul><h4>Fraction units</h4><p>fr are fraction units, and they are used in CSS Grid to divide space into fractions.</p><p>We’ll talk about them in the context of CSS Grid later on.</p><h3>URL</h3><p>When we talk about background images, @import, and more, we use the url() function to load a resource:</p><pre>div {<br>  background-image: url(test.png);<br>}</pre><p>In this case I used a relative URL, which searches the file in the folder where the CSS file is defined.</p><p>I could go one level back</p><pre>div {<br>  background-image: url(../test.png);<br>}</pre><p>or go into a folder</p><pre>div {<br>  background-image: url(subfolder/test.png);<br>}</pre><p>Or I could load a file starting from the root of the domain where the CSS is hosted:</p><pre>div {<br>  background-image: url(/test.png);<br>}</pre><p>Or I could use an absolute URL to load an external resource:</p><pre>div {<br>  background-image: url(<a href="https://mysite.com/test.png">https://mysite.com/test.png</a>);<br>}</pre><h3>CALC</h3><p>The calc() function lets you perform basic math operations on values, and it&#39;s especially useful when you need to add or subtract a length value from a percentage.</p><p>This is how it works:</p><pre>div {<br>    max-width: calc(80% - 100px)<br>}</pre><p>It returns a length value, so it can be used anywhere you expect a pixel value.</p><p>You can perform</p><ul><li>additions using +</li><li>subtractions using -</li><li>multiplication using *</li><li>division using /</li></ul><blockquote><em>One caveat: with addition and subtraction, the space around the operator is mandatory, otherwise it does not work as expected.</em></blockquote><p>Examples:</p><pre>div {<br>    max-width: calc(50% / 3)<br>}</pre><pre>div {<br>    max-width: calc(50% + 3px)<br>}</pre><h3>BACKGROUNDS</h3><p>The background of an element can be changed using several CSS properties:</p><ul><li>background-color</li><li>background-image</li><li>background-clip</li><li>background-position</li><li>background-origin</li><li>background-repeat</li><li>background-attachment</li><li>background-size</li></ul><p>and the shorthand property background, which allows us to shorten definitions and group them on a single line.</p><p>background-color accepts a color value, which can be one of the color keywords, or an rgb or hsl value:</p><pre>p {<br>  background-color: yellow;<br>}</pre><pre>div {<br>  background-color: #333;<br>}</pre><p>Instead of using a color, you can use an image as background to an element, by specifying the image location URL:</p><pre>div {<br>  background-image: url(image.png);<br>}</pre><p>background-clip lets you determine the area used by the background image, or color. The default value is border-box, which extends up to the border outer edge.</p><p>Other values are</p><ul><li>padding-box to extend the background up to the padding edge, without the border</li><li>content-box to extend the background up to the content edge, without the padding</li><li>inherit to apply the value of the parent</li></ul><p>When using an image as background you will want to set the position of the image placement using the background-position property: left, right, center are all valid values for the X axis, and top, bottom for the Y axis:</p><pre>div {<br>  background-position: top right;<br>}</pre><p>If the image is smaller than the background, you need to set the behavior using background-repeat. Should it repeat-x, repeat-y or repeat on all the axes? This last one is the default value. Another value is no-repeat.</p><p>background-origin lets you choose where the background should be applied: to the entire element including padding (default) using padding-box, to the entire element including the border using border-box, to the element without the padding using content-box.</p><p>With background-attachment we can attach the background to the viewport, so that scrolling will not affect the background:</p><pre>div {<br>  background-attachment: fixed;<br>}</pre><p>By default the value is scroll. There is another value, local. The best way to visualize their behavior is <a href="https://codepen.io/BernLeech/pen/mMNKJV">this Codepen</a>.</p><p>The last background property is background-size. We can use 3 keywords: auto, cover and contain. auto is the default.</p><p>cover expands the image until the entire element is covered by the background.</p><p>contain stops expanding the background image when one dimension (x or y) covers the whole smallest edge of the image, so it&#39;s fully contained into the element.</p><p>You can also specify a length value, and if so it sets the width of the background image (and the height is automatically defined):</p><pre>div {<br>  background-size: 100%;<br>}</pre><p>If you specify 2 values, one is the width and the second is the height:</p><pre>div {<br>  background-size: 800px 600px;<br>}</pre><p>The shorthand property background allows to shorten definitions and group them on a single line.</p><p>This is an example:</p><pre>div {<br>  background: url(bg.png) top left no-repeat;<br>}</pre><p>If you use an image, and the image could not be loaded, you can set a fallback color:</p><pre>div {<br>  background: url(image.png) yellow;<br>}</pre><p>You can also set a gradient as background:</p><pre>div {<br>  background: linear-gradient(#fff, #333);<br>}</pre><h3>COMMENTS</h3><p>CSS gives you the ability to write comments in a CSS file, or in the style tag in the page header</p><p>The format is the /* this is a comment */ C-style (or JavaScript-style, if you prefer) comments.</p><p>This is a multiline comment. Until you add the closing */ token, the all the lines found after the opening one are commented.</p><p>Example:</p><pre>#name { display: block; } /* Nice rule! */</pre><pre>/* #name { display: block; } */</pre><pre>#name {<br>    display: block; /*<br>    color: red;<br>    */<br>}</pre><p>CSS does not have inline comments, like // in C or JavaScript.</p><p>Pay attention though — if you add // before a rule, the rule will not be applied, looking like the comment worked. In reality, CSS detected a syntax error and due to how it works it ignored the line with the error, and went straight to the next line.</p><p>Knowing this approach lets you purposefully write inline comments, although you have to be careful because you can’t add random text like you can in a block comment.</p><p>For example:</p><pre>// Nice rule!<br>#name { display: block; }</pre><p>In this case, due to how CSS works, the #name rule is actually commented out. You can find more details <a href="https://www.xanthir.com/b4U10">here</a> if you find this interesting. To avoid shooting yourself in the foot, just avoid using inline comments and rely on block comments.</p><h3>CUSTOM PROPERTIES</h3><p>In the last few years CSS preprocessors have had a lot of success. It was very common for greenfield projects to start with Less or Sass. And it’s still a very popular technology.</p><p>The main benefits of those technologies are, in my opinion:</p><ul><li>They allow you to nest selectors</li><li>The provide an easy imports functionality</li><li>They give you variables</li></ul><p>Modern CSS has a new powerful feature called <strong>CSS Custom Properties</strong>, also commonly known as <strong>CSS Variables</strong>.</p><p>CSS is not a programming language like <a href="https://flaviocopes.com/javascript/">JavaScript</a>, Python, PHP, Ruby or Go where variables are key to do something useful. CSS is very limited in what it can do, and it’s mainly a declarative syntax to tell browsers how they should display an HTML page.</p><p>But a variable is a variable: a name that refers to a value, and variables in CSS help reduce repetition and inconsistencies in your CSS, by centralizing the values definition.</p><p>And it introduces a unique feature that CSS preprocessors won’t ever have: <strong>you can access and change the value of a CSS Variable programmatically using JavaScript</strong>.</p><h4>The basics of using variables</h4><p>A CSS Variable is defined with a special syntax, prepending <strong>two dashes</strong> to a name (--variable-name), then a colon and a value. Like this:</p><pre>:root {<br>  --primary-color: yellow;<br>}</pre><p>(more on :root later)</p><p>You can access the variable value using var():</p><pre>p {<br>  color: var(--primary-color)<br>}</pre><p>The variable value can be any valid CSS value, for example:</p><pre>:root {<br>  --default-padding: 30px 30px 20px 20px;<br>  --default-color: red;<br>  --default-background: #fff;<br>}</pre><h4>Create variables inside any element</h4><p>CSS Variables can be defined inside any element. Some examples:</p><pre>:root {<br>  --default-color: red;<br>}</pre><pre>body {<br>  --default-color: red;<br>}</pre><pre>main {<br>  --default-color: red;<br>}</pre><pre>p {<br>  --default-color: red;<br>}</pre><pre>span {<br>  --default-color: red;<br>}</pre><pre>a:hover {<br>  --default-color: red;<br>}</pre><p>What changes in those different examples is the <strong>scope</strong>.</p><h4>Variables scope</h4><p>Adding variables to a selector makes them available to all the children of it.</p><p>In the example above you saw the use of :root when defining a CSS variable:</p><pre>:root {<br>  --primary-color: yellow;<br>}</pre><p>:root is a CSS pseudo-class that identifies the root element of a tree.</p><p>In the context of an HTML document, using the :root selector points to the html element, except that :root has higher specificity (takes priority).</p><p>In the context of an SVG image, :root points to the svg tag.</p><p>Adding a CSS custom property to :root makes it available to all the elements in the page.</p><p>If you add a variable inside a .container selector, it&#39;s only going to be available to children of .container:</p><pre>.container {<br>  --secondary-color: yellow;<br>}</pre><p>and using it outside of this element is not going to work.</p><p>Variables can be <strong>reassigned</strong>:</p><pre>:root {<br>  --primary-color: yellow;<br>}</pre><pre>.container {<br>  --primary-color: blue;<br>}</pre><p>Outside .container, --primary-color will be <em>yellow</em>, but inside it will be <em>blue</em>.</p><p>You can also assign or overwrite a variable inside the HTML using <strong>inline styles</strong>:</p><pre>&lt;main style=&quot;--primary-color: orange;&quot;&gt;<br>  &lt;!-- ... --&gt;<br>&lt;/main&gt;</pre><blockquote><em>CSS Variables follow the normal CSS cascading rules, with precedence set according to specificity.</em></blockquote><h4>Interacting with a CSS Variable value using JavaScript</h4><p>The coolest thing with CSS Variables is the ability to access and edit them using JavaScript.</p><p>Here’s how you set a variable value using plain JavaScript:</p><pre>const element = document.getElementById(&#39;my-element&#39;)<br>element.style.setProperty(&#39;--variable-name&#39;, &#39;a-value&#39;)</pre><p>This code below can be used to access a variable value instead, in case the variable is defined on :root:</p><pre>const styles = getComputedStyle(document.documentElement)<br>const value = String(styles.getPropertyValue(&#39;--variable-name&#39;)).trim()</pre><p>Or, to get the style applied to a specific element, in case of variables set with a different scope:</p><pre>const element = document.getElementById(&#39;my-element&#39;)<br>const styles = getComputedStyle(element)<br>const value = String(styles.getPropertyValue(&#39;--variable-name&#39;)).trim()</pre><h4>Handling invalid values</h4><p>If a variable is assigned to a property which does not accept the variable value, it’s considered invalid.</p><p>For example you might pass a pixel value to a position property, or a rem value to a color property.</p><p>In this case the line is considered invalid and is ignored.</p><h4>Browser support</h4><p>Browser support for CSS Variables is <strong>very good</strong>, <a href="https://www.caniuse.com/#feat=css-variables">according to Can I Use</a>.</p><p>CSS Variables are here to stay, and you can use them today if you don’t need to support Internet Explorer and old versions of the other browsers.</p><p>If you need to support older browsers you can use libraries like <a href="https://flaviocopes.com/postcss/">PostCSS</a> or <a href="http://www.myth.io/">Myth</a>, but you’ll lose the ability to interact with variables via JavaScript or the Browser Developer Tools, as they are transpiled to good old variable-less CSS (and as such, you lose most of the power of CSS Variables).</p><h4>CSS Variables are case sensitive</h4><p>This variable:</p><pre>--width: 100px;</pre><p>is different than this one:</p><pre>--Width: 100px;</pre><h4>Math in CSS Variables</h4><p>To do math in CSS Variables, you need to use calc(), for example:</p><pre>:root {<br>  --default-left-padding: calc(10px * 2);<br>}</pre><h4>Media queries with CSS Variables</h4><p>Nothing special here. CSS Variables normally apply to media queries:</p><pre>body {<br>  --width: 500px;<br>}</pre><pre><a href="http://twitter.com/media">@media</a> screen and (max-width: 1000px) and (min-width: 700px) {<br>  --width: 800px;<br>}</pre><pre>.container {<br>  width: var(--width);<br>}</pre><h4>Setting a fallback value for var()</h4><p>var() accepts a second parameter, which is the default fallback value when the variable value is not set:</p><pre>.container {<br>  margin: var(--default-margin, 30px);<br>}</pre><h3>FONTS</h3><p>At the dawn of the web you only had a handful of fonts you could choose from.</p><p>Thankfully today you can load any kind of font on your pages.</p><p>CSS has gained many nice capabilities over the years in regards to fonts.</p><p>The font property is the shorthand for a number of properties:</p><ul><li>font-family</li><li>font-weight</li><li>font-stretch</li><li>font-style</li><li>font-size</li></ul><p>Let’s see each one of them and then we’ll cover font.</p><p>Then we’ll talk about how to load custom fonts, using @import or @font-face, or by loading a font stylesheet.</p><h4>font-family</h4><p>Sets the font <em>family</em> that the element will use.</p><p>Why “family”? Because what we know as a font is actually composed of several sub-fonts which provide all the style (bold, italic, light..) we need.</p><p>Here’s an example from my Mac’s Font Book app — the Fira Code font family hosts several dedicated fonts underneath:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/999/1*3ml9bEZBaSu-JhFW05I6KA.png" /></figure><p>This property lets you select a specific font, for example:</p><pre>body {<br>  font-family: Helvetica;<br>}</pre><p>You can set multiple values, so the second option will be used if the first cannot be used for some reason (if it’s not found on the machine, or the network connection to download the font failed, for example):</p><pre>body {<br>  font-family: Helvetica, Arial;<br>}</pre><p>I used some specific fonts up to now, ones we call <strong>Web Safe Fonts</strong>, as they are pre-installed on different operating systems.</p><p>We divide them in Serif, Sans-Serif, and Monospace fonts. Here’s a list of some of the most popular ones:</p><p><strong>Serif</strong></p><ul><li>Georgia</li><li>Palatino</li><li>Times New Roman</li><li>Times</li></ul><p><strong>Sans-Serif</strong></p><ul><li>Arial</li><li>Helvetica</li><li>Verdana</li><li>Geneva</li><li>Tahoma</li><li>Lucida Grande</li><li>Impact</li><li>Trebuchet MS</li><li>Arial Black</li></ul><p><strong>Monospace</strong></p><ul><li>Courier New</li><li>Courier</li><li>Lucida Console</li><li>Monaco</li></ul><p>You can use all of those as font-family properties, but they are not guaranteed to be there for every system. Others exist, too, with a varying level of support.</p><p>You can also use generic names:</p><ul><li>sans-serif a font without ligatures</li><li>serif a font with ligatures</li><li>monospace a font especially good for code</li><li>cursive used to simulate handwritten pieces</li><li>fantasy the name says it all</li></ul><p>Those are typically used at the end of a font-family definition, to provide a fallback value in case nothing else can be applied:</p><pre>body {<br>  font-family: Helvetica, Arial, sans-serif;<br>}</pre><h4>font-weight</h4><p>This property sets the width of a font. You can use those predefined values:</p><ul><li>normal</li><li>bold</li><li>bolder (relative to the parent element)</li><li>lighter (relative to the parent element)</li></ul><p>Or using the numeric keywords</p><ul><li>100</li><li>200</li><li>300</li><li>400, mapped to normal</li><li>500</li><li>600</li><li>700 mapped to bold</li><li>800</li><li>900</li></ul><p>where 100 is the lightest font, and 900 is the boldest.</p><p>Some of those numeric values might not map to a font, because that must be provided in the font family. When one is missing, CSS makes that number be at least as bold as the preceding one, so you might have numbers that point to the same font.</p><h4>font-stretch</h4><p>Allows you to choose a narrow or wide face of the font, if available.</p><p>This is important: the font must be equipped with different faces.</p><p>Values allowed are, from narrower to wider:</p><ul><li>ultra-condensed</li><li>extra-condensed</li><li>condensed</li><li>semi-condensed</li><li>normal</li><li>semi-expanded</li><li>expanded</li><li>extra-expanded</li><li>ultra-expanded</li></ul><h4>font-style</h4><p>Allows you to apply an italic style to a font:</p><pre>p {<br>  font-style: italic;<br>}</pre><p>This property also allows the values oblique and normal. There is very little, if any, difference between using italic and oblique. The first is easier to me, as HTML already offers an i element which means italic.</p><h4>font-size</h4><p>This property is used to determine the size of fonts.</p><p>You can pass 2 kinds of values:</p><ol><li>a length value, like px, em, rem etc, or a percentage</li><li>a predefined value keyword</li></ol><p>In the second case, the values you can use are:</p><ul><li>xx-small</li><li>x-small</li><li>small</li><li>medium</li><li>large</li><li>x-large</li><li>xx-large</li><li>smaller (relative to the parent element)</li><li>larger (relative to the parent element)</li></ul><p>Usage:</p><pre>p {<br>  font-size: 20px;<br>}</pre><pre>li {<br>  font-size: medium;<br>}</pre><h4>font-variant</h4><p>This property was originally used to change the text to small caps, and it had just 3 valid values:</p><ul><li>normal</li><li>inherit</li><li>small-caps</li></ul><p>Small caps means the text is rendered in “smaller caps” beside its uppercase letters.</p><h4>font</h4><p>The font property lets you apply different font properties in a single one, reducing the clutter.</p><p>We must at least set 2 properties, font-size and font-family, the others are optional:</p><pre>body {<br>  font: 20px Helvetica;<br>}</pre><p>If we add other properties, they need to be put in the correct order.</p><p>This is the order:</p><pre>font: &lt;font-stretch&gt; &lt;font-style&gt; &lt;font-variant&gt; &lt;font-weight&gt; &lt;font-size&gt; &lt;line-height&gt; &lt;font-family&gt;;</pre><p>Example:</p><pre>body {<br>  font: italic bold 20px Helvetica;<br>}</pre><pre>section {<br>  font: small-caps bold 20px Helvetica;<br>}</pre><h4>Loading custom fonts using @font-face</h4><p>@font-face lets you add a new font family name, and map it to a file that holds a font.</p><p>This font will be downloaded by the browser and used in the page, and it’s been such a fundamental change to typography on the web — we can now use any font we want.</p><p>We can add @font-face declarations directly into our CSS, or link to a CSS dedicated to importing the font.</p><p>In our CSS file we can also use @import to load that CSS file.</p><p>A @font-face declaration contains several properties we use to define the font, including src, the URI (one or more URIs) to the font. This follows the same-origin policy, which means fonts can only be downloaded form the current origin (domain + port + protocol).</p><p>Fonts are usually in the formats</p><ul><li>woff (Web Open Font Format)</li><li>woff2 (Web Open Font Format 2.0)</li><li>eot (Embedded Open Type)</li><li>otf (OpenType Font)</li><li>ttf (TrueType Font)</li></ul><p>The following properties allow us to define the properties to the font we are going to load, as we saw above:</p><ul><li>font-family</li><li>font-weight</li><li>font-style</li><li>font-stretch</li></ul><h4>A note on performance</h4><p>Of course loading a font has performance implications which you must consider when creating the design of your page.</p><h3>TYPOGRAPHY</h3><p>We already talked about fonts, but there’s more to styling text.</p><p>In this section we’ll talk about the following properties:</p><ul><li>text-transform</li><li>text-decoration</li><li>text-align</li><li>vertical-align</li><li>line-height</li><li>text-indent</li><li>text-align-last</li><li>word-spacing</li><li>letter-spacing</li><li>text-shadow</li><li>white-space</li><li>tab-size</li><li>writing-mode</li><li>hyphens</li><li>text-orientation</li><li>direction</li><li>line-break</li><li>word-break</li><li>overflow-wrap</li></ul><h4>text-transform</h4><p>This property can transform the case of an element.</p><p>There are 4 valid values:</p><ul><li>capitalize to uppercase the first letter of each word</li><li>uppercase to uppercase all the text</li><li>lowercase to lowercase all the text</li><li>none to disable transforming the text, used to avoid inheriting the property</li></ul><p>Example:</p><pre>p {<br>  text-transform: uppercase;<br>}</pre><h4>text-decoration</h4><p>This property is sed to add decorations to the text, including</p><ul><li>underline</li><li>overline</li><li>line-through</li><li>blink</li><li>none</li></ul><p>Example:</p><pre>p {<br>  text-decoration: underline;<br>}</pre><p>You can also set the style of the decoration, and the color.</p><p>Example:</p><pre>p {<br>  text-decoration: underline dashed yellow;<br>}</pre><p>Valid style values are solid, double, dotted, dashed, wavy.</p><p>You can do all in one line, or use the specific properties:</p><ul><li>text-decoration-line</li><li>text-decoration-color</li><li>text-decoration-style</li></ul><p>Example:</p><pre>p {<br>  text-decoration-line: underline;<br>  text-decoration-color: yellow;<br>  text-decoration-style: dashed;<br>}</pre><h4>text-align</h4><p>By default text align has the start value, meaning the text starts at the &quot;start&quot;, origin 0, 0 of the box that contains it. This means top left in left-to-right languages, and top right in right-to-left languages.</p><p>Possible values are start, end, left, right, center, justify (nice to have a consistent spacing at the line ends):</p><pre>p {<br>  text-align: right;<br>}</pre><h4>vertical-align</h4><p>Determines how inline elements are vertically aligned.</p><p>We have several values for this property. First we can assign a length or percentage value. Those are used to align the text in a position higher or lower (using negative values) than the baseline of the parent element.</p><p>Then we have the keywords:</p><ul><li>baseline (the default), aligns the baseline to the baseline of the parent element</li><li>sub makes an element subscripted, simulating the sub HTML element result</li><li>super makes an element superscripted, simulating the sup HTML element result</li><li>top align the top of the element to the top of the line</li><li>text-top align the top of the element to the top of the parent element font</li><li>middle align the middle of the element to the middle of the line of the parent</li><li>bottom align the bottom of the element to the bottom of the line</li><li>text-bottom align the bottom of the element to the bottom of the parent element font</li></ul><h4>line-height</h4><p>This allows you to change the height of a line. Each line of text has a certain font height, but then there is additional spacing vertically between the lines. That’s the line height:</p><pre>p {<br>  line-height: 0.9rem;<br>}</pre><h4>text-indent</h4><p>Indent the first line of a paragraph by a set length, or a percentage of the paragraph width:</p><pre>p {<br>  text-indent: -10px;<br>}</pre><h4>text-align-last</h4><p>By default the last line of a paragraph is aligned following the text-align value. Use this property to change that behavior:</p><pre>p {<br>  text-align-last: right;<br>}</pre><h4>word-spacing</h4><p>Modifies the spacing between each word.</p><p>You can use the normal keyword, to reset inherited values, or use a length value:</p><pre>p {<br>  word-spacing: 2px;<br>}</pre><pre>span {<br>  word-spacing: -0.2em;<br>}</pre><h4>letter-spacing</h4><p>Modifies the spacing between each letter.</p><p>You can use the normal keyword, to reset inherited values, or use a length value:</p><pre>p {<br>  letter-spacing: 0.2px;<br>}</pre><pre>span {<br>  letter-spacing: -0.2em;<br>}</pre><h4>text-shadow</h4><p>Apply a shadow to the text. By default the text has now shadow.</p><p>This property accepts an optional color, and a set of values that set</p><ul><li>the X offset of the shadow from the text</li><li>the Y offset of the shadow from the text</li><li>the blur radius</li></ul><p>If the color is not specified, the shadow will use the text color.</p><p>Examples:</p><pre>p {<br>  text-shadow: 0.2px 2px;<br>}</pre><pre>span {<br>  text-shadow: yellow 0.2px 2px 3px;<br>}</pre><h4>white-space</h4><p>Sets how CSS handles the white space, new lines and tabs inside an element.</p><p>Valid values that collapse white space are:</p><ul><li>normal collapses white space. Adds new lines when necessary as the text reaches the container end</li><li>nowrap collapses white space. Does not add a new line when the text reaches the end of the container, and suppresses any line break added to the text</li><li>pre-line collapses white space. Adds new lines when necessary as the text reaches the container end</li></ul><p>Valid values that preserve white space are:</p><ul><li>pre preserves white space. Does not add a new line when the text reaches the end of the container, but preserves line break added to the text</li><li>pre-wrap preserves white space. Adds new lines when necessary as the text reaches the container end</li></ul><h4>tab-size</h4><p>Sets the width of the tab character. By default it’s 8, and you can set an integer value that sets the character spaces it takes, or a length value:</p><pre>p {<br>  tab-size: 2;<br>}</pre><pre>span {<br>  tab-size: 4px;<br>}</pre><h4>writing-mode</h4><p>Defines whether lines of text are laid out horizontally or vertically, and the direction in which blocks progress.</p><p>The values you can use are</p><ul><li>horizontal-tb (default)</li><li>vertical-rl content is laid out vertically. New lines are put on the left of the previous</li><li>vertical-lr content is laid out vertically. New lines are put on the right of the previous</li></ul><h4>hyphens</h4><p>Determines if hyphens should be automatically added when going to a new line.</p><p>Valid values are</p><ul><li>none (default)</li><li>manual only add an hyphen when there is already a visible hyphen or a hidden hyphen (a special character)</li><li>auto add hyphens when determined the text can have a hyphen.</li></ul><h4>text-orientation</h4><p>When writing-mode is in a vertical mode, determines the orientation of the text.</p><p>Valid values are</p><ul><li>mixed is the default, and if a language is vertical (like Japanese) it preserves that orientation, while rotating text written in western languages</li><li>upright makes all text be vertically oriented</li><li>sideways makes all text horizontally oriented</li></ul><h4>direction</h4><p>Sets the direction of the text. Valid values are ltr and rtl:</p><pre>p {<br>  direction: rtl;<br>}</pre><h4>word-break</h4><p>This property specifies how to break lines within words.</p><ul><li>normal (default) means the text is only broken between words, not inside a word</li><li>break-all the browser can break a word (but no hyphens are added)</li><li>keep-all suppress soft wrapping. Mostly used for CJK (Chinese/Japanese/Korean) text.</li></ul><p>Speaking of CJK text, the property line-break is used to determine how text lines break. I&#39;m not an expert with those languages, so I will avoid covering it.</p><h4>overflow-wrap</h4><p>If a word is too long to fit a line, it can overflow outside of the container.</p><blockquote><em>This property is also known as </em><em>word-wrap, although that is non-standard (but still works as an alias)</em></blockquote><p>This is the default behavior (overflow-wrap: normal;).</p><p>We can use:</p><pre>p {<br>  overflow-wrap: break-word;<br>}</pre><p>to break it at the exact length of the line, or</p><pre>p {<br>  overflow-wrap: anywhere;<br>}</pre><p>if the browser sees there’s a soft wrap opportunity somewhere earlier. No hyphens are added, in any case.</p><p>This property is very similar to word-break. We might want to choose this one on western languages, while word-break has special treatment for non-western languages.</p><h3>BOX MODEL</h3><p>Every CSS element is essentially a box. Every element is a generic box.</p><p>The box model explains the sizing of the elements based on a few CSS properties.</p><p>From the inside to the outside, we have:</p><ul><li>the content area</li><li>padding</li><li>border</li><li>margin</li></ul><p>The best way to visualize the box model is to open the browser DevTools and check how it is displayed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/809/1*npKrklhwE6rRPigIDX1cBA.png" /></figure><p>Here you can see how Firefox tells me the properties of a span element I highlighted. I right-clicked on it, pressed Inspect Element, and went to the Layout panel of the DevTools.</p><p>See, the light blue space is the content area. Surrounding it there is the padding, then the border and finally the margin.</p><p>By default, if you set a width (or height) on the element, that is going to be applied to the <strong>content area</strong>. All the padding, border, and margin calculations are done outside of the value, so you have to keep this in mind when you do your calculation.</p><p>Later you’ll see how you can change this behavior using Box Sizing.</p><h3>BORDER</h3><p>The border is a thin layer between padding and margin. By editing the border, you can make elements draw their perimeter on screen.</p><p>You can work on borders by using those properties:</p><ul><li>border-style</li><li>border-color</li><li>border-width</li></ul><p>The property border can be used as a shorthand for all those properties.</p><p>border-radius is used to create rounded corners.</p><p>You also have the ability to use images as borders, an ability given to you by border-image and its specific separate properties:</p><ul><li>border-image-source</li><li>border-image-slice</li><li>border-image-width</li><li>border-image-outset</li><li>border-image-repeat</li></ul><p>Let’s start with border-style.</p><h4>The border style</h4><p>The border-style property lets you choose the style of the border. The options you can use are:</p><ul><li>dotted</li><li>dashed</li><li>solid</li><li>double</li><li>groove</li><li>ridge</li><li>inset</li><li>outset</li><li>none</li><li>hidden</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/426/1*-PD10DuxD54x2ChtzvHt2A.png" /></figure><p>Check out <a href="https://codepen.io/flaviocopes/pen/yraaxq">this Codepen</a> for a live example.</p><p>The default for the style is none, so to make the border appear at all you need to change it to something else. solid is a good choice most of the time.</p><p>You can set a different style for each edge using the properties</p><ul><li>border-top-style</li><li>border-right-style</li><li>border-bottom-style</li><li>border-left-style</li></ul><p>or you can use border-style with multiple values to define them, using the usual Top-Right-Bottom-Left order:</p><pre>p {<br>  border-style: solid dotted solid dotted;<br>}</pre><h4>The border width</h4><p>border-width is used to set the width of the border.</p><p>You can use one of the pre-defined values:</p><ul><li>thin</li><li>medium (the default value)</li><li>thick</li></ul><p>or express a value in pixels, em or rem or any other valid length value.</p><p>Example:</p><pre>p {<br>  border-width: 2px;<br>}</pre><p>You can set the width of each edge (Top-Right-Bottom-Left) separately by using 4 values:</p><pre>p {<br>  border-width: 2px 1px 2px 1px;<br>}</pre><p>or you can use the specific edge properties border-top-width, border-right-width, border-bottom-width, border-left-width.</p><h4>The border color</h4><p>border-color is used to set the color of the border.</p><p>If you don’t set a color, the border by default is colored using the color of the text in the element.</p><p>You can pass any valid color value to border-color.</p><p>Example:</p><pre>p {<br>  border-color: yellow;<br>}</pre><p>You can set the color of each edge (Top-Right-Bottom-Left) separately by using 4 values:</p><pre>p {<br>  border-color: black red yellow blue;<br>}</pre><p>or you can use the specific edge properties border-top-color, border-right-color, border-bottom-color, border-left-color.</p><h4>The border shorthand property</h4><p>Those 3 properties mentioned, border-width, border-style and border-color can be set using the shorthand property border.</p><p>Example:</p><pre>p {<br>  border: 2px black solid;<br>}</pre><p>You can also use the edge-specific properties border-top, border-right, border-bottom, border-left.</p><p>Example:</p><pre>p {<br>  border-left: 2px black solid;<br>  border-right: 3px red dashed;<br>}</pre><h4>The border radius</h4><p>border-radius is used to set rounded corners to the border. You need to pass a value that will be used as the radius of the circle that will be used to round the border.</p><p>Usage:</p><pre>p {<br>  border-radius: 3px;<br>}</pre><p>You can also use the edge-specific properties border-top-left-radius, border-top-right-radius, border-bottom-left-radius, border-bottom-right-radius.</p><h4>Using images as borders</h4><p>One very cool thing with borders is the ability to use images to style them. This lets you go very creative with borders.</p><p>We have 5 properties:</p><ul><li>border-image-source</li><li>border-image-slice</li><li>border-image-width</li><li>border-image-outset</li><li>border-image-repeat</li></ul><p>and the shorthand border-image. I won&#39;t go in much details here as images as borders would need a more in-depth coverage as what I can do in this little chapter. I recommend reading the <a href="https://css-tricks.com/almanac/properties/b/border-image/">CSS Tricks almanac entry on border-image</a> for more information.</p><h3>PADDING</h3><p>The padding CSS property is commonly used in CSS to add space in the inner side of an element.</p><p>Remember:</p><ul><li>margin adds space outside an element border</li><li>padding adds space inside an element border</li></ul><h4>Specific padding properties</h4><p>padding has 4 related properties that alter the padding of a single edge at once:</p><ul><li>padding-top</li><li>padding-right</li><li>padding-bottom</li><li>padding-left</li></ul><p>The usage of those is very simple and cannot be confused, for example:</p><pre>padding-left: 30px;<br>padding-right: 3em;</pre><h4>Using the padding shorthand</h4><p>padding is a shorthand to specify multiple padding values at the same time, and depending on the number of values entered, it behaves differently.</p><h4>1 value</h4><p>Using a single value applies that to <strong>all</strong> the paddings: top, right, bottom, left.</p><pre>padding: 20px;</pre><h4>2 values</h4><p>Using 2 values applies the first to <strong>bottom &amp; top</strong>, and the second to <strong>left &amp; right</strong>.</p><pre>padding: 20px 10px;</pre><h4>3 values</h4><p>Using 3 values applies the first to <strong>top</strong>, the second to <strong>left &amp; right</strong>, the third to <strong>bottom</strong>.</p><pre>padding: 20px 10px 30px;</pre><h4>4 values</h4><p>Using 4 values applies the first to <strong>top</strong>, the second to <strong>right</strong>, the third to <strong>bottom</strong>, the fourth to <strong>left</strong>.</p><pre>padding: 20px 10px 5px 0px;</pre><p>So, the order is <em>top-right-bottom-left</em>.</p><h4>Values accepted</h4><p>padding accepts values expressed in any kind of length unit, the most common ones are px, em, rem, but <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/length">many others exist</a>.</p><h3>MARGIN</h3><p>The margin CSS property is commonly used in CSS to add space around an element.</p><p>Remember:</p><ul><li>margin adds space outside an element border</li><li>padding adds space inside an element border</li></ul><h4>Specific margin properties</h4><p>margin has 4 related properties that alter the margin of a single edge at once:</p><ul><li>margin-top</li><li>margin-right</li><li>margin-bottom</li><li>margin-left</li></ul><p>The usage of those is very simple and cannot be confused, for example:</p><pre>margin-left: 30px;<br>margin-right: 3em;</pre><h4>Using the margin shorthand</h4><p>margin is a shorthand to specify multiple margins at the same time, and depending on the number of values entered, it behaves differently.</p><h4>1 value</h4><p>Using a single value applies that to <strong>all</strong> the margins: top, right, bottom, left.</p><pre>margin: 20px;</pre><h4>2 values</h4><p>Using 2 values applies the first to <strong>bottom &amp; top</strong>, and the second to <strong>left &amp; right</strong>.</p><pre>margin: 20px 10px;</pre><h4>3 values</h4><p>Using 3 values applies the first to <strong>top</strong>, the second to <strong>left &amp; right</strong>, the third to <strong>bottom</strong>.</p><pre>margin: 20px 10px 30px;</pre><h4>4 values</h4><p>Using 4 values applies the first to <strong>top</strong>, the second to <strong>right</strong>, the third to <strong>bottom</strong>, the fourth to <strong>left</strong>.</p><pre>margin: 20px 10px 5px 0px;</pre><p>So, the order is <em>top-right-bottom-left</em>.</p><h4>Values accepted</h4><p>margin accepts values expressed in any kind of length unit, the most common ones are px, em, rem, but <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/length">many others exist</a>.</p><p>It also accepts percentage values, and the special value auto.</p><h4>Using auto to center elements</h4><p>auto can be used to tell the browser to select automatically a margin, and it&#39;s most commonly used to center an element in this way:</p><pre>margin: 0 auto;</pre><p>As said above, using 2 values applies the first to <strong>bottom &amp; top</strong>, and the second to <strong>left &amp; right</strong>.</p><p>The modern way to center elements is to use <a href="https://flaviocopes.com/flexbox/">Flexbox</a>, and its justify-content: center; directive.</p><p>Older browsers of course do not implement Flexbox, and if you need to support them margin: 0 auto; is still a good choice.</p><h4>Using a negative margin</h4><p>margin is the only property related to sizing that can have a negative value. It&#39;s extremely useful, too. Setting a negative top margin makes an element move over elements before it, and given enough negative value it will move out of the page.</p><p>A negative bottom margin moves up the elements after it.</p><p>A negative right margin makes the content of the element expand beyond its allowed content size.</p><p>A negative left margin moves the element left over the elements that precede it, and given enough negative value it will move out of the page.</p><h3>BOX SIZING</h3><p>The default behavior of browsers when calculating the width of an element is to apply the calculated width and height to the <strong>content area</strong>, without taking any of the padding, border and margin in consideration.</p><p>This approach has proven to be quite complicated to work with.</p><p>You can change this behavior by setting the box-sizing property.</p><p>The box-sizing property is a great help. It has 2 values:</p><ul><li>border-box</li><li>content-box</li></ul><p>content-box is the default, the one we had for ages before box-sizing became a thing.</p><p>border-box is the new and great thing we are looking for. If you set that on an element:</p><pre>.my-div {<br>  box-sizing: border-box;<br>}</pre><p>width and height calculation include the padding and the border. Only the margin is left out, which is reasonable since in our mind we also typically see that as a separate thing: margin is outside of the box.</p><p>This property is a small change but has a big impact. CSS Tricks even declared an <a href="https://css-tricks.com/international-box-sizing-awareness-day/">international box-sizing awareness day</a>, just saying, and it’s recommended to apply it to every element on the page, out of the box, with this:</p><pre>*, *:before, *:after {<br>  box-sizing: border-box;<br>}</pre><h3>DISPLAY</h3><p>The display property of an object determines how it is rendered by the browser.</p><p>It’s a very important property, and probably the one with the highest number of values you can use.</p><p>Those values include:</p><ul><li>block</li><li>inline</li><li>none</li><li>contents</li><li>flow</li><li>flow-root</li><li>table (and all the table-* ones)</li><li>flex</li><li>grid</li><li>list-item</li><li>inline-block</li><li>inline-table</li><li>inline-flex</li><li>inline-grid</li><li>inline-list-item</li></ul><p>plus others you will not likely use, like ruby.</p><p>Choosing any of those will considerably alter the behavior of the browser with the element and its children.</p><p>In this section we’ll analyze the most important ones not covered elsewhere:</p><ul><li>block</li><li>inline</li><li>inline-block</li><li>none</li></ul><p>We’ll see some of the others in later chapters, including coverage of table, flex and grid.</p><h4>inline</h4><p>Inline is the default display value for every element in CSS.</p><p>All the HTML tags are displayed inline out of the box except some elements like div, p and section, which are set as block by the user agent (the browser).</p><p>Inline elements don’t have any margin or padding applied.</p><p>Same for height and width.</p><p>You <em>can</em> add them, but the appearance in the page won’t change — they are calculated and applied automatically by the browser.</p><h4>inline-block</h4><p>Similar to inline, but with inline-block width and height applied as you specify.</p><h4>block</h4><p>As mentioned, normally elements are displayed inline, with the exception of some elements, including</p><ul><li>div</li><li>p</li><li>section</li><li>ul</li></ul><p>which are set as block by the browser.</p><p>With display: block, elements are stacked one after each other, vertically, and every element takes up 100% of the page.</p><p>The values assigned to the width and height properties are respected, if you set them, along with margin and padding.</p><h4>none</h4><p>Using display: none makes an element disappear. It&#39;s still there in the HTML, but just not visible in the browser.</p><h3>POSITIONING</h3><p>Positioning is what makes us determine where elements appear on the screen, and how they appear.</p><p>You can move elements around, and position them exactly where you want.</p><p>In this section we’ll also see how things change on a page based on how elements with different position interact with each other.</p><p>We have one main CSS property: position.</p><p>It can have those 5 values:</p><ul><li>static</li><li>relative</li><li>absolute</li><li>fixed</li><li>sticky</li></ul><h4>Static positioning</h4><p>This is the default value for an element. Static positioned elements are displayed in the normal page flow.</p><h4>Relative positioning</h4><p>If you set position: relative on an element, you are now able to position it with an offset, using the properties</p><ul><li>top</li><li>right</li><li>bottom</li><li>left</li></ul><p>which are called <strong>offset properties</strong>. They accept a length value or a percentage.</p><p>Take <a href="https://codepen.io/flaviocopes/pen/WWGgrR">this example I made on Codepen</a>. I create a parent container, a child container, and an inner box with some text:</p><pre>&lt;div class=&quot;parent&quot;&gt;<br>  &lt;div class=&quot;child&quot;&gt;<br>    &lt;div class=&quot;box&quot;&gt;<br>      &lt;p&gt;Test&lt;/p&gt;<br>    &lt;/div&gt;<br>  &lt;/div&gt;<br>&lt;/div&gt;</pre><p>with some CSS to give some colors and padding, but does not affect positioning:</p><pre>.parent {<br>  background-color: #af47ff;<br>  padding: 30px;<br>  width: 300px;<br>}</pre><pre>.child {<br>  background-color: #ff4797;<br>  padding: 30px;<br>}</pre><pre>.box {<br>  background-color: #f3ff47;<br>  padding: 30px;<br>  border: 2px solid #333;<br>  border-style: dotted;<br>  font-family: courier;<br>  text-align: center;<br>  font-size: 2rem;<br>}</pre><p>here’s the result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/379/1*NpSTXd5BTH4t0Aueg5V4Ew.png" /></figure><p>You can try and add any of the properties I mentioned before (top, right, bottom, left) to .box, and nothing will happen. The position is static.</p><p>Now if we set position: relative to the box, at first apparently nothing changes. But the element is now able to move using the top, right, bottom, left properties, and now you can alter the position of it relatively to the element containing it.</p><p>For example:</p><pre>.box {<br>  /* ... */<br>  position: relative;<br>  top: -60px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/386/1*KwYBBQV397Wy5nNw2aXANw.png" /></figure><p>A negative value for top will make the box move up relatively to its container.</p><p>Or</p><pre>.box {<br>  /* ... */<br>  position: relative;<br>  top: -60px;<br>  left: 180px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/508/1*kDF_fYUArVFn5gf5BGBkeQ.png" /></figure><p>Notice how the space that is occupied by the box remains preserved in the container, like it was still in its place.</p><p>Another property that will now work is z-index to alter the z-axis placement. We&#39;ll talk about it later on.</p><h4>Absolute positioning</h4><p>Setting position: absolute on an element will remove it from the document&#39;s flow.</p><p>Remember in relative positioning that we noticed the space originally occupied by an element was preserved even if it was moved around?</p><p>With absolute positioning, as soon as we set position: absolute on .box, its original space is now collapsed, and only the origin (x, y coordinates) remain the same.</p><pre>.box {<br>  /* ... */<br>  position: absolute;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/381/1*nflIyA6jy95Z6EqiblUSAA.png" /></figure><p>We can now move the box around as we please, using the top, right, bottom, left properties:</p><pre>.box {<br>  /* ... */<br>  position: absolute;<br>  top: 0px;<br>  left: 0px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/419/1*hOUkqhsHM9x0_HdPTGSFWA.png" /></figure><p>or</p><pre>.box {<br>  /* ... */<br>  position: absolute;<br>  top: 140px;<br>  left: 50px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/388/1*ndOXkDvDO0b5pqAw6iTXrQ.png" /></figure><p>The coordinates are relative to the closest container that is not static.</p><p>This means that if we add position: relative to the .child element, and we set top and left to 0, the box will not be positioned at the top left margin of the <em>window</em>, but rather it will be positioned at the 0, 0 coordinates of .child:</p><pre>.child {<br>  /* ... */<br>  position: relative;<br>}</pre><pre>.box {<br>  /* ... */<br>  position: absolute;<br>  top: 0px;<br>  left: 0px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/419/1*k_BCMo14lF_AmNMdOIflyQ.png" /></figure><p>Here’s how we already saw that .child is static (the default):</p><pre>.child {<br>  /* ... */<br>  position: static;<br>}</pre><pre>.box {<br>  /* ... */<br>  position: absolute;<br>  top: 0px;<br>  left: 0px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/419/1*hOUkqhsHM9x0_HdPTGSFWA.png" /></figure><p>Like for relative positioning, you can use z-index to alter the z-axis placement.</p><h4>Fixed positioning</h4><p>Like with absolute positioning, when an element is assigned position: fixed it&#39;s removed from the flow of the page.</p><p>The difference with absolute positioning is this: elements are now always positioned relative to the window, instead of the first non-static container.</p><pre>.box {<br>  /* ... */<br>  position: fixed;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/381/1*eqTXNTo-QFdQUJU-pOvSxw.png" /></figure><pre>.box {<br>  /* ... */<br>  position: fixed;<br>  top: 0;<br>  left: 0;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/395/1*1AIOKLr8dHSPRmciRClzIg.png" /></figure><p>Another big difference is that elements are not affected by scrolling. Once you put a sticky element somewhere, scrolling the page does not remove it from the visible part of the page.</p><h4>Sticky positioning</h4><p>While the above values have been around for a very long time, this one was introduced recently and it’s still relatively unsupported (<a href="https://caniuse.com/#feat=css-sticky">see caniuse.com</a>)</p><p>The UITableView iOS component is the thing that comes to mind when I think about position: sticky. You know when you scroll in the contacts list and the first letter is stuck to the top, to let you know you are viewing that particular letter&#39;s contacts?</p><p>We used JavaScript to emulate that, but this is the approach taken by CSS to allow it natively.</p><h3>FLOATING AND CLEARING</h3><p>Floating has been a very important topic in the past.</p><p>It was used in lots of hacks and creative usages because it was one of the few ways, along with tables, we could really implement some layouts. In the past we used to float the sidebar to the left, for example, to show it on the left side of the screen and added some margin to the main content.</p><p>Luckily times have changed and today we have Flexbox and Grid to help us with layout, and float has gone back to its original scope: placing content on one side of the container element, and making its siblings show up around it.</p><p>The float property supports 3 values:</p><ul><li>left</li><li>right</li><li>none (the default)</li></ul><p>Say we have a box which contains a paragraph with some text, and the paragraph also contains an image.</p><p>Here’s some code:</p><pre>&lt;div class=&quot;parent&quot;&gt;<br>  &lt;div class=&quot;child&quot;&gt;<br>    &lt;div class=&quot;box&quot;&gt;<br>      &lt;p&gt;This is some random paragraph and an image. &lt;img src=&quot;<a href="https://via.placeholder.com/100x100">https://via.placeholder.com/100x100</a>&quot; /&gt; The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text.<br>      &lt;/p&gt;<br>    &lt;/div&gt;<br>  &lt;/div&gt;<br>&lt;/div&gt;</pre><pre>.parent {<br>  background-color: #af47ff;<br>  padding: 30px;<br>  width: 500px;<br>}</pre><pre>.child {<br>  background-color: #ff4797;<br>  padding: 30px;<br>}</pre><pre>.box {<br>  background-color: #f3ff47;<br>  padding: 30px;<br>  border: 2px solid #333;<br>  border-style: dotted;<br>  font-family: courier;<br>  text-align: justify;<br>  font-size: 1rem;<br>}</pre><p>and the visual appearance:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/578/1*0ux7Op0joayz9IYbkcOP2Q.png" /></figure><p>As you can see, the normal flow by default considers the image inline, and makes space for it in the line itself.</p><p>If we add float: left to the image, and some padding:</p><pre>img {<br>  float: left;<br>  padding: 20px 20px 0px 0px;<br>}</pre><p>this is the result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/584/1*tyzn3Kw5q70J4WLRCdfCHw.png" /></figure><p>and this is what we get by applying a float: right, adjusting the padding accordingly:</p><pre>img {<br>  float: right;<br>  padding: 20px 0px 20px 20px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/583/1*qnu-HXF_kMidFXsrNN3Ufw.png" /></figure><p>A floated element is removed from the normal flow of the page, and the other content flows around it.</p><p><a href="https://codepen.io/flaviocopes/pen/WWGqPr?editors=1100">See the example on Codepen</a></p><p>You are not limited to floating images, too. Here we switch the image with a span element:</p><pre>&lt;div class=&quot;parent&quot;&gt;<br>  &lt;div class=&quot;child&quot;&gt;<br>    &lt;div class=&quot;box&quot;&gt;<br>      &lt;p&gt;This is some random paragraph and an image. &lt;span&gt;Some text to float&lt;/span&gt; The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text.<br>      &lt;/p&gt;<br>    &lt;/div&gt;<br>  &lt;/div&gt;<br>&lt;/div&gt;</pre><pre>span {<br>  float: right;<br>  margin: 20px 0px 20px 20px;<br>  padding: 10px;<br>  border: 1px solid black<br>}</pre><p>and this is the result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/579/1*4ZWnT4C5RHLQqifULV8EUw.png" /></figure><h4>Clearing</h4><p>What happens when you float more than one element?</p><p>If when floated they find another floated image, by default they are stacked up one next to the other, horizontally. Until there is no room, and they will start being stacked on a new line.</p><p>Say we had 3 inline images inside a p tag:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/580/1*bDr4zfU21m8tCxrmy_FOmg.png" /></figure><p>If we add float: left to those images:</p><pre>img {<br>  float: left;<br>  padding: 20px 20px 0px 0px;<br>}</pre><p>this is what we’ll have:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/1*jxV_lywxjr9c02Cn9mtO8g.png" /></figure><p>if you add clear: left to images, those are going to be stacked vertically rather than horizontally:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/578/1*k3HUxqOo4AmjOYmnemHpmQ.png" /></figure><p>I used the left value for clear. It allows</p><ul><li>left to clear left floats</li><li>right to clear right floats</li><li>both to clear both left and right floats</li><li>none (default) disables clearing</li></ul><h3>Z-INDEX</h3><p>When we talked about positioning, I mentioned that you can use the z-index property to control the Z axis positioning of elements.</p><p>It’s very useful when you have multiple elements that overlap each other, and you need to decide which one is visible, as nearer to the user, and which one(s) should be hidden behind it.</p><p>This property takes a number (without decimals) and uses that number to calculate which elements appear nearer to the user, in the Z axis.</p><p>The higher the z-index value, the more an element is positioned nearer to the user.</p><p>When deciding which element should be visible and which one should be positioned behind it, the browser does a calculation on the z-index value.</p><p>The default value is auto, a special keyword. Using auto, the Z axis order is determined by the position of the HTML element in the page - the last sibling appears first, as it&#39;s defined last.</p><p>By default elements have the static value for the position property. In this case, the z-index property does not make any difference - it must be set to absolute, relative or fixed to work.</p><p>Example:</p><pre>.my-first-div {<br>    position: absolute;<br>    top: 0;<br>    left: 0;<br>    width: 600px;<br>    height: 600px;<br>    z-index: 10;<br>}</pre><pre>.my-second-div {<br>    position: absolute;<br>    top: 0;<br>    left: 0;<br>    width: 500px;<br>    height: 500px;<br>    z-index: 20;<br>}</pre><p>The element with class .my-second-div will be displayed, and behind it .my-first-div.</p><p>Here we used 10 and 20, but you can use any number. Negative numbers too. It’s common to pick non-consecutive numbers, so you can position elements in the middle. If you use consecutive numbers instead, you would need to re-calculate the z-index of each element involved in the positioning.</p><h3>CSS GRID</h3><p>CSS Grid is the new kid in the CSS town, and while not yet fully supported by all browsers, it’s going to be the future system for layouts.</p><p>CSS Grid is a fundamentally new approach to building layouts using CSS.</p><p>Keep an eye on the CSS Grid Layout page on caniuse.com (<a href="https://caniuse.com/#feat=css-grid">https://caniuse.com/#feat=css-grid</a>) to find out which browsers currently support it. At the time of writing, April 2019, all major browsers (except IE, which will never have support for it) are already supporting this technology, covering 92% of all users.</p><p>CSS Grid is not a competitor to Flexbox. They interoperate and collaborate on complex layouts, because CSS Grid works on 2 dimensions (rows AND columns) while Flexbox works on a single dimension (rows OR columns).</p><p>Building layouts for the web has traditionally been a complicated topic.</p><p>I won’t dig into the reasons for this complexity, which is a complex topic on its own. But you can think yourself as a very lucky human because nowadays you have 2 very powerful and well supported tools at your disposal:</p><ul><li><strong>CSS Flexbox</strong></li><li><strong>CSS Grid</strong></li></ul><p>These 2 are the tools to build the Web layouts of the future.</p><p>Unless you need to support old browsers like IE8 and IE9, there is no reason to be messing with things like:</p><ul><li>Table layouts</li><li>Floats</li><li>clearfix hacks</li><li>display: table hacks</li></ul><p>In this guide there’s all you need to know about going from zero knowledge of CSS Grid to being a proficient user.</p><h4>The basics</h4><p>The CSS Grid layout is activated on a container element (which can be a div or any other tag) by setting display: grid.</p><p>As with flexbox, you can define some properties on the container, and some properties on each individual item in the grid.</p><p>These properties combined will determine the final look of the grid.</p><p>The most basic container properties are grid-template-columns and grid-template-rows.</p><h4>grid-template-columns and grid-template-rows</h4><p>Those properties define the number of columns and rows in the grid, and they also set the width of each column/row.</p><p>The following snippet defines a grid with 4 columns each 200px wide, and 2 rows with a 300px height each.</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 200px 200px 200px 200px;<br>  grid-template-rows: 300px 300px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*zSTaLMgkEfFqMyMvW-Y42w.png" /></figure><p>Here’s another example of a grid with 2 columns and 2 rows:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 200px 200px;<br>  grid-template-rows: 100px 100px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/696/1*EIBZBxA2P-m4SokHwCWm9Q.png" /></figure><h4>Automatic dimensions</h4><p>Many times you might have a fixed header size, a fixed footer size, and the main content that is flexible in height, depending on its length. In this case you can use the auto keyword:</p><pre>.container {<br>  display: grid;<br>  grid-template-rows: 100px auto 100px;<br>}</pre><h4>Different columns and rows dimensions</h4><p>In the above examples we made regular grids by using the same values for rows and the same values for columns.</p><p>You can specify any value for each row/column, to create a lot of different designs:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 100px 200px;<br>  grid-template-rows: 100px 50px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/597/1*l0Xzao03U65dX88GWXiswQ.png" /></figure><p>Another example:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 10px 100px;<br>  grid-template-rows: 100px 10px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/581/1*Qbe-tBDOzjtGLduBjjikgw.png" /></figure><h4>Adding space between the cells</h4><p>Unless specified, there is no space between the cells.</p><p>You can add spacing by using those properties:</p><ul><li>grid-column-gap</li><li>grid-row-gap</li></ul><p>or the shorthand syntax grid-gap.</p><p>Example:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 100px 200px;<br>  grid-template-rows: 100px 50px;<br>  grid-column-gap: 25px;<br>  grid-row-gap: 25px;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/642/1*N3P4AFRtJzkc5D2dAqlWKA.png" /></figure><p>The same layout using the shorthand:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 100px 200px;<br>  grid-template-rows: 100px 50px;<br>  grid-gap: 25px;<br>}</pre><h4>Spawning items on multiple columns and/or rows</h4><p>Every cell item has the option to occupy more than just one box in the row, and expand horizontally or vertically to get more space, while respecting the grid proportions set in the container.</p><p>These are the properties we’ll use for that:</p><ul><li>grid-column-start</li><li>grid-column-end</li><li>grid-row-start</li><li>grid-row-end</li></ul><p>Example:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 200px 200px 200px 200px;<br>  grid-template-rows: 300px 300px;<br>}<br>.item1 {<br>  grid-column-start: 2;<br>  grid-column-end: 4;<br>}<br>.item6 {<br>  grid-column-start: 3;<br>  grid-column-end: 5;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/730/1*uqKy096inIpnHiMDMGmOpw.png" /></figure><p>The numbers correspond to the vertical line that separates each column, starting from 1:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/745/1*D14pVXJgN9gcCxBzAB4opg.png" /></figure><p>The same principle applies to grid-row-start and grid-row-end, except this time instead of taking more columns, a cell takes more rows.</p><h4>Shorthand syntax</h4><p>Those properties have a shorthand syntax provided by:</p><ul><li>grid-column</li><li>grid-row</li></ul><p>The usage is simple, here’s how to replicate the above layout:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 200px 200px 200px 200px;<br>  grid-template-rows: 300px 300px;<br>}<br>.item1 {<br>  grid-column: 2 / 4;<br>}<br>.item6 {<br>  grid-column: 3 / 5;<br>}</pre><p>Another approach is to set the starting column/row, and set how many it should occupy using span:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 200px 200px 200px 200px;<br>  grid-template-rows: 300px 300px;<br>}<br>.item1 {<br>  grid-column: 2 / span 2;<br>}<br>.item6 {<br>  grid-column: 3 / span 2;<br>}</pre><h3>More grid configuration</h3><h4>Using fractions</h4><p>Specifying the exact width of each column or row is not ideal in every case.</p><p>A fraction is a unit of space.</p><p>The following example divides a grid into 3 columns with the same width, 1/3 of the available space each.</p><pre>.container {<br>  grid-template-columns: 1fr 1fr 1fr;<br>}</pre><h4>Using percentages and rem</h4><p>You can also use percentages, and mix and match fractions, pixels, rem and percentages:</p><pre>.container {<br>  grid-template-columns: 3rem 15% 1fr 2fr<br>}</pre><h4>Using repeat()</h4><p>repeat() is a special function that takes a number that indicates the number of times a row/column will be repeated, and the length of each one.</p><p>If every column has the same width, you can specify the layout using this syntax:</p><pre>.container {<br>  grid-template-columns: repeat(4, 100px);<br>}</pre><p>This creates 4 columns with the same width.</p><p>Or using fractions:</p><pre>.container {<br>  grid-template-columns: repeat(4, 1fr);<br>}</pre><h4>Specify a minimum width for a row</h4><p>Common use case: Have a sidebar that never collapses more than a certain amount of pixels when you resize the window.</p><p>Here’s an example where the sidebar takes 1/4 of the screen and never takes less than 200px:</p><pre>.container {<br>  grid-template-columns: minmax(200px, 3fr) 9fr;<br>}</pre><p>You can also set just a maximum value using the auto keyword:</p><pre>.container {<br>  grid-template-columns: minmax(auto, 50%) 9fr;<br>}</pre><p>or just a minimum value:</p><pre>.container {<br>  grid-template-columns: minmax(100px, auto) 9fr;<br>}</pre><h4>Positioning elements using grid-template-areas</h4><p>By default elements are positioned in the grid using their order in the HTML structure.</p><p>Using grid-template-areas you can define template areas to move them around in the grid, and also to spawn an item on multiple rows / columns instead of using grid-column.</p><p>Here’s an example:</p><pre>&lt;div class=&quot;container&quot;&gt;<br>  &lt;main&gt;<br>    ...<br>  &lt;/main&gt;<br>  &lt;aside&gt;<br>    ...<br>  &lt;/aside&gt;<br>  &lt;header&gt;<br>    ...<br>  &lt;/header&gt;<br>  &lt;footer&gt;<br>    ...<br>  &lt;/footer&gt;<br>&lt;/div&gt;</pre><pre>.container {<br>  display: grid;<br>  grid-template-columns: 200px 200px 200px 200px;<br>  grid-template-rows: 300px 300px;<br>  grid-template-areas:<br>    &quot;header header header header&quot;<br>    &quot;sidebar main main main&quot;<br>    &quot;footer footer footer footer&quot;;<br>}<br>main {<br>  grid-area: main;<br>}<br>aside {<br>  grid-area: sidebar;<br>}<br>header {<br>  grid-area: header;<br>}<br>footer {<br>  grid-area: footer;<br>}</pre><p>Despite their original order, items are placed where grid-template-areas define, depending on the grid-area property associated to them.</p><h4>Adding empty cells in template areas</h4><p>You can set an empty cell using the dot . instead of an area name in grid-template-areas:</p><pre>.container {<br>  display: grid;<br>  grid-template-columns: 200px 200px 200px 200px;<br>  grid-template-rows: 300px 300px;<br>  grid-template-areas:<br>    &quot;. header header .&quot;<br>    &quot;sidebar . main main&quot;<br>    &quot;. footer footer .&quot;;<br>}</pre><h4>Fill a page with a grid</h4><p>You can make a grid extend to fill the page using fr:</p><pre>.container {<br>  display: grid;<br>  height: 100vh;<br>  grid-template-columns: 1fr 1fr 1fr 1fr;<br>  grid-template-rows: 1fr 1fr;<br>}</pre><h4>An example: header, sidebar, content and footer</h4><p>Here is a simple example of using CSS Grid to create a site layout that provides a header op top, a main part with sidebar on the left and content on the right, and a footer afterwards.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/768/1*GZJxOGF4x_dfKnEKlkL3Ag.png" /></figure><p>Here’s the markup:</p><pre>&lt;div class=&quot;wrapper&quot;&gt;<br>  &lt;header&gt;Header&lt;/header&gt;<br>  &lt;article&gt;<br>    &lt;h1&gt;Welcome&lt;/h1&gt;<br>    &lt;p&gt;Hi!&lt;/p&gt;<br>  &lt;/article&gt;<br>  &lt;aside&gt;&lt;ul&gt;&lt;li&gt;Sidebar&lt;/li&gt;&lt;/ul&gt;&lt;/aside&gt;<br>  &lt;footer&gt;Footer&lt;/footer&gt;<br>&lt;/div&gt;</pre><p>and here’s the CSS:</p><pre>header {<br>  grid-area: header;<br>  background-color: #fed330;<br>  padding: 20px;<br>}<br>article {<br>  grid-area: content;<br>  background-color: #20bf6b;<br>  padding: 20px;<br>}<br>aside {<br>  grid-area: sidebar;<br>  background-color: #45aaf2;<br>}<br>footer {<br>  padding: 20px;<br>  grid-area: footer;<br>  background-color: #fd9644;<br>}<br>.wrapper {<br>  display: grid;<br>  grid-gap: 20px;<br>  grid-template-columns: 1fr 3fr;<br>  grid-template-areas:<br>    &quot;header  header&quot;<br>    &quot;sidebar content&quot;<br>    &quot;footer  footer&quot;;<br>}</pre><p>I added some colors to make it prettier, but basically it assigns to every different tag a grid-area name, which is used in the grid-template-areas property in .wrapper.</p><p>When the layout is smaller we can put the sidebar below the content using a media query:</p><pre><a href="http://twitter.com/media">@media</a> (max-width: 500px) {<br>  .wrapper {<br>    grid-template-columns: 4fr;<br>    grid-template-areas:<br>      &quot;header&quot;<br>      &quot;content&quot;<br>      &quot;sidebar&quot;<br>      &quot;footer&quot;;<br>  }<br>}</pre><p><a href="https://codepen.io/flaviocopes/pen/JZWOEK">See on CodePen</a></p><p>These are the basics of CSS Grid. There are many things I didn’t include in this introduction but I wanted to make it very simple, so you can start using this new layout system without making it feel overwhelming.</p><h3>FLEXBOX</h3><p>Flexbox, also called Flexible Box Module, is one of the two modern layouts systems, along with CSS Grid.</p><p>Compared to CSS Grid (which is bi-dimensional), flexbox is a <strong>one-dimensional layout model</strong>. It will control the layout based on a row or on a column, but not together at the same time.</p><p>The main goal of flexbox is to allow items to fill the whole space offered by their container, depending on some rules you set.</p><p>Unless you need to support old browsers like IE8 and IE9, Flexbox is the tool that lets you forget about using</p><ul><li>Table layouts</li><li>Floats</li><li>clearfix hacks</li><li>display: table hacks</li></ul><p>Let’s dive into flexbox and become a master of it in a very short time.</p><h3>Browser support</h3><p>At the time of writing (Feb 2018), it’s supported by 97.66% of the users. All the most important browsers have implemented it for years, so even older browsers (including IE10+) are covered:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/683/1*Zrt2XEGxxay2_Y76qdphAQ.png" /></figure><p>While we must wait a few years for users to catch up on CSS Grid, Flexbox is an older technology and can be used right now.</p><h3>Enable Flexbox</h3><p>A flexbox layout is applied to a container, by setting</p><pre>display: flex;</pre><p>or</p><pre>display: inline-flex;</pre><p>The content <strong>inside the container</strong> will be aligned using flexbox.</p><h4>Container properties</h4><p>Some flexbox properties apply to the container, which sets the general rules for its items. They are</p><ul><li>flex-direction</li><li>justify-content</li><li>align-items</li><li>flex-wrap</li><li>flex-flow</li></ul><h4>Align rows or columns</h4><p>The first property we see, <strong>flex-direction</strong>, determines if the container should align its items as rows, or as columns:</p><ul><li>flex-direction: row places items as a <strong>row</strong>, in the text direction (left-to-right for western countries)</li><li>flex-direction: row-reverse places items just like row but in the opposite direction</li><li>flex-direction: column places items in a <strong>column</strong>, ordering top to bottom</li><li>flex-direction: column-reverse places items in a column, just like column but in the opposite direction</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/616/1*d6lABFbObfmzoddmEpA_Qg.png" /></figure><h4>Vertical and horizontal alignment</h4><p>By default, items start from the left if flex-direction is row, and from the top if flex-direction is column.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/625/1*nN-0W-GWh9LsVWDv6QgxMA.png" /></figure><p>You can change this behavior using justify-content to change the horizontal alignment, and align-items to change the vertical alignment.</p><h4>Change the horizontal alignment</h4><p><strong>justify-content</strong> has 5 possible values:</p><ul><li>flex-start: align to the left side of the container.</li><li>flex-end: align to the right side of the container.</li><li>center: align at the center of the container.</li><li>space-between: display with equal spacing between them.</li><li>space-around: display with equal spacing around them</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/869/1*wVMAVomypsux-cBLitVjaw.png" /></figure><h4>Change the vertical alignment</h4><p><strong>align-items</strong> has 5 possible values:</p><ul><li>flex-start: align to the top of the container.</li><li>flex-end: align to the bottom of the container.</li><li>center: align at the vertical center of the container.</li><li>baseline: display at the baseline of the container.</li><li>stretch: items are stretched to fit the container.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/606/1*P14Ict738lYO7i0fsVF3QQ.png" /></figure><p>A note on baseline:</p><p>baseline looks similar to flex-start in this example, due to my boxes being too simple. Check out <a href="https://codepen.io/flaviocopes/pen/oExoJR">this Codepen</a> to have a more useful example, which I forked from a Pen originally created by <a href="https://twitter.com/machal">Martin Michálek</a>. As you can see there, item dimensions are aligned.</p><h4>Wrap</h4><p>By default, items in a flexbox container are kept on a single line, shrinking them to fit in the container.</p><p>To force the items to spread across multiple lines, use flex-wrap: wrap. This will distribute the items according to the order set in flex-direction. Use flex-wrap: wrap-reverse to reverse this order.</p><p>A shorthand property called flex-flow allows you to specify flex-direction and flex-wrap in a single line, by adding the flex-direction value first, followed by flex-wrap value, for example: flex-flow: row wrap.</p><h4>Properties that apply to each single item</h4><p>Up to this point, we’ve seen the properties you can apply to the container.</p><p>Single items can have a certain amount of independence and flexibility, and you can alter their appearance using those properties:</p><ul><li>order</li><li>align-self</li><li>flex-grow</li><li>flex-shrink</li><li>flex-basis</li><li>flex</li></ul><p>Let’s see them in detail.</p><h4>Moving items before / after another one using order</h4><p>Items are ordered based on the order they are assigned. By default every item has order 0 and the appearance in the HTML determines the final order.</p><p>You can override this property using order on each separate item. This is a property you set on the item, not the container. You can make an item appear before all the others by setting a negative value.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/607/1*nl05F2vr__l9Rq8ex_6tnQ.png" /></figure><h4>Vertical alignment using align-self</h4><p>An item can choose to <strong>override</strong> the container align-items setting, using <strong>align-self</strong>, which has the same 5 possible values of align-items:</p><ul><li>flex-start: align to the top of the container.</li><li>flex-end: align to the bottom of the container.</li><li>center: align at the vertical center of the container.</li><li>baseline: display at the baseline of the container.</li><li>stretch: items are stretched to fit the container.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*74lVS32M-SXzUPaxOFFs0A.png" /></figure><h4>Grow or shrink an item if necessary</h4><p><strong>flex-grow</strong></p><p>The defaut for any item is 0.</p><p>If all items are defined as 1 and one is defined as 2, the bigger element will take the space of two “1” items.</p><p><strong>flex-shrink</strong></p><p>The defaut for any item is 1.</p><p>If all items are defined as 1 and one is defined as 3, the bigger element will shrink 3x the other ones. When less space is available, it will take 3x less space.</p><p><strong>flex-basis</strong></p><p>If set to auto, it sizes an item according to its width or height, and adds extra space based on the flex-grow property.</p><p>If set to 0, it does not add any extra space for the item when calculating the layout.</p><p>If you specify a pixel number value, it will use that as the length value (width or height depends on if it’s a row or a column item)</p><p><strong>flex</strong></p><p>This property combines the above 3 properties:</p><ul><li>flex-grow</li><li>flex-shrink</li><li>flex-basis</li></ul><p>and provides a shorthand syntax: flex: 0 1 auto</p><h3>TABLES</h3><p>Tables in the past were greatly overused in CSS, as they were one of the only ways we could create a fancy page layout.</p><p>Today with Grid and Flexbox we can move tables back to the job they were intended to do: styling tables.</p><p>Let’s start from the HTML. This is a basic table:</p><pre>&lt;table&gt;<br>  &lt;thead&gt;<br>    &lt;tr&gt;<br>      &lt;th scope=&quot;col&quot;&gt;Name&lt;/th&gt;<br>      &lt;th scope=&quot;col&quot;&gt;Age&lt;/th&gt;<br>    &lt;/tr&gt;<br>  &lt;/thead&gt;<br>  &lt;tbody&gt;<br>    &lt;tr&gt;<br>      &lt;th scope=&quot;row&quot;&gt;Flavio&lt;/th&gt;<br>      &lt;td&gt;36&lt;/td&gt;<br>    &lt;/tr&gt;<br>    &lt;tr&gt;<br>      &lt;th scope=&quot;row&quot;&gt;Roger&lt;/th&gt;<br>      &lt;td&gt;7&lt;/td&gt;<br>    &lt;/tr&gt;<br>  &lt;/tbody&gt;<br>&lt;/table&gt;</pre><p>By default it’s not very attractive. The browser provides some standard styles, and that’s it:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/346/1*XcQ1sQVZEoxv4AGbPF8quw.png" /></figure><p>We can use CSS to style all the elements of the table, of course.</p><p>Let’s start with the border. A nice border can go a long way.</p><p>We can apply it on the table element, and on the inner elements too, like th and td:</p><pre>table, th, td {<br>  border: 1px solid #333;<br>}</pre><p>If we pair it with some margin, we get a nice result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/402/1*bcVAPWz_1J-Ini6IDxmKlA.png" /></figure><p>One common thing with tables is the ability to add a color to one row, and a different color to another row. This is possible using the :nth-child(odd) or :nth-child(even) selector:</p><pre>tbody tr:nth-child(odd) {<br>  background-color: #af47ff;<br>}</pre><p>This gives us:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/387/1*1qRgMRN3gc-F5BW_FQAgTA.png" /></figure><p>If you add border-collapse: collapse; to the table element, all borders are collapsed into one:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*1Oyw7NHCkoMqvzt4yPizSA.png" /></figure><h3>CENTERING</h3><p>Centering things in CSS is a task that is very different if you need to center horizontally or vertically.</p><p>In this post I explain the most common scenarios and how to solve them. If a new solution is provided by <a href="https://flaviocopes.com/flexbox/">Flexbox</a> I ignore the old techniques because we need to move forward, and Flexbox has been supported by browsers for years, IE10 included.</p><h3>Center horizontally</h3><h4>Text</h4><p>Text is very simple to center horizontally using the text-align property set to center:</p><pre>p {<br>  text-align: center;<br>}</pre><h4>Blocks</h4><p>The modern way to center anything that is not text is to use Flexbox:</p><pre>#mysection {<br>  display: flex;<br>  justify-content: center;<br>}</pre><p>any element inside #mysection will be horizontally centered.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/618/1*q0HxM1dgYN8C8n8QpGDH5g.png" /></figure><p>Here is the alternative approach if you don’t want to use Flexbox.</p><p>Anything that is not text can be centered by applying an automatic margin to left and right, and setting the width of the element:</p><pre>section {<br>  margin: 0 auto;<br>  width: 50%;<br>}</pre><p>the above margin: 0 auto; is a shorthand for:</p><pre>section {<br>  margin-top: 0;<br>  margin-bottom: 0;<br>  margin-left: auto;<br>  margin-right: auto;<br>}</pre><p>Remember to set the item to display: block if it&#39;s an inline element.</p><h3>Center vertically</h3><p>Traditionally this has always been a difficult task. Flexbox now provides us a great way to do this in the simplest possible way:</p><pre>#mysection {<br>  display: flex;<br>  align-items: center;<br>}</pre><p>any element inside #mysection will be vertically centered.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/613/1*XRtHWK4px1Xq-01ZTDxvYw.png" /></figure><h3>Center both vertically and horizontally</h3><p>Flexbox techniques to center vertically and horizontally can be combined to completely center an element in the page.</p><pre>#mysection {<br>  display: flex;<br>  align-items: center;<br>  justify-content: center;<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/615/1*hOfATH2E3NurmrcdhVRnNQ.png" /></figure><p>The same can be done using <a href="https://flaviocopes.com/css-grid/">CSS Grid</a>:</p><pre>body {<br>  display: grid;<br>  place-items: center;<br>  height: 100vh;<br>}</pre><h3>LISTS</h3><p>Lists are a very important part of many web pages.</p><p>CSS can style them using several properties.</p><p>list-style-type is used to set a predefined marker to be used by the list:</p><pre>li {<br>  list-style-type: square;<br>}</pre><p>We have lots of possible values, which you can see here <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type">https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type</a> with examples of their appearance. Some of the most popular ones are disc, circle, square and none.</p><p>list-style-image is used to use a custom marker when a predefined marker is not appropriate:</p><pre>li {<br>  list-style-image: url(list-image.png);<br>}</pre><p>list-style-position lets you add the marker outside (the default) or inside of the list content, in the flow of the page rather than outside of it</p><pre>li {<br>  list-style-position: inside;<br>}</pre><p>The list-style shorthand property lets us specify all those properties in the same line:</p><pre>li {<br>  list-style: url(list-image.png) inside;<br>}</pre><h3>MEDIA QUERIES AND RESPONSIVE DESIGN</h3><p>In this section we’re going to first introduce media types and media feature descriptors, then we’ll explain media queries.</p><h4>Media types</h4><p>Used in media queries and @import declarations, media types allow us to determine on which media a CSS file, or a piece of CSS, is loaded.</p><p>We have the following <strong>media types</strong></p><ul><li>all means all the media</li><li>print used when printing</li><li>screen used when the page is presented on a screen</li><li>speech used for screen readers</li></ul><p>screen is the default.</p><p>In the past we had more of them, but most are deprecated as they proved to be ineffective ways of determining device needs.</p><p>We can use them in @import statements like this:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) screen;<br><a href="http://twitter.com/import">@import</a> url(myfile-print.css) print;</pre><p>We can load a CSS file on multiple media types separating each with a comma:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) screen, print;</pre><p>The same works for the link tag in HTML:</p><pre>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;myfile.css&quot; media=&quot;screen&quot; /&gt;<br>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;another.css&quot; media=&quot;screen, print&quot; /&gt;</pre><p>We’re not limited to just using media types in the media attribute and in the @import declaration. There&#39;s more.</p><h4>Media feature descriptors</h4><p>First, let’s introduce <strong>media feature descriptors</strong>. They are additional keywords that we can add to the media attribute of link or the the @import declaration, to express more conditionals over the loading of the CSS.</p><p>Here’s the list of them:</p><ul><li>width</li><li>height</li><li>device-width</li><li>device-height</li><li>aspect-ratio</li><li>device-aspect-ratio</li><li>color</li><li>color-index</li><li>monochrome</li><li>resolution</li><li>orientation</li><li>scan</li><li>grid</li></ul><p>Each of them has a corresponding min-<em> and max-</em>, for example:</p><ul><li>min-width, max-width</li><li>min-device-width, max-device-width</li></ul><p>and so on.</p><p>Some of those accept a length value which can be expressed in px or rem or any length value. It&#39;s the case of width, height, device-width, device-height.</p><p>For example:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) screen and (max-width: 800px);</pre><p>Notice that we wrap each block using media feature descriptors in parentheses.</p><p>Some accept a fixed value. orientation, used to detect the device orientation, accepts portrait or landscape.</p><p>Example:</p><pre>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;myfile.css&quot; media=&quot;screen and (orientation: portrait)&quot; /&gt;</pre><p>scan, used to determine the type of screen, accepts progressive (for modern displays) or interlace (for older CRT devices).</p><p>Some others want an integer.</p><p>Like color which inspects the number of bits per color component used by the device. Very low-level, but you just need to know it&#39;s there for your usage (like grid, color-index, monochrome).</p><p>aspect-ratio and device-aspect-ratio accept a ratio value representing the width to height viewport ratio, which is expressed as a fraction.</p><p>Example:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) screen and (aspect-ratio: 4/3);</pre><p>resolution represents the pixel density of the device, expressed in a <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/resolution">resolution data type</a> like dpi.</p><p>Example:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) screen and (min-resolution: 100dpi);</pre><h4>Logic operators</h4><p>We can combine rules using and:</p><pre>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;myfile.css&quot; media=&quot;screen and (max-width: 800px)&quot; /&gt;</pre><p>We can perform an “or” type of logic operation using commas, which combines multiple media queries:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) screen, print;</pre><p>We can use not to negate a media query:</p><pre><a href="http://twitter.com/import">@import</a> url(myfile.css) not screen;</pre><blockquote><em>Important: </em><em>not can only be used to negate an entire media query, so it must be placed at the beginning of it (or after a comma).</em></blockquote><h4>Media queries</h4><p>All those above rules we saw applied to @import or the the link HTML tag can be applied inside the CSS, too.</p><p>You need to wrap them in a @media () {} structure.</p><p>Example:</p><pre><a href="http://twitter.com/media">@media</a> screen and (max-width: 800px) {<br>  /* enter some CSS */<br>}</pre><p>and this is the foundation for <strong>responsive design</strong>.</p><p>Media queries can be quite complex. This example applies the CSS only if it’s a screen device, the width is between 600 and 800 pixels, and the orientation is landscape:</p><pre><a href="http://twitter.com/media">@media</a> screen and (max-width: 800px) and (min-width: 600px) and (orientation: landscape) {<br>  /* enter some CSS */<br>}</pre><h3>FEATURE QUERIES</h3><p>Feature queries are a recent and relatively unknown ability of CSS, but a <a href="https://caniuse.com/#feat=css-featurequeries">well supported</a> one.</p><p>We can use it to check if a feature is supported by the browser using the @supports keyword.</p><p>I think this is especially useful, at the time of writing, for checking if a browser supports CSS grid, for example, which can be done using:</p><pre><a href="http://twitter.com/supports">@supports</a> (display: grid) {<br>  /* apply this CSS */<br>}</pre><p>We check if the browser supports the grid value for the display property.</p><p>We can use @supports for any CSS property, to check any value.</p><p>We can also use the logical operators and, or and not to build complex feature queries:</p><pre><a href="http://twitter.com/supports">@supports</a> (display: grid) and (display: flex) {<br>  /* apply this CSS */<br>}</pre><h3>FILTERS</h3><p>Filters allow us to perform operations on elements.</p><p>Things you normally do with Photoshop or other photo editing software, like changing the opacity or the brightness, and more.</p><p>You use the filter property. Here&#39;s an example of it applied on an image, but this property can be used on <em>any</em> element:</p><pre>img {<br>  filter: &lt;something&gt;;<br>}</pre><p>You can use various values here:</p><ul><li>blur()</li><li>brightness()</li><li>contrast()</li><li>drop-shadow()</li><li>grayscale()</li><li>hue-rotate()</li><li>invert()</li><li>opacity()</li><li>sepia()</li><li>saturate()</li><li>url()</li></ul><p>Notice the parentheses after each option, because they all require a parameter.</p><p>For example:</p><pre>img {<br>  filter: opacity(0.5);<br>}</pre><p>means the image will be 50% transparent, because opacity() takes one value from 0 to 1, or a percentage.</p><p>You can also apply multiple filters at once:</p><pre>img {<br>  filter: opacity(0.5) blur(2px);<br>}</pre><p>Let’s now talk about each filter in detail.</p><h4>blur()</h4><p>Blurs an element content. You pass it a value, expressed in px or em or rem that will be used to determine the blur radius.</p><p>Example:</p><pre>img {<br>  filter: blur(4px);<br>}</pre><h4>opacity()</h4><p>opacity() takes one value from 0 to 1, or a percentage, and determines the image transparency based on it.</p><p>0, or 0%, means totally transparent. 1, or 100%, or higher, means totally visible.</p><p>Example:</p><pre>img {<br>  filter: opacity(0.5);<br>}</pre><p>CSS also has an opacity property. filter however can be hardware accelerated, depending on the implementation, so this should be the preferred method.</p><h4>drop-shadow()</h4><p>drop-shadow() shows a shadow behind the element, which follows the alpha channel. This means that if you have a transparent image, you get a shadow applied to the image shape, not the image box. If the image does not have an alpha channel, the shadow will be applied to the entire image box.</p><p>It accepts a minimum of 2 parameters, up to 5:</p><ul><li><em>offset-x</em> sets the horizontal offset. Can be negative.</li><li><em>offset-y</em> sets the vertical offset. Can be negative.</li><li><em>blur-radius</em>, optional, sets the blur radius for the shadow. It defaults to 0, no blur.</li><li><em>spread-radius</em>, optional, sets the spread radius. Expressed in px, rem or em</li><li><em>color</em>, optional, sets the color of the shadow.</li></ul><p>You can set the color without setting the spread radius or blur radius. CSS understands the value is a color and not a length value.</p><p>Example:</p><pre>img {<br>  filter: drop-shadow(10px 10px 5px orange);<br>}</pre><pre>img {<br>  filter: drop-shadow(10px 10px orange);<br>}</pre><pre>img {<br>  filter: drop-shadow(10px 10px 5px 5px #333);<br>}</pre><h4>grayscale()</h4><p>Makes the element have a gray color.</p><p>You pass one value from 0 to 1, or from 0% to 100%, where 1 and 100% mean completely gray, and 0 or 0% mean the image is not touched, and the original colors remain.</p><p>Example:</p><pre>img {<br>  filter: grayscale(50%);<br>}</pre><h4>sepia()</h4><p>Makes the element have a sepia color.</p><p>You pass one value from 0 to 1, or from 0% to 100%, where 1 and 100% mean completely sepia, and 0 or 0% mean the image is not touched, and the original colors remain.</p><p>Example:</p><pre>img {<br>  filter: sepia(50%);<br>}</pre><h4>invert()</h4><p>Invert the colors of an element. Inverting a color means looking up the opposite of a color in the HSL color wheel. Just search “color wheel” in Google if you have no idea what that means. For example, the opposite of yellow is blue, the opposite of red is cyan. Every single color has an opposite.</p><p>You pass a number, from 0 to 1 or from 0% to 100%, that determines the amount of inversion. 1 or 100% means full inversion, 0 or 0% means no inversion.</p><p>0.5 or 50% will always render a 50% gray color, because you always end up in the middle of the wheel.</p><p>Example:</p><pre>img {<br>  filter: invert(50%);<br>}</pre><h4>hue-rotate()</h4><p>The HSL color wheel is represented in degrees. Using hue-rotate() you can rotate the color using a positive or negative rotation.</p><p>The function accepts a deg value.</p><p>Example:</p><pre>img {<br>  filter: hue-rotate(90deg);<br>}</pre><h4>brightness()</h4><p>Alters the brightness of an element.</p><p>0 or 0% gives a total black element. 1 or 100% gives an unchanged image.</p><p>Values higher than 1 or 100% make the image brighter up to reaching a total white element.</p><p>Example:</p><pre>img {<br>  filter: brightness(50%);<br>}</pre><h3>contrast()</h3><p>Alters the contrast of an element.</p><p>0 or 0% gives a total gray element. 1 or 100% gives an unchanged image.</p><p>Values higher than 1 or 100% give more contrast.</p><p>Example:</p><pre>img {<br>  filter: contrast(150%);<br>}</pre><h4>saturate()</h4><p>Alters the saturation of an element.</p><p>0 or 0% gives a total grayscale element (with less saturation). 1 or 100% gives an unchanged image.</p><p>Values higher than 1 or 100% give more saturation.</p><p>Example:</p><pre>img {<br>  filter: saturate();<br>}</pre><h4>url()</h4><p>This filter allows to apply a filter defined in an SVG file. You point to the SVG file location.</p><p>Example:</p><pre>img {<br>  filter: url(filter.svg);<br>}</pre><p>SVG filters are out of the scope of this piece, but you can read more on this Smashing Magazine post: <a href="https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/">https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/</a></p><h3>TRANSFORMS</h3><p>Transforms allow you to translate, rotate, scale, and skew elements, in the 2D or 3D space. They are a very cool CSS feature, especially when combined with animations.</p><h4>2D transforms</h4><p>The transform property accepts those functions:</p><ul><li>translate() to move elements around</li><li>rotate() to rotate elements</li><li>scale() to scale elements in size</li><li>skew() to twist or slant an element</li><li>matrix() a way to perform any of the above operations using a matrix of 6 elements, a less user friendly syntax but less verbose</li></ul><p>We also have axis-specific functions:</p><ul><li>translateX() to move elements around on the X axis</li><li>translateY() to move elements around on the Y axis</li><li>scaleX() to scale elements in size on the X axis</li><li>scaleY() to scale elements in size on the Y axis</li><li>skewX() to twist or slant an element on the X axis</li><li>skewY() to twist or slant an element on the Y axis</li></ul><p>Here is an example of a transform which changes the .box element width by 2 (duplicating it) and the height by 0.5 (reducing it to half):</p><pre>.box {<br>    transform: scale(2, 0.5);<br>}</pre><p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin">transform-origin</a> lets us set the origin (the (0, 0) coordinates) for the transformation, letting us change the rotation center.</p><h4>Combining multiple transforms</h4><p>You can combine multiple transforms by separating each function with a space.</p><p>For example:</p><pre>transform: rotateY(20deg) scaleX(3) translateY(100px);</pre><h4>3D transforms</h4><p>We can go one step further and move our elements in a 3D space instead of in a 2D space. With 3D, we are adding another axis, Z, which adds depth to our visuals.</p><p>Using the perspective property you can specify how far the 3D object is from the viewer.</p><p>Example:</p><pre>.3Delement {<br>  perspective: 100px;<br>}</pre><p>perspective-origin determines the appearance of the position of the viewer, how are we looking at it in the X and Y axis.</p><p>Now we can use additional functions that control the Z axis, and that add up to the other X and Y axis transforms:</p><ul><li>translateZ()</li><li>rotateZ()</li><li>scaleZ()</li></ul><p>and the corresponding shorthands translate3d(), rotate3d() and scale3d() as shorthands for using the translateX(), translateY() and translateZ() functions and so on.</p><p>3D transforms are a bit too advanced for this handbook, but are a great topic to explore on your own.</p><h3>TRANSITIONS</h3><p>CSS Transitions are the simplest way to create an animation in CSS.</p><p>In a transition, you change the value of a property, and you tell CSS to slowly change it according to some parameters, towards a final state.</p><p>CSS Transitions are defined by these properties:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/654/1*I5jx8KegiwFggBTQA3DF9Q.png" /></figure><p>The transition property is a handy shorthand:</p><pre>.container {<br>  transition: property<br>              duration<br>              timing-function<br>              delay;<br>}</pre><h4>Example of a CSS Transition</h4><p>This code implements a CSS Transition:</p><pre>.one,<br>.three {<br>  background: rgba(142, 92, 205, .75);<br>  transition: background 1s ease-in;<br>}</pre><pre>.two,<br>.four {<br>  background: rgba(236, 252, 100, .75);<br>}</pre><pre>.circle:hover {<br>  background: rgba(142, 92, 205, .25); /* lighter */<br>}</pre><p>See the example on Glitch <a href="https://flavio-css-transitions-example.glitch.me/">https://flavio-css-transitions-example.glitch.me</a></p><p>When hovering the .one and .three elements, the purple circles, there is a transition animation that eases the change of background, while the yellow circles do not, because they do not have the transition property defined.</p><h4>Transition timing function values</h4><p>transition-timing-function allows you to specify the acceleration curve of the transition.</p><p>There are some simple values you can use:</p><ul><li>linear</li><li>ease</li><li>ease-in</li><li>ease-out</li><li>ease-in-out</li></ul><p><a href="https://flavio-css-transitions-easings.glitch.me/">This Glitch</a> shows how these work in practice.</p><p>You can create a completely custom timing function using <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/single-transition-timing-function">cubic bezier curves</a>. This is rather advanced, but basically any of those functions above are built using bezier curves. We have handy names as they are common ones.</p><h4>CSS Transitions in Browser DevTools</h4><p>The <a href="https://flaviocopes.com/browser-devtools/">Browser DevTools</a> offer a great way to visualize transitions.</p><p>This is Chrome:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/560/1*HF4j7P95-Hf7_zv55UJjbg.png" /></figure><p>This is Firefox:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/713/1*vaHwMUgcLItZdCPlltUb4g.png" /></figure><p>From those panels you can live edit the transition and experiment in the page directly without reloading your code.</p><h4>Which Properties you can Animate using CSS Animations</h4><p>A lot! They are the same you can animate using CSS Transitions, too.</p><p>Here’s the full list:</p><ul><li>background</li><li>background-color</li><li>background-position</li><li>background-size</li><li>border</li><li>border-color</li><li>border-width</li><li>border-bottom</li><li>border-bottom-color</li><li>border-bottom-left-radius</li><li>border-bottom-right-radius</li><li>border-bottom-width</li><li>border-left</li><li>border-left-color</li><li>border-left-width</li><li>border-radius</li><li>border-right</li><li>border-right-color</li><li>border-right-width</li><li>border-spacing</li><li>border-top</li><li>border-top-color</li><li>border-top-left-radius</li><li>border-top-right-radius</li><li>border-top-width</li><li>bottom</li><li>box-shadow</li><li>caret-color</li><li>clip</li><li>color</li><li>column-count</li><li>column-gap</li><li>column-rule</li><li>column-rule-color</li><li>column-rule-width</li><li>column-width</li><li>columns</li><li>content</li><li>filter</li><li>flex</li><li>flex-basis</li><li>flex-grow</li><li>flex-shrink</li><li>font</li><li>font-size</li><li>font-size-adjust</li><li>font-stretch</li><li>font-weight</li><li>grid-area</li><li>grid-auto-columns</li><li>grid-auto-flow</li><li>grid-auto-rows</li><li>grid-column-end</li><li>grid-column-gap</li><li>grid-column-start</li><li>grid-column</li><li>grid-gap</li><li>grid-row-end</li><li>grid-row-gap</li><li>grid-row-start</li><li>grid-row</li><li>grid-template-areas</li><li>grid-template-columns</li><li>grid-template-rows</li><li>grid-template</li><li>grid</li><li>height</li><li>left</li><li>letter-spacing</li><li>line-height</li><li>margin</li><li>margin-bottom</li><li>margin-left</li><li>margin-right</li><li>margin-top</li><li>max-height</li><li>max-width</li><li>min-height</li><li>min-width</li><li>opacity</li><li>order</li><li>outline</li><li>outline-color</li><li>outline-offset</li><li>outline-width</li><li>padding</li><li>padding-bottom</li><li>padding-left</li><li>padding-right</li><li>padding-top</li><li>perspective</li><li>perspective-origin</li><li>quotes</li><li>right</li><li>tab-size</li><li>text-decoration</li><li>text-decoration-color</li><li>text-indent</li><li>text-shadow</li><li>top</li><li>transform.</li><li>vertical-align</li><li>visibility</li><li>width</li><li>word-spacing</li><li>z-index</li></ul><h3>ANIMATIONS</h3><p>CSS Animations are a great way to create visual animations, not limited to a single movement like CSS Transitions, but much more articulated.</p><p>An animation is applied to an element using the animation property.</p><pre>.container {<br>  animation: spin 10s linear infinite;<br>}</pre><p>spin is the name of the animation, which we need to define separately. We also tell CSS to make the animation last 10 seconds, perform it in a linear way (no acceleration or any difference in its speed) and to repeat it infinitely.</p><p>You must <strong>define how your animation works</strong> using <strong>keyframes</strong>. Example of an animation that rotates an item:</p><pre><a href="http://twitter.com/keyframes">@keyframes</a> spin {<br>  0% {<br>    transform: rotateZ(0);<br>  }<br>  100% {<br>    transform: rotateZ(360deg);<br>  }<br>}</pre><p>Inside the @keyframes definition you can have as many intermediate waypoints as you want.</p><p>In this case we instruct CSS to make the transform property to rotate the Z axis from 0 to 360 grades, completing the full loop.</p><p>You can use any CSS transform here.</p><p>Notice how this does not dictate anything about the temporal interval the animation should take. This is defined when you use it via animation.</p><h4>A CSS Animations Example</h4><p>I want to draw four circles, all with a starting point in common, all 90 degrees distant from each other.</p><pre>&lt;div class=&quot;container&quot;&gt;<br>  &lt;div class=&quot;circle one&quot;&gt;&lt;/div&gt;<br>  &lt;div class=&quot;circle two&quot;&gt;&lt;/div&gt;<br>  &lt;div class=&quot;circle three&quot;&gt;&lt;/div&gt;<br>  &lt;div class=&quot;circle four&quot;&gt;&lt;/div&gt;<br>&lt;/div&gt;</pre><pre>body {<br>  display: grid;<br>  place-items: center;<br>  height: 100vh;<br>}</pre><pre>.circle {<br>  border-radius: 50%;<br>  left: calc(50% - 6.25em);<br>  top: calc(50% - 12.5em);<br>  transform-origin: 50% 12.5em;<br>  width: 12.5em;<br>  height: 12.5em;<br>  position: absolute;<br>  box-shadow: 0 1em 2em rgba(0, 0, 0, .5);<br>}</pre><pre>.one,<br>.three {<br>  background: rgba(142, 92, 205, .75);<br>}</pre><pre>.two,<br>.four {<br>  background: rgba(236, 252, 100, .75);<br>}</pre><pre>.one {<br>  transform: rotateZ(0);<br>}</pre><pre>.two {<br>  transform: rotateZ(90deg);<br>}</pre><pre>.three {<br>  transform: rotateZ(180deg);<br>}</pre><pre>.four {<br>  transform: rotateZ(-90deg);<br>}</pre><p>You can see them in this Glitch: <a href="https://flavio-css-circles.glitch.me/">https://flavio-css-circles.glitch.me</a></p><p>Let’s make this structure (all the circles together) rotate. To do this, we apply an animation on the container, and we define that animation as a 360 degree rotation:</p><pre><a href="http://twitter.com/keyframes">@keyframes</a> spin {<br>  0% {<br>    transform: rotateZ(0);<br>  }<br>  100% {<br>    transform: rotateZ(360deg);<br>  }<br>}</pre><pre>.container {<br>  animation: spin 10s linear infinite;<br>}</pre><p>See it on <a href="https://flavio-css-animations-tutorial.glitch.me/">https://flavio-css-animations-tutorial.glitch.me</a></p><p>You can add more keyframes to have funnier animations:</p><pre><a href="http://twitter.com/keyframes">@keyframes</a> spin {<br>  0% {<br>    transform: rotateZ(0);<br>  }<br>  25% {<br>    transform: rotateZ(30deg);<br>  }<br>  50% {<br>    transform: rotateZ(270deg);<br>  }<br>  75% {<br>    transform: rotateZ(180deg);<br>  }<br>  100% {<br>    transform: rotateZ(360deg);<br>  }<br>}</pre><p>See the example on <a href="https://flavio-css-animations-four-steps.glitch.me/">https://flavio-css-animations-four-steps.glitch.me</a></p><h4>The CSS animation properties</h4><p>CSS animations offers a lot of different parameters you can tweak:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/747/1*WP9pN5STufDtSrdhBebPbg.png" /></figure><p>The animation property is a shorthand for all these properties, in this order:</p><pre>.container {<br>  animation: name<br>             duration<br>             timing-function<br>             delay<br>             iteration-count<br>             direction<br>             fill-mode<br>             play-state;<br>}</pre><p>This is the example we used above:</p><pre>.container {<br>  animation: spin 10s linear infinite;<br>}</pre><h4>JavaScript events for CSS Animations</h4><p>Using JavaScript you can listen for the following events:</p><ul><li>animationstart</li><li>animationend</li><li>animationiteration</li></ul><p>Be careful with animationstart, because if the animation starts on page load, your JavaScript code is always executed after the CSS has been processed, so the animation is already started and you cannot intercept the event.</p><pre>const container = document.querySelector(&#39;.container&#39;)</pre><pre>container.addEventListener(&#39;animationstart&#39;, (e) =&gt; {<br>  //do something<br>}, false)</pre><pre>container.addEventListener(&#39;animationend&#39;, (e) =&gt; {<br>  //do something<br>}, false)</pre><pre>container.addEventListener(&#39;animationiteration&#39;, (e) =&gt; {<br>  //do something<br>}, false)</pre><h4>Which Properties You Can Animate using CSS Animations</h4><p>A lot! They are the same you can animate using CSS Transitions, too.</p><p>Here’s the full list:</p><ul><li>background</li><li>background-color</li><li>background-position</li><li>background-size</li><li>border</li><li>border-color</li><li>border-width</li><li>border-bottom</li><li>border-bottom-color</li><li>border-bottom-left-radius</li><li>border-bottom-right-radius</li><li>border-bottom-width</li><li>border-left</li><li>border-left-color</li><li>border-left-width</li><li>border-radius</li><li>border-right</li><li>border-right-color</li><li>border-right-width</li><li>border-spacing</li><li>border-top</li><li>border-top-color</li><li>border-top-left-radius</li><li>border-top-right-radius</li><li>border-top-width</li><li>bottom</li><li>box-shadow</li><li>caret-color</li><li>clip</li><li>color</li><li>column-count</li><li>column-gap</li><li>column-rule</li><li>column-rule-color</li><li>column-rule-width</li><li>column-width</li><li>columns</li><li>content</li><li>filter</li><li>flex</li><li>flex-basis</li><li>flex-grow</li><li>flex-shrink</li><li>font</li><li>font-size</li><li>font-size-adjust</li><li>font-stretch</li><li>font-weight</li><li>grid-area</li><li>grid-auto-columns</li><li>grid-auto-flow</li><li>grid-auto-rows</li><li>grid-column-end</li><li>grid-column-gap</li><li>grid-column-start</li><li>grid-column</li><li>grid-gap</li><li>grid-row-end</li><li>grid-row-gap</li><li>grid-row-start</li><li>grid-row</li><li>grid-template-areas</li><li>grid-template-columns</li><li>grid-template-rows</li><li>grid-template</li><li>grid</li><li>height</li><li>left</li><li>letter-spacing</li><li>line-height</li><li>margin</li><li>margin-bottom</li><li>margin-left</li><li>margin-right</li><li>margin-top</li><li>max-height</li><li>max-width</li><li>min-height</li><li>min-width</li><li>opacity</li><li>order</li><li>outline</li><li>outline-color</li><li>outline-offset</li><li>outline-width</li><li>padding</li><li>padding-bottom</li><li>padding-left</li><li>padding-right</li><li>padding-top</li><li>perspective</li><li>perspective-origin</li><li>quotes</li><li>right</li><li>tab-size</li><li>text-decoration</li><li>text-decoration-color</li><li>text-indent</li><li>text-shadow</li><li>top</li><li>transform.</li><li>vertical-align</li><li>visibility</li><li>width</li><li>word-spacing</li><li>z-index</li></ul><h3>NORMALIZING CSS</h3><p>The default browser stylesheet is the set of rules that browsers have to apply to give some minimum style to elements.</p><p>Most of the time those styles are very useful.</p><p>Since every browser has its own set, it’s common to find a common ground.</p><p>Rather than removing all defaults, like one of the <strong>CSS reset</strong> approaches does, the normalizing process removes browser inconsistencies, while keeping a basic set of rules you can rely on.</p><p>Normalize.css <a href="http://necolas.github.io/normalize.css">http://necolas.github.io/normalize.css</a> is the most commonly used solution for this problem.</p><p>You must load the normalizing CSS file before any other CSS.</p><h3>ERROR HANDLING</h3><p>CSS is resilient. When it finds an error, it does not act like JavaScript which packs up all its things and goes away altogether, terminating all the script executions after the error is found.</p><p>CSS tries very hard to do what you want.</p><p>If a line has an error, it skips it and jumps to the next line without any error.</p><p>If you forget the semicolon on one line:</p><pre>p {<br>  font-size: 20px<br>  color: black;<br>  border: 1px solid black;<br>}</pre><p>the line with the error AND the next one will <strong>not</strong> be applied, but the third rule will be successfully applied on the page. Basically, it scans all until it finds a semicolon, but when it reaches it, the rule is now font-size: 20px color: black;, which is invalid, so it skips it.</p><p>Sometimes it’s tricky to realize there is an error somewhere, and where that error is, because the browser won’t tell us.</p><p>This is why tools like <a href="http://csslint.net/">CSS Lint</a> exist.</p><h3>VENDOR PREFIXES</h3><p>Vendor prefixes are one way browsers use to give CSS developers access to newer features not yet considered stable.</p><p>Before going on, keep in mind that this approach is declining in popularity. People now favour using <strong>experimental flags</strong>, which must be enabled explicitly in the user’s browser.</p><p>Why? Because developers, instead of considering vendor prefixes as a way to preview features, sometimes ship them in production — something considered harmful by the CSS Working Group.</p><p>Mostly because once you add a flag and developers start using it in production, browsers are in a bad position if they realise something must change. With flags, you can’t ship a feature unless you can push all your visitors to enable that flag in their browser (just joking, don’t try).</p><p>That said, let’s see what vendor prefixes are.</p><p>I specifically remember them for working with CSS Transitions in the past. Instead of just using the transition property, you had to do this:</p><pre>.myClass {<br>    -webkit-transition: all 1s linear;<br>    -moz-transition: all 1s linear;<br>    -ms-transition: all 1s linear;<br>    -o-transition: all 1s linear;<br>    transition: all 1s linear;<br>}</pre><p>Now you just use</p><pre>.myClass {<br>    transition: all 1s linear;<br>}</pre><p>since the property is now well supported by all modern browsers.</p><p>The prefixes used are:</p><ul><li>-webkit- (Chrome, Safari, iOS Safari / iOS WebView, Android)</li><li>-moz- (Safari)</li><li>-ms- (Edge, Internet Explorer)</li><li>-o- (Opera, Opera Mini)</li></ul><p>Since Opera is Chromium-based and Edge will soon be too, -o- and -ms- will probably soon go out of fashion. But as we said, vendor prefixes as a whole are going out of fashion, too.</p><p>Writing prefixes is hard, mostly because of uncertainty. Do you actually need a prefix for one property? Several online resources are outdated, too, which makes it even harder to do right. Projects like <a href="https://github.com/postcss/autoprefixer">Autoprefixer</a> can automate the process in its entirety without us needing to find out if a prefix is needed any more, or the feature is now stable and the prefix should be dropped. It uses data from caniuse.com, a very good reference site for all things related to browser support.</p><p>If you use React or Vue, projects like create-react-app and Vue CLI, two common ways to start building an application, use autoprefixer out of the box, so you don&#39;t even have to worry about it.</p><h3>CSS FOR PRINT</h3><p>Even though we increasingly stare at our screens, printing is still a thing.</p><p>Even with blog posts. I remember one time back in 2009 I met a person that told me he made his personal assistant print every blog post I published (yes, I stared blankly for a little bit). Definitely unexpected.</p><p>My main use case for looking into printing usually is printing to a PDF. I might create something inside the browser, and I want to make it available as PDF.</p><p>Browsers make this very easy, with Chrome defaulting to “Save” when trying to print a document and a printer is not available, and Safari has a dedicated button in the menu bar:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*6bP3E26t6Ok96tfdihcZYA.png" /></figure><h4>Print CSS</h4><p>Some common things you might want to do when printing is to hide some parts of the document, maybe the footer, something in the header, the sidebar.</p><p>Maybe you want to use a different font for printing, which is totally legit.</p><p>If you have a large CSS for print, you’d better use a separate file for it. Browsers will only download it when printing:</p><pre>&lt;link rel=&quot;stylesheet&quot;<br>      src=&quot;print.css&quot;<br>      type=&quot;text/css&quot;<br>      media=&quot;print&quot; /&gt;</pre><h4>CSS @media print</h4><p>An alternative to the previous approach is media queries. Anything you add inside this block:</p><pre><a href="http://twitter.com/media">@media</a> print {<br>  /* ... */<br>}</pre><p>is going to be applied only to printed documents.</p><h4>Links</h4><p>HTML is great because of links. It’s called HyperText for a good reason. When printing we might lose a lot of information, depending on the content.</p><p>CSS offers a great way to solve this problem by editing the content, appending the link after the &lt;a&gt; tag text, using:</p><pre><a href="http://twitter.com/media">@media</a> print {<br>    a[href*=&#39;//&#39;]:after {<br>        content:&quot; (&quot; attr(href) &quot;) &quot;;<br>        color: $primary;<br>    }<br>}</pre><p>I target a[href*=&#39;//&#39;] to only do this for external links. I might have internal links for navigation and internal indexing purposes, which would be useless in most of my use cases. If you also want internal links to be printed, just do:</p><pre><a href="http://twitter.com/media">@media</a> print {<br>    a:after {<br>        content:&quot; (&quot; attr(href) &quot;) &quot;;<br>        color: $primary;<br>    }<br>}</pre><h4>Page margins</h4><p>You can add margins to every single page. cm or in is a good unit for paper printing.</p><pre><a href="http://twitter.com/page">@page</a> {<br>    margin-top: 2cm;<br>    margin-bottom: 2cm;<br>    margin-left: 2cm;<br>    margin-right: 2cm;<br>}</pre><p>@page can also be used to only target the first page, using @page :first, or only the left and right pages using @page :left and @page: right.</p><h4>Page breaks</h4><p>You might want to add a page break after some elements, or before them. Use page-break-after and page-break-before:</p><pre>.book-date {<br>    page-break-after: always;<br>}</pre><pre>.post-content {<br>    page-break-before: always;<br>}</pre><p>Those properties <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-after">accept a wide variety of values</a>.</p><h4>Avoid breaking images in the middle</h4><p>I experienced this with Firefox: images by default are cut in the middle, and continue on the next page. It might also happen to text.</p><p>Use</p><pre>p {<br>  page-break-inside: avoid;<br>}</pre><p>and wrap your images in a p tag. Targeting img directly didn&#39;t work in my tests.</p><p>This applies to other content as well, not just images. If you notice something is cut when you don’t want, use this property.</p><h4>Debug the printing presentation</h4><p>The Chrome DevTools offer ways to emulate the print layout:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/631/1*_E7nL0tyDIGuSAvlhD9ixQ.png" /></figure><p>Once the panel opens, change the rendering emulation to print:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/544/1*FylXX-JenFgjH-RiU0_v1A.png" /></figure><h3>WRAPPING UP</h3><p>I hope this article helped you get up to speed with CSS and get an overview of the main features you can use to style your pages and apps. I wrote it to help you get comfortable with CSS and get you quickly up to speed with using this awesome tool that lets you create stunning designs on the Web, and I hope I achieved with this goal.</p><p><a href="https://flaviocopes.com/page/css-handbook"><strong>Click here to get a PDF / ePub / Mobi version of this post to read offline</strong></a></p><p>Flavio</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b56695917d11" width="1" height="1" alt=""><hr><p><a href="https://medium.com/free-code-camp/the-css-handbook-a-handy-guide-to-css-for-developers-b56695917d11">The CSS Handbook: a handy guide to CSS for developers</a> was originally published in <a href="https://medium.com/free-code-camp">We’ve moved to freeCodeCamp.org/news</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ES5 to ESNext — here’s every feature added to JavaScript since 2015]]></title>
            <link>https://medium.com/free-code-camp/es5-to-esnext-heres-every-feature-added-to-javascript-since-2015-d0c255e13c6e?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/d0c255e13c6e</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Wed, 13 Feb 2019 16:33:04 GMT</pubDate>
            <atom:updated>2019-09-27T08:00:17.979Z</atom:updated>
            <content:encoded><![CDATA[<h3>ES5 to ESNext — here’s every feature added to JavaScript since 2015</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QZppItKE3Sqdi3kZA-TNGQ.png" /></figure><p>I wrote this article to help you move from pre-ES6 knowledge of JavaScript and get you quickly up to speed with the most recent advancements of the language.</p><p>JavaScript today is in the privileged position to be the only language that can run natively in the browser, and is highly integrated and optimized for that.</p><p>The future of JavaScript is going to be brilliant. Keeping up with the changes shouldn’t be harder than it already is, and my goal here is to give you a quick yet comprehensive overview of the new stuff available to us.</p><p><a href="https://flaviocopes.com/page/es5-to-esnext"><strong>Click here to get a PDF / ePub / Mobi version of this post to read offline</strong></a></p><h4>Table of Contents</h4><p><a href="https://medium.com/p/d0c255e13c6e#3641"><strong>Introduction to ECMAScript</strong></a></p><p><strong>ES2015</strong></p><ul><li><a href="https://medium.com/p/d0c255e13c6e#f95b">let and const</a></li><li><a href="https://medium.com/p/d0c255e13c6e#1d7c">Arrow Functions</a></li><li><a href="https://medium.com/p/d0c255e13c6e#5609">Classes</a></li><li><a href="https://medium.com/p/d0c255e13c6e#679e">Default parameters</a></li><li><a href="https://medium.com/p/d0c255e13c6e#1676">Template Literals</a></li><li><a href="https://medium.com/p/d0c255e13c6e#c962">Destructuring assignments</a></li><li><a href="https://medium.com/p/d0c255e13c6e#438e">Enhanced Object Literals</a></li><li><a href="https://medium.com/p/d0c255e13c6e#3189">For-of loop</a></li><li><a href="https://medium.com/p/d0c255e13c6e#6295">Promises</a></li><li><a href="https://medium.com/p/d0c255e13c6e#1250">Modules</a></li><li><a href="https://medium.com/p/d0c255e13c6e#b1bc">New String methods</a></li><li><a href="https://medium.com/p/d0c255e13c6e#928f">New Object methods</a></li><li><a href="https://medium.com/p/d0c255e13c6e#c80e">The spread operator</a></li><li><a href="https://medium.com/p/d0c255e13c6e#62ad">Set</a></li><li><a href="https://medium.com/p/d0c255e13c6e#c981">Map</a></li><li><a href="https://medium.com/p/d0c255e13c6e#c668">Generators</a></li></ul><p><strong>ES2016</strong></p><ul><li><a href="https://medium.com/p/d0c255e13c6e#b599">Array.prototype.includes()</a></li><li><a href="https://medium.com/p/d0c255e13c6e#2050">Exponentiation Operator</a></li></ul><p><strong>ES2017</strong></p><ul><li><a href="https://medium.com/p/d0c255e13c6e#95af">String padding</a></li><li><a href="https://medium.com/p/d0c255e13c6e#21cc">Object.values()</a></li><li><a href="https://medium.com/p/d0c255e13c6e#b188">Object.entries()</a></li><li><a href="https://medium.com/p/d0c255e13c6e#4d8c">Object.getOwnPropertyDescriptors()</a></li><li><a href="https://medium.com/p/d0c255e13c6e#9e68">Trailing commas</a></li><li><a href="https://medium.com/p/d0c255e13c6e#6bc5">Shared Memory and Atomics</a></li></ul><p><strong>ES2018</strong></p><ul><li><a href="https://medium.com/p/d0c255e13c6e#63f6">Rest/Spread Properties</a></li><li><a href="https://medium.com/p/d0c255e13c6e#301d">Asynchronous iteration</a></li><li><a href="https://medium.com/p/d0c255e13c6e#d396">Promise.prototype.finally()</a></li><li><a href="https://medium.com/p/d0c255e13c6e#3fa1">Regular Expression improvements</a></li></ul><p><a href="https://medium.com/p/d0c255e13c6e#241b"><strong>ESNext</strong></a></p><ul><li><a href="https://medium.com/p/d0c255e13c6e#24dc">Array.prototype.{flat,flatMap}</a></li><li><a href="https://medium.com/p/d0c255e13c6e#7b25">Optional catch binding</a></li><li><a href="https://medium.com/p/d0c255e13c6e#8aed">Object.fromEntries()</a></li><li><a href="https://medium.com/p/d0c255e13c6e#ae63">String.prototype.{trimStart,trimEnd}</a></li><li><a href="https://medium.com/p/d0c255e13c6e#4954">Symbol.prototype.description</a></li><li><a href="https://medium.com/p/d0c255e13c6e#b93d">JSON improvements</a></li><li><a href="https://medium.com/p/d0c255e13c6e#835a">Well-formed JSON.stringify()</a></li><li><a href="https://medium.com/p/d0c255e13c6e#b38b">Function.prototype.toString()</a></li></ul><h3>Introduction to ECMAScript</h3><p>Whenever you read about JavaScript you’ll inevitably see one of these terms: ES3, ES5, ES6, ES7, ES8, ES2015, ES2016, ES2017, ECMAScript 2017, ECMAScript 2016, ECMAScript 2015… what do they mean?</p><p>They are all referring to a <strong>standard</strong>, called ECMAScript.</p><p>ECMAScript is <strong>the standard upon which JavaScript is based</strong>, and it’s often abbreviated to <strong>ES</strong>.</p><p>Beside JavaScript, other languages implement(ed) ECMAScript, including:</p><ul><li><em>ActionScript</em> (the Flash scripting language), which is losing popularity since Flash will be officially discontinued in 2020</li><li><em>JScript</em> (the Microsoft scripting dialect), since at the time JavaScript was supported only by Netscape and the browser wars were at their peak, Microsoft had to build its own version for Internet Explorer</li></ul><p>but of course JavaScript is the <strong>most popular</strong> and widely used implementation of ES.</p><p>Why this weird name? Ecma International is a Swiss standards association who is in charge of defining international standards.</p><p>When JavaScript was created, it was presented by Netscape and Sun Microsystems to Ecma and they gave it the name ECMA-262 alias <strong>ECMAScript</strong>.</p><p><a href="https://web.archive.org/web/20070916144913/http://wp.netscape.com/newsref/pr/newsrelease67.html">This press release by Netscape and Sun Microsystems</a> (the maker of Java) might help figure out the name choice, which might include legal and branding issues by Microsoft which was in the committee, <a href="https://en.wikipedia.org/wiki/ECMAScript">according to Wikipedia</a>.</p><p>After IE9, Microsoft stopped branding its ES support in browsers as JScript and started calling it JavaScript (at least, I could not find references to it any more).</p><p>So as of 201x, the only popular language supporting the ECMAScript spec is JavaScript.</p><h4>Current ECMAScript version</h4><p>The current ECMAScript version is <strong>ES2018</strong>.</p><p>It was released in June 2018.</p><h4>What is TC39</h4><p>TC39 is the committee that evolves JavaScript.</p><p>The members of TC39 are companies involved in JavaScript and browser vendors, including Mozilla, Google, Facebook, Apple, Microsoft, Intel, PayPal, SalesForce and others.</p><p>Every standard version proposal must go through various stages, <a href="https://tc39.github.io/process-document/">which are explained here</a>.</p><h4>ES Versions</h4><p>I found it puzzling why sometimes an ES version is referenced by edition number and sometimes by year, and I am confused by the year by chance being -1 on the number, which adds to the general confusion around JS/ES 😄</p><p>Before ES2015, ECMAScript specifications were commonly called by their edition. So ES5 is the official name for the ECMAScript specification update published in 2009.</p><p>Why does this happen? During the process that led to ES2015, the name was changed from ES6 to ES2015, but since this was done late, people still referenced it as ES6, and the community has not left the edition naming behind — <em>the world is still calling ES releases by edition number</em>.</p><p>This table should clear things up a bit:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*ta8eBjBIGeJucahugjlopg.png" /></figure><p>Let’s dive into the specific features added to JavaScript since ES5. Let’s start with the ES2015 features.</p><h3>let and const</h3><p>Until ES2015, var was the only construct available for defining variables.</p><pre>var a = 0</pre><p>If you forget to add var you will be assigning a value to an undeclared variable, and the results might vary.</p><p>In modern environments, with strict mode enabled, you will get an error. In older environments (or with strict mode disabled) this will initialize the variable and assign it to the global object.</p><p>If you don’t initialize the variable when you declare it, it will have the undefined value until you assign a value to it.</p><pre>var a //typeof a === &#39;undefined&#39;</pre><p>You can redeclare the variable many times, overriding it:</p><pre>var a = 1<br>var a = 2</pre><p>You can also declare multiple variables at once in the same statement:</p><pre>var a = 1, b = 2</pre><p>The <strong>scope</strong> is the portion of code where the variable is visible.</p><p>A variable initialized with var outside of any function is assigned to the global object, has a global scope and is visible everywhere. A variable initialized with var inside a function is assigned to that function, it&#39;s local and is visible only inside it, just like a function parameter.</p><p>Any variable defined in a function with the same name as a global variable takes precedence over the global variable, shadowing it.</p><p>It’s important to understand that a block (identified by a pair of curly braces) does not define a new scope. A new scope is only created when a function is created, because var does not have block scope, but function scope.</p><p>Inside a function, any variable defined in it is visible throughout all the function code, even if the variable is declared at the end of the function it can still be referenced in the beginning, because JavaScript before executing the code actually <em>moves all variables on top</em> (something that is called <strong>hoisting</strong>). To avoid confusion, always declare variables at the beginning of a function.</p><h4>Using let</h4><p>let is a new feature introduced in ES2015 and it&#39;s essentially a block scoped version of var. Its scope is limited to the block, statement or expression where it&#39;s defined, and all the contained inner blocks.</p><p>Modern JavaScript developers might choose to only use let and completely discard the use of var.</p><blockquote><em>If </em><em>let seems an obscure term, just read </em><em>let color = &#39;red&#39; as </em>let the color be red<em> and it all makes much more sense</em></blockquote><p>Defining let outside of any function - contrary to var - does not create a global variable.</p><h4>Using const</h4><p>Variables declared with var or let can be changed later on in the program, and reassigned. Once a const is initialized, its value can never be changed again, and it can&#39;t be reassigned to a different value.</p><pre>const a = &#39;test&#39;</pre><p>We can’t assign a different literal to the a const. We can however mutate a if it&#39;s an object that provides methods that mutate its contents.</p><p>const does not provide immutability, just makes sure that the reference can&#39;t be changed.</p><p>const has block scope, same as let.</p><p>Modern JavaScript developers might choose to always use const for variables that don&#39;t need to be reassigned later in the program, because we should always use the simplest construct available to avoid making errors down the road.</p><h3>Arrow Functions</h3><p>Arrow functions, since their introduction, changed forever how JavaScript code looks (and works).</p><p>In my opinion this change was so welcome that you now rarely see the usage of the function keyword in modern codebases. Although that has still its usage.</p><p>Visually, it’s a simple and welcome change, which allows you to write functions with a shorter syntax, from:</p><pre>const myFunction = function() {<br>  //...<br>}</pre><p>to</p><pre>const myFunction = () =&gt; {<br>  //...<br>}</pre><p>If the function body contains just a single statement, you can omit the brackets and write all on a single line:</p><pre>const myFunction = () =&gt; doSomething()</pre><p>Parameters are passed in the parentheses:</p><pre>const myFunction = (param1, param2) =&gt; doSomething(param1, param2)</pre><p>If you have one (and just one) parameter, you could omit the parentheses completely:</p><pre>const myFunction = param =&gt; doSomething(param)</pre><p>Thanks to this short syntax, arrow functions <strong>encourage the use of small functions</strong>.</p><h4>Implicit return</h4><p>Arrow functions allow you to have an implicit return: values are returned without having to use the return keyword.</p><p>It works when there is a one-line statement in the function body:</p><pre>const myFunction = () =&gt; &#39;test&#39;</pre><pre>myFunction() //&#39;test&#39;</pre><p>Another example, when returning an object, remember to wrap the curly brackets in parentheses to avoid it being considered the wrapping function body brackets:</p><pre>const myFunction = () =&gt; ({ value: &#39;test&#39; })</pre><pre>myFunction() //{value: &#39;test&#39;}</pre><h4>How this works in arrow functions</h4><p>this is a concept that can be complicated to grasp, as it varies a lot depending on the context and also varies depending on the mode of JavaScript (<em>strict mode</em> or not).</p><p>It’s important to clarify this concept because arrow functions behave very differently compared to regular functions.</p><p>When defined as a method of an object, in a regular function this refers to the object, so you can do:</p><pre>const car = {<br>  model: &#39;Fiesta&#39;,<br>  manufacturer: &#39;Ford&#39;,<br>  fullName: function() {<br>    return `${this.manufacturer} ${this.model}`<br>  }<br>}</pre><p>calling car.fullName() will return &quot;Ford Fiesta&quot;.</p><p>The this scope with arrow functions is <strong>inherited</strong> from the execution context. An arrow function does not bind this at all, so its value will be looked up in the call stack, so in this code car.fullName() will not work, and will return the string &quot;undefined undefined&quot;:</p><pre>const car = {<br>  model: &#39;Fiesta&#39;,<br>  manufacturer: &#39;Ford&#39;,<br>  fullName: () =&gt; {<br>    return `${this.manufacturer} ${this.model}`<br>  }<br>}</pre><p>Due to this, arrow functions are not suited as object methods.</p><p>Arrow functions cannot be used as constructors either, when instantiating an object will raise a TypeError.</p><p>This is where regular functions should be used instead, <strong>when dynamic context is not needed</strong>.</p><p>This is also a problem when handling events. DOM Event listeners set this to be the target element, and if you rely on this in an event handler, a regular function is necessary:</p><pre>const link = document.querySelector(&#39;#link&#39;)<br>link.addEventListener(&#39;click&#39;, () =&gt; {<br>  // this === window<br>})</pre><pre>const link = document.querySelector(&#39;#link&#39;)<br>link.addEventListener(&#39;click&#39;, function() {<br>  // this === link<br>})</pre><h3>Classes</h3><p>JavaScript has quite an uncommon way to implement inheritance: prototypical inheritance. <a href="https://flaviocopes.com/javascript-prototypal-inheritance/">Prototypal inheritance</a>, while in my opinion great, is unlike most other popular programming language’s implementation of inheritance, which is class-based.</p><p>People coming from Java or Python or other languages had a hard time understanding the intricacies of prototypal inheritance, so the ECMAScript committee decided to sprinkle syntactic sugar on top of prototypical inheritance so that it resembles how class-based inheritance works in other popular implementations.</p><p>This is important: JavaScript under the hood is still the same, and you can access an object prototype in the usual way.</p><h4>A class definition</h4><p>This is how a class looks.</p><pre>class Person {<br>  constructor(name) {<br>    this.name = name<br>  }</pre><pre>  hello() {<br>    return &#39;Hello, I am &#39; + this.name + &#39;.&#39;<br>  }<br>}</pre><p>A class has an identifier, which we can use to create new objects using new ClassIdentifier().</p><p>When the object is initialized, the constructor method is called, with any parameters passed.</p><p>A class also has as many methods as it needs. In this case hello is a method and can be called on all objects derived from this class:</p><pre>const flavio = new Person(&#39;Flavio&#39;)<br>flavio.hello()</pre><h4>Class inheritance</h4><p>A class can extend another class, and objects initialized using that class inherit all the methods of both classes.</p><p>If the inherited class has a method with the same name as one of the classes higher in the hierarchy, the closest method takes precedence:</p><pre>class Programmer extends Person {<br>  hello() {<br>    return super.hello() + &#39; I am a programmer.&#39;<br>  }<br>}</pre><pre>const flavio = new Programmer(&#39;Flavio&#39;)<br>flavio.hello()</pre><p>(the above program prints “<em>Hello, I am Flavio. I am a programmer.</em>”)</p><p>Classes do not have explicit class variable declarations, but you must initialize any variable in the constructor.</p><p>Inside a class, you can reference the parent class calling super().</p><h4>Static methods</h4><p>Normally methods are defined on the instance, not on the class.</p><p>Static methods are executed on the class instead:</p><pre>class Person {<br>  static genericHello() {<br>    return &#39;Hello&#39;<br>  }<br>}</pre><pre>Person.genericHello() //Hello</pre><h4>Private methods</h4><p>JavaScript does not have a built-in way to define private or protected methods.</p><p>There are workarounds, but I won’t describe them here.</p><h4>Getters and setters</h4><p>You can add methods prefixed with get or set to create a getter and setter, which are two different pieces of code that are executed based on what you are doing: accessing the variable, or modifying its value.</p><pre>class Person {<br>  constructor(name) {<br>    this._name = name<br>  }</pre><pre>  set name(value) {<br>    this._name = value<br>  }</pre><pre>  get name() {<br>    return this._name<br>  }<br>}</pre><p>If you only have a getter, the property cannot be set, and any attempt at doing so will be ignored:</p><pre>class Person {<br>  constructor(name) {<br>    this._name = name<br>  }</pre><pre>  get name() {<br>    return this._name<br>  }<br>}</pre><p>If you only have a setter, you can change the value but not access it from the outside:</p><pre>class Person {<br>  constructor(name) {<br>    this._name = name<br>  }</pre><pre>  set name(value) {<br>    this._name = value<br>  }<br>}</pre><h3>Default parameters</h3><p>This is a doSomething function which accepts param1.</p><pre>const doSomething = (param1) =&gt; {</pre><pre>}</pre><p>We can add a default value for param1 if the function is invoked without specifying a parameter:</p><pre>const doSomething = (param1 = &#39;test&#39;) =&gt; {</pre><pre>}</pre><p>This works for more parameters as well, of course:</p><pre>const doSomething = (param1 = &#39;test&#39;, param2 = &#39;test2&#39;) =&gt; {</pre><pre>}</pre><p>What if you have an unique object with parameters values in it?</p><p>Once upon a time, if we had to pass an object of options to a function, in order to have default values of those options if one of them was not defined, you had to add a little bit of code inside the function:</p><pre>const colorize = (options) =&gt; {<br>  if (!options) {<br>    options = {}<br>  }</pre><pre>  const color = (&#39;color&#39; in options) ? options.color : &#39;yellow&#39;<br>  ...<br>}</pre><p>With destructuring you can provide default values, which simplifies the code a lot:</p><pre>const colorize = ({ color = &#39;yellow&#39; }) =&gt; {<br>  ...<br>}</pre><p>If no object is passed when calling our colorize function, similarly we can assign an empty object by default:</p><pre>const spin = ({ color = &#39;yellow&#39; } = {}) =&gt; {<br>  ...<br>}</pre><h3>Template Literals</h3><p>Template Literals allow you to work with strings in a novel way compared to ES5 and below.</p><p>The syntax at a first glance is very simple, just use backticks instead of single or double quotes:</p><pre>const a_string = `something`</pre><p>They are unique because they provide a lot of features that normal strings built with quotes do not, in particular:</p><ul><li>they offer a great syntax to define multiline strings</li><li>they provide an easy way to interpolate variables and expressions in strings</li><li>they allow you to create DSLs with template tags (DSL means domain specific language, and it’s for example used in React by Styled Components, to define CSS for a component)</li></ul><p>Let’s dive into each of these in detail.</p><h4>Multiline strings</h4><p>Pre-ES6, to create a string spanning over two lines you had to use the \ character at the end of a line:</p><pre>const string =<br>  &#39;first part \<br>second part&#39;</pre><p>This allows to create a string on 2 lines, but it’s rendered on just one line:</p><p>first part second part</p><p>To render the string on multiple lines as well, you explicitly need to add \n at the end of each line, like this:</p><pre>const string =<br>  &#39;first line\n \<br>second line&#39;</pre><p>or</p><pre>const string = &#39;first line\n&#39; + &#39;second line&#39;</pre><p>Template literals make multiline strings much simpler.</p><p>Once a template literal is opened with the backtick, you just press enter to create a new line, with no special characters, and it’s rendered as-is:</p><pre>const string = `Hey<br>this</pre><pre>string<br>is awesome!`</pre><p>Keep in mind that space is meaningful, so doing this:</p><pre>const string = `First<br>                Second`</pre><p>is going to create a string like this:</p><pre>First<br>                Second</pre><p>an easy way to fix this problem is by having an empty first line, and appending the trim() method right after the closing backtick, which will eliminate any space before the first character:</p><pre>const string = `<br>First<br>Second`.trim()</pre><h4>Interpolation</h4><p>Template literals provide an easy way to interpolate variables and expressions into strings.</p><p>You do so by using the ${...} syntax:</p><pre>const var = &#39;test&#39;<br>const string = `something ${var}` //something test</pre><p>inside the ${} you can add anything, even expressions:</p><pre>const string = `something ${1 + 2 + 3}`<br>const string2 = `something ${foo() ? &#39;x&#39; : &#39;y&#39;}`</pre><h4>Template tags</h4><p>Tagged templates is one feature that might sound less useful at first for you, but it’s actually used by lots of popular libraries around, like Styled Components or Apollo, the GraphQL client/server lib, so it’s essential to understand how it works.</p><p>In Styled Components template tags are used to define CSS strings:</p><pre>const Button = styled.button`<br>  font-size: 1.5em;<br>  background-color: black;<br>  color: white;<br>`</pre><p>In Apollo template tags are used to define a GraphQL query schema:</p><pre>const query = gql`<br>  query {<br>    ...<br>  }<br>`</pre><p>The styled.button and gql template tags highlighted in those examples are just <strong>functions</strong>:</p><pre>function gql(literals, ...expressions) {}</pre><p>this function returns a string, which can be the result of <em>any</em> kind of computation.</p><p>literals is an array containing the template literal content tokenized by the expressions interpolations.</p><p>expressions contains all the interpolations.</p><p>If we take an example above:</p><pre>const string = `something ${1 + 2 + 3}`</pre><p>literals is an array with two items. The first is something, the string until the first interpolation, and the second is an empty string, the space between the end of the first interpolation (we only have one) and the end of the string.</p><p>expressions in this case is an array with a single item, 6.</p><p>A more complex example is:</p><pre>const string = `something<br>another ${&#39;x&#39;}<br>new line ${1 + 2 + 3}<br>test`</pre><p>in this case literals is an array where the first item is:</p><pre>;`something<br>another `</pre><p>the second is:</p><pre>;`<br>new line `</pre><p>and the third is:</p><pre>;`<br>test`</pre><p>expressions in this case is an array with two items, x and 6.</p><p>The function that is passed those values can do anything with them, and this is the power of this kind feature.</p><p>The most simple example is replicating what the string interpolation does, by joining literals and expressions:</p><pre>const interpolated = interpolate`I paid ${10}€`</pre><p>and this is how interpolate works:</p><pre>function interpolate(literals, ...expressions) {<br>  let string = ``<br>  for (const [i, val] of expressions) {<br>    string += literals[i] + val<br>  }<br>  string += literals[literals.length - 1]<br>  return string<br>}</pre><h3>Destructuring assignments</h3><p>Given an object, you can extract just some values and put them into named variables:</p><pre>const person = {<br>  firstName: &#39;Tom&#39;,<br>  lastName: &#39;Cruise&#39;,<br>  actor: true,<br>  age: 54, //made up<br>}</pre><pre>const {firstName: name, age} = person</pre><p>name and age contain the desired values.</p><p>The syntax also works on arrays:</p><pre>const a = [1,2,3,4,5]<br>const [first, second] = a</pre><p>This statement creates 3 new variables by getting the items with index 0, 1, 4 from the array a:</p><pre>const [first, second, , , fifth] = a</pre><h3>Enhanced Object Literals</h3><p>In ES2015 Object Literals gained superpowers.</p><h4>Simpler syntax to include variables</h4><p>Instead of doing</p><pre>const something = &#39;y&#39;<br>const x = {<br>  something: something<br>}</pre><p>you can do</p><pre>const something = &#39;y&#39;<br>const x = {<br>  something<br>}</pre><h4>Prototype</h4><p>A prototype can be specified with</p><pre>const anObject = { y: &#39;y&#39; }<br>const x = {<br>  __proto__: anObject<br>}</pre><h4>super()</h4><pre>const anObject = { y: &#39;y&#39;, test: () =&gt; &#39;zoo&#39; }<br>const x = {<br>  __proto__: anObject,<br>  test() {<br>    return super.test() + &#39;x&#39;<br>  }<br>}<br>x.test() //zoox</pre><h4>Dynamic properties</h4><pre>const x = {<br>  [&#39;a&#39; + &#39;_&#39; + &#39;b&#39;]: &#39;z&#39;<br>}<br>x.a_b //z</pre><h3>For-of loop</h3><p>ES5 back in 2009 introduced forEach() loops. While nice, they offered no way to break, like for loops always did.</p><p>ES2015 introduced the <strong>for-of loop</strong>, which combines the conciseness of forEach with the ability to break:</p><pre>//iterate over the value<br>for (const v of [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]) {<br>  console.log(v);<br>}</pre><pre>//get the index as well, using `entries()`<br>for (const [i, v] of [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;].entries()) {<br>  console.log(index) //index<br>  console.log(value) //value<br>}</pre><p>Notice the use of const. This loop creates a new scope in every iteration, so we can safely use that instead of let.</p><p>The difference with for...in is:</p><ul><li>for...of <strong>iterates over the property values</strong></li><li>for...in <strong>iterates the property names</strong></li></ul><h3>Promises</h3><p>A promise is commonly defined as <strong>a proxy for a value that will eventually become available</strong>.</p><p>Promises are one way to deal with asynchronous code, without writing too many callbacks in your code.</p><p><strong>Async functions</strong> use the promises API as their building block, so understanding them is fundamental even if in newer code you’ll likely use async functions instead of promises.</p><h4>How promises work, in brief</h4><p>Once a promise has been called, it will start in <strong>pending state</strong>. This means that the caller function continues the execution, while it waits for the promise to do its own processing, and give the caller function some feedback.</p><p>At this point, the caller function waits for it to either return the promise in a <strong>resolved state</strong>, or in a <strong>rejected state</strong>, but as you know <a href="https://flaviocopes.com/javascript/">JavaScript</a> is asynchronous, so <em>the function continues its execution while the promise does it work</em>.</p><h4>Which JS API use promises?</h4><p>In addition to your own code and library code, promises are used by standard modern Web APIs such as:</p><ul><li>the Battery API</li><li>the <a href="https://flaviocopes.com/fetch-api/">Fetch API</a></li><li><a href="https://flaviocopes.com/service-workers/">Service Workers</a></li></ul><p>It’s unlikely that in modern JavaScript you’ll find yourself <em>not</em> using promises, so let’s start diving right into them.</p><h4>Creating a promise</h4><p>The Promise API exposes a Promise constructor, which you initialize using new Promise():</p><pre>let done = true</pre><pre>const isItDoneYet = new Promise((resolve, reject) =&gt; {<br>  if (done) {<br>    const workDone = &#39;Here is the thing I built&#39;<br>    resolve(workDone)<br>  } else {<br>    const why = &#39;Still working on something else&#39;<br>    reject(why)<br>  }<br>})</pre><p>As you can see the promise checks the done global constant, and if that&#39;s true, we return a resolved promise, otherwise a rejected promise.</p><p>Using resolve and reject we can communicate back a value, in the above case we just return a string, but it could be an object as well.</p><h4>Consuming a promise</h4><p>In the last section, we introduced how a promise is created.</p><p>Now let’s see how the promise can be <em>consumed</em> or used.</p><pre>const isItDoneYet = new Promise()<br>//...</pre><pre>const checkIfItsDone = () =&gt; {<br>  isItDoneYet<br>    .then(ok =&gt; {<br>      console.log(ok)<br>    })<br>    .catch(err =&gt; {<br>      console.error(err)<br>    })<br>}</pre><p>Running checkIfItsDone() will execute the isItDoneYet() promise and will wait for it to resolve, using the then callback, and if there is an error, it will handle it in the catch callback.</p><h4>Chaining promises</h4><p>A promise can be returned to another promise, creating a chain of promises.</p><p>A great example of chaining promises is given by the <a href="https://flaviocopes.com/fetch-api">Fetch API</a>, a layer on top of the XMLHttpRequest API, which we can use to get a resource and queue a chain of promises to execute when the resource is fetched.</p><p>The Fetch API is a promise-based mechanism, and calling fetch() is equivalent to defining our own promise using new Promise().</p><h4>Example of chaining promises</h4><pre>const status = response =&gt; {<br>  if (response.status &gt;= 200 &amp;&amp; response.status &lt; 300) {<br>    return Promise.resolve(response)<br>  }<br>  return Promise.reject(new Error(response.statusText))<br>}</pre><pre>const json = response =&gt; response.json()</pre><pre>fetch(&#39;/todos.json&#39;)<br>  .then(status)<br>  .then(json)<br>  .then(data =&gt; {<br>    console.log(&#39;Request succeeded with JSON response&#39;, data)<br>  })<br>  .catch(error =&gt; {<br>    console.log(&#39;Request failed&#39;, error)<br>  })</pre><p>In this example, we call fetch() to get a list of TODO items from the todos.json file found in the domain root, and we create a chain of promises.</p><p>Running fetch() returns a <a href="https://fetch.spec.whatwg.org/#concept-response">response</a>, which has many properties, and within those we reference:</p><ul><li>status, a numeric value representing the HTTP status code</li><li>statusText, a status message, which is OK if the request succeeded</li></ul><p>response also has a json() method, which returns a promise that will resolve with the content of the body processed and transformed into JSON.</p><p>So given those premises, this is what happens: the first promise in the chain is a function that we defined, called status(), that checks the response status and if it&#39;s not a success response (between 200 and 299), it rejects the promise.</p><p>This operation will cause the promise chain to skip all the chained promises listed and will skip directly to the catch() statement at the bottom, logging the Request failed text along with the error message.</p><p>If that succeeds instead, it calls the json() function we defined. Since the previous promise, when successful, returned the response object, we get it as an input to the second promise.</p><p>In this case, we return the data JSON processed, so the third promise receives the JSON directly:</p><pre>.then((data) =&gt; {<br>  console.log(&#39;Request succeeded with JSON response&#39;, data)<br>})</pre><p>and we log it to the console.</p><h4>Handling errors</h4><p>In the above example, in the previous section, we had a catch that was appended to the chain of promises.</p><p>When anything in the chain of promises fails and raises an error or rejects the promise, the control goes to the nearest catch() statement down the chain.</p><pre>new Promise((resolve, reject) =&gt; {<br>  throw new Error(&#39;Error&#39;)<br>}).catch(err =&gt; {<br>  console.error(err)<br>})</pre><pre>// or</pre><pre>new Promise((resolve, reject) =&gt; {<br>  reject(&#39;Error&#39;)<br>}).catch(err =&gt; {<br>  console.error(err)<br>})</pre><h4>Cascading errors</h4><p>If inside the catch() you raise an error, you can append a second catch() to handle it, and so on.</p><pre>new Promise((resolve, reject) =&gt; {<br>  throw new Error(&#39;Error&#39;)<br>})<br>  .catch(err =&gt; {<br>    throw new Error(&#39;Error&#39;)<br>  })<br>  .catch(err =&gt; {<br>    console.error(err)<br>  })</pre><h4>Orchestrating promises</h4><h4>Promise.all()</h4><p>If you need to synchronize different promises, Promise.all() helps you define a list of promises, and execute something when they are all resolved.</p><p>Example:</p><pre>const f1 = fetch(&#39;/something.json&#39;)<br>const f2 = fetch(&#39;/something2.json&#39;)</pre><pre>Promise.all([f1, f2])<br>  .then(res =&gt; {<br>    console.log(&#39;Array of results&#39;, res)<br>  })<br>  .catch(err =&gt; {<br>    console.error(err)<br>  })</pre><p>The ES2015 destructuring assignment syntax allows you to also do</p><pre>Promise.all([f1, f2]).then(([res1, res2]) =&gt; {<br>  console.log(&#39;Results&#39;, res1, res2)<br>})</pre><p>You are not limited to using fetch of course, <strong>any promise is good to go</strong>.</p><h4>Promise.race()</h4><p>Promise.race() runs as soon as one of the promises you pass to it resolves, and it runs the attached callback just once with the result of the first promise resolved.</p><p>Example:</p><pre>const promiseOne = new Promise((resolve, reject) =&gt; {<br>  setTimeout(resolve, 500, &#39;one&#39;)<br>})<br>const promiseTwo = new Promise((resolve, reject) =&gt; {<br>  setTimeout(resolve, 100, &#39;two&#39;)<br>})</pre><pre>Promise.race([promiseOne, promiseTwo]).then(result =&gt; {<br>  console.log(result) // &#39;two&#39;<br>})</pre><h3>Modules</h3><p>ES Modules is the ECMAScript standard for working with modules.</p><p>While Node.js has been using the CommonJS standard for years, the browser never had a module system, as every major decision such as a module system must be first standardized by ECMAScript and then implemented by the browser.</p><p>This standardization process completed with ES2015 and browsers started implementing this standard trying to keep everything well aligned, working all in the same way, and now ES Modules are supported in Chrome, Safari, Edge and Firefox (since version 60).</p><p>Modules are very cool, because they let you encapsulate all sorts of functionality, and expose this functionality to other JavaScript files, as libraries.</p><h4>The ES Modules Syntax</h4><p>The syntax to import a module is:</p><pre>import package from &#39;module-name&#39;</pre><p>while CommonJS uses</p><pre>const package = require(&#39;module-name&#39;)</pre><p>A module is a JavaScript file that <strong>exports</strong> one or more values (objects, functions or variables), using the export keyword. For example, this module exports a function that returns a string uppercase:</p><blockquote><em>uppercase.js</em></blockquote><pre>export default str =&gt; str.toUpperCase()</pre><p>In this example, the module defines a single, <strong>default export</strong>, so it can be an anonymous function. Otherwise it would need a name to distinguish it from other exports.</p><p>Now, <strong>any other JavaScript module</strong> can import the functionality offered by uppercase.js by importing it.</p><p>An HTML page can add a module by using a &lt;script&gt; tag with the special type=&quot;module&quot; attribute:</p><pre>&lt;script type=&quot;module&quot; src=&quot;index.js&quot;&gt;&lt;/script&gt;</pre><blockquote><em>Note: this module import behaves like a </em><em>defer script load. See </em><a href="https://flaviocopes.com/javascript-async-defer/"><em>efficiently load JavaScript with defer and async</em></a></blockquote><p>It’s important to note that any script loaded with type=&quot;module&quot; is loaded in strict mode.</p><p>In this example, the uppercase.js module defines a <strong>default export</strong>, so when we import it, we can assign it a name we prefer:</p><pre>import toUpperCase from &#39;./uppercase.js&#39;</pre><p>and we can use it:</p><pre>toUpperCase(&#39;test&#39;) //&#39;TEST&#39;</pre><p>You can also use an absolute path for the module import, to reference modules defined on another domain:</p><pre>import toUpperCase from &#39;https://flavio-es-modules-example.glitch.me/uppercase.js&#39;</pre><p>This is also valid import syntax:</p><pre>import { toUpperCase } from &#39;/uppercase.js&#39;<br>import { toUpperCase } from &#39;../uppercase.js&#39;</pre><p>This is not:</p><pre>import { toUpperCase } from &#39;uppercase.js&#39;<br>import { toUpperCase } from &#39;utils/uppercase.js&#39;</pre><p>It’s either absolute, or has a ./ or / before the name.</p><h4>Other import/export options</h4><p>We saw this example above:</p><pre>export default str =&gt; str.toUpperCase()</pre><p>This creates one default export. In a file however you can export more than one thing, by using this syntax:</p><pre>const a = 1<br>const b = 2<br>const c = 3</pre><pre>export { a, b, c }</pre><p>Another module can import all those exports using</p><pre>import * from &#39;module&#39;</pre><p>You can import just a few of those exports, using the destructuring assignment:</p><pre>import { a } from &#39;module&#39;<br>import { a, b } from &#39;module&#39;</pre><p>You can rename any import, for convenience, using as:</p><pre>import { a, b as two } from &#39;module&#39;</pre><p>You can import the default export, and any non-default export by name, like in this common React import:</p><pre>import React, { Component } from &#39;react&#39;</pre><p>You can see an ES Modules example here: <a href="https://glitch.com/edit/#!/flavio-es-modules-example?path=index.html">https://glitch.com/edit/#!/flavio-es-modules-example?path=index.html</a></p><h4>CORS</h4><p>Modules are fetched using CORS. This means that if you reference scripts from other domains, they must have a valid CORS header that allows cross-site loading (like Access-Control-Allow-Origin: *)</p><h4>What about browsers that do not support modules?</h4><p>Use a combination of type=&quot;module&quot; and nomodule:</p><pre>&lt;script type=&quot;module&quot; src=&quot;module.js&quot;&gt;&lt;/script&gt;<br>&lt;script nomodule src=&quot;fallback.js&quot;&gt;&lt;/script&gt;</pre><h4>Wrapping up modules</h4><p>ES Modules are one of the biggest features introduced in modern browsers. They are part of ES6 but the road to implement them has been long.</p><p>We can now use them! But we must also remember that having more than a few modules is going to have a performance hit on our pages, as it’s one more step that the browser must perform at runtime.</p><p>Webpack is probably going to still be a huge player even if ES Modules land in the browser, but having such a feature directly built in the language is huge for a unification of how modules work client-side and on Node.js as well.</p><h3>New String methods</h3><p>Any string value got some new instance methods:</p><ul><li>repeat()</li><li>codePointAt()</li></ul><h4>repeat()</h4><p>Repeats the strings for the specified number of times:</p><pre>&#39;Ho&#39;.repeat(3) //&#39;HoHoHo&#39;</pre><p>Returns an empty string if there is no parameter, or the parameter is 0. If the parameter is negative you&#39;ll get a RangeError.</p><h4>codePointAt()</h4><p>This method can be used to handle Unicode characters that cannot be represented by a single 16-bit Unicode unit, but need 2 instead.</p><p>Using charCodeAt() you need to retrieve the first, and the second, and combine them. Using codePointAt() you get the whole character in one call.</p><p>For example, this Chinese character “𠮷” is composed by 2 UTF-16 (Unicode) parts:</p><pre>&quot;𠮷&quot;.charCodeAt(0).toString(16) //d842<br>&quot;𠮷&quot;.charCodeAt(1).toString(16) //dfb7</pre><p>If you create a new character by combining those unicode characters:</p><pre>&quot;\ud842\udfb7&quot; //&quot;𠮷&quot;</pre><p>You can get the same result sign codePointAt():</p><pre>&quot;𠮷&quot;.codePointAt(0) //20bb7</pre><p>If you create a new character by combining those unicode characters:</p><pre>&quot;\u{20bb7}&quot; //&quot;𠮷&quot;</pre><p>More on Unicode and working with it in my <a href="https://flaviocopes.com/unicode/">Unicode guide</a>.</p><h3>New Object methods</h3><p>ES2015 introduced several static methods under the Object namespace:</p><ul><li>Object.is() determines if two values are the same value</li><li>Object.assign() used to shallow copy an object</li><li>Object.setPrototypeOf sets an object prototype</li></ul><h4>Object.is()</h4><p>This methods aims to help comparing values.</p><p>Usage:</p><pre>Object.is(a, b)</pre><p>The result is always false unless:</p><ul><li>a and b are the same exact object</li><li>a and b are equal strings (strings are equal when composed by the same characters)</li><li>a and b are equal numbers (numbers are equal when their value is equal)</li><li>a and b are both undefined, both null, both NaN, both true or both false</li></ul><p>0 and -0 are different values in JavaScript, so pay attention in this special case (convert all to +0 using the + unary operator before comparing, for example).</p><h4>Object.assign()</h4><p>Introduced in ES2015, this method copies all the <strong>enumerable own properties</strong> of one or more objects into another.</p><p>Its primary use case is to create a shallow copy of an object.</p><pre>const copied = Object.assign({}, original)</pre><p>Being a shallow copy, values are cloned, and objects references are copied (not the objects themselves), so if you edit an object property in the original object, that’s modified also in the copied object, since the referenced inner object is the same:</p><pre>const original = {<br>  name: &#39;Fiesta&#39;,<br>  car: {<br>    color: &#39;blue&#39;<br>  }<br>}<br>const copied = Object.assign({}, original)</pre><pre>original.name = &#39;Focus&#39;<br>original.car.color = &#39;yellow&#39;</pre><pre>copied.name //Fiesta<br>copied.car.color //yellow</pre><p>I mentioned “one or more”:</p><pre>const wisePerson = {<br>  isWise: true<br>}<br>const foolishPerson = {<br>  isFoolish: true<br>}<br>const wiseAndFoolishPerson = Object.assign({}, wisePerson, foolishPerson)</pre><pre>console.log(wiseAndFoolishPerson) //{ isWise: true, isFoolish: true }</pre><h4>Object.setPrototypeOf()</h4><p>Set the prototype of an object. Accepts two arguments: the object and the prototype.</p><p>Usage:</p><pre>Object.setPrototypeOf(object, prototype)</pre><p>Example:</p><pre>const animal = {<br>  isAnimal: true<br>}<br>const mammal = {<br>  isMammal: true<br>}</pre><pre>mammal.__proto__ = animal<br>mammal.isAnimal //true</pre><pre>const dog = Object.create(animal)</pre><pre>dog.isAnimal  //true<br>console.log(dog.isMammal)  //undefined</pre><pre>Object.setPrototypeOf(dog, mammal)</pre><pre>dog.isAnimal //true<br>dog.isMammal //true</pre><h3>The spread operator</h3><p>You can expand an array, an object or a string using the spread operator ...</p><p>Let’s start with an array example. Given</p><pre>const a = [1, 2, 3]</pre><p>you can create a new array using</p><pre>const b = [...a, 4, 5, 6]</pre><p>You can also create a copy of an array using</p><pre>const c = [...a]</pre><p>This works for objects as well. Clone an object with:</p><pre>const newObj = { ...oldObj }</pre><p>Using strings, the spread operator creates an array with each char in the string:</p><pre>const hey = &#39;hey&#39;<br>const arrayized = [...hey] // [&#39;h&#39;, &#39;e&#39;, &#39;y&#39;]</pre><p>This operator has some pretty useful applications. The most important one is the ability to use an array as function argument in a very simple way:</p><pre>const f = (foo, bar) =&gt; {}<br>const a = [1, 2]<br>f(...a)</pre><p>(In the past you could do this using f.apply(null, a) but that&#39;s not as nice and readable.)</p><p>The <strong>rest element</strong> is useful when working with <strong>array destructuring</strong>:</p><pre>const numbers = [1, 2, 3, 4, 5]<br>[first, second, ...others] = numbers</pre><p>and <strong>spread elements</strong>:</p><pre>const numbers = [1, 2, 3, 4, 5]<br>const sum = (a, b, c, d, e) =&gt; a + b + c + d + e<br>const sum = sum(...numbers)</pre><p>ES2018 introduces rest properties, which are the same but for objects.</p><p><strong>Rest properties</strong>:</p><pre>const { first, second, ...others } = {<br>  first: 1,<br>  second: 2,<br>  third: 3,<br>  fourth: 4,<br>  fifth: 5<br>}</pre><pre>first // 1<br>second // 2<br>others // { third: 3, fourth: 4, fifth: 5 }</pre><p><strong>Spread properties</strong> allow us to create a new object by combining the properties of the object passed after the spread operator:</p><pre>const items = { first, second, ...others }<br>items //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }</pre><h3>Set</h3><p>A Set data structure allows us to add data to a container.</p><p>A Set is a collection of objects or primitive types (strings, numbers or booleans), and you can think of it as a Map where values are used as map keys, with the map value always being a boolean true.</p><h4>Initialize a Set</h4><p>A Set is initialized by calling:</p><pre>const s = new Set()</pre><h4>Add items to a Set</h4><p>You can add items to the Set by using the add method:</p><pre>s.add(&#39;one&#39;)<br>s.add(&#39;two&#39;)</pre><p>A set only stores unique elements, so calling s.add(&#39;one&#39;) multiple times won&#39;t add new items.</p><p>You can’t add multiple elements to a set at the same time. You need to call add() multiple times.</p><h4>Check if an item is in the set</h4><p>Once an element is in the set, we can check if the set contains it:</p><pre>s.has(&#39;one&#39;) //true<br>s.has(&#39;three&#39;) //false</pre><h4>Delete an item from a Set by key</h4><p>Use the delete() method:</p><pre>s.delete(&#39;one&#39;)</pre><h4>Determine the number of items in a Set</h4><p>Use the size property:</p><pre>s.size</pre><h4>Delete all items from a Set</h4><p>Use the clear() method:</p><pre>s.clear()</pre><h4>Iterate the items in a Set</h4><p>Use the keys() or values() methods - they are equivalent:</p><pre>for (const k of s.keys()) {<br>  console.log(k)<br>}</pre><pre>for (const k of s.values()) {<br>  console.log(k)<br>}</pre><p>The entries() method returns an iterator, which you can use like this:</p><pre>const i = s.entries()<br>console.log(i.next())</pre><p>calling i.next() will return each element as a { value, done = false } object until the iterator ends, at which point done is true.</p><p>You can also use the forEach() method on the set:</p><pre>s.forEach(v =&gt; console.log(v))</pre><p>or you can just use the set in a for..of loop:</p><pre>for (const k of s) {<br>  console.log(k)<br>}</pre><h4>Initialize a Set with values</h4><p>You can initialize a Set with a set of values:</p><pre>const s = new Set([1, 2, 3, 4])</pre><h4>Convert the Set keys into an array</h4><pre>const a = [...s.keys()]</pre><pre>// or</pre><pre>const a = [...s.values()]</pre><h4>A WeakSet</h4><p>A WeakSet is a special kind of Set.</p><p>In a Set, items are never garbage collected. A WeakSet instead lets all its items be freely garbage collected. Every key of a WeakSet is an object. When the reference to this object is lost, the value can be garbage collected.</p><p>Here are the main differences:</p><ol><li>you cannot iterate over the WeakSet</li><li>you cannot clear all items from a WeakSet</li><li>you cannot check its size</li></ol><p>A WeakSet is generally used by framework-level code, and only exposes these methods:</p><ul><li>add()</li><li>has()</li><li>delete()</li></ul><h3>Map</h3><p>A Map data structure allows us to associate data to a key.</p><h4>Before ES6</h4><p>Before its introduction, people generally used objects as maps, by associating some object or value to a specific key value:</p><pre>const car = {}<br>car[&#39;color&#39;] = &#39;red&#39;<br>car.owner = &#39;Flavio&#39;<br>console.log(car[&#39;color&#39;]) //red<br>console.log(car.color) //red<br>console.log(car.owner) //Flavio<br>console.log(car[&#39;owner&#39;]) //Flavio</pre><h4>Enter Map</h4><p>ES6 introduced the Map data structure, providing us a proper tool to handle this kind of data organization.</p><p>A Map is initialized by calling:</p><pre>const m = new Map()</pre><h4>Add items to a Map</h4><p>You can add items to the map by using the set method:</p><pre>m.set(&#39;color&#39;, &#39;red&#39;)<br>m.set(&#39;age&#39;, 2)</pre><h4>Get an item from a map by key</h4><p>And you can get items out of a map by using get:</p><pre>const color = m.get(&#39;color&#39;)<br>const age = m.get(&#39;age&#39;)</pre><h4>Delete an item from a map by key</h4><p>Use the delete() method:</p><pre>m.delete(&#39;color&#39;)</pre><h4>Delete all items from a map</h4><p>Use the clear() method:</p><pre>m.clear()</pre><h4>Check if a map contains an item by key</h4><p>Use the has() method:</p><pre>const hasColor = m.has(&#39;color&#39;)</pre><h4>Find the number of items in a map</h4><p>Use the size property:</p><pre>const size = m.size</pre><h4>Initialize a map with values</h4><p>You can initialize a map with a set of values:</p><pre>const m = new Map([[&#39;color&#39;, &#39;red&#39;], [&#39;owner&#39;, &#39;Flavio&#39;], [&#39;age&#39;, 2]])</pre><h4>Map keys</h4><p>Just like any value (object, array, string, number) can be used as the value of the key-value entry of a map item, <strong>any value can be used as the key</strong>, even objects.</p><p>If you try to get a non-existing key using get() out of a map, it will return undefined.</p><h4>Weird situations you’ll almost never find in real life</h4><pre>const m = new Map()<br>m.set(NaN, &#39;test&#39;)<br>m.get(NaN) //test</pre><pre>const m = new Map()<br>m.set(+0, &#39;test&#39;)<br>m.get(-0) //test</pre><h4>Iterate over map keys</h4><p>Map offers the keys() method we can use to iterate on all the keys:</p><pre>for (const k of m.keys()) {<br>  console.log(k)<br>}</pre><h4>Iterate over map values</h4><p>The Map object offers the values() method we can use to iterate on all the values:</p><pre>for (const v of m.values()) {<br>  console.log(v)<br>}</pre><h4>Iterate over map key, value pairs</h4><p>The Map object offers the entries() method we can use to iterate on all the values:</p><pre>for (const [k, v] of m.entries()) {<br>  console.log(k, v)<br>}</pre><p>which can be simplified to</p><pre>for (const [k, v] of m) {<br>  console.log(k, v)<br>}</pre><h4>Convert the map keys into an array</h4><pre>const a = [...m.keys()]</pre><h4>Convert the map values into an array</h4><pre>const a = [...m.values()]</pre><h4>WeakMap</h4><p>A WeakMap is a special kind of map.</p><p>In a map object, items are never garbage collected. A WeakMap instead lets all its items be freely garbage collected. Every key of a WeakMap is an object. When the reference to this object is lost, the value can be garbage collected.</p><p>Here are the main differences:</p><ol><li>you cannot iterate over the keys or values (or key-values) of a WeakMap</li><li>you cannot clear all items from a WeakMap</li><li>you cannot check its size</li></ol><p>A WeakMap exposes those methods, which are equivalent to the Map ones:</p><ul><li>get(k)</li><li>set(k, v)</li><li>has(k)</li><li>delete(k)</li></ul><p>The use cases of a WeakMap are less evident than the ones of a Map, and you might never find the need for them, but essentially it can be used to build a memory-sensitive cache that is not going to interfere with garbage collection, or for careful encapsulation and information hiding.</p><h3>Generators</h3><p>Generators are a special kind of function with the ability to pause itself, and resume later, allowing other code to run in the meantime.</p><p>See the full JavaScript Generators Guide for a detailed explanation of the topic.</p><p>The code decides that it has to wait, so it lets other code “in the queue” to run, and keeps the right to resume its operations “when the thing it’s waiting for” is done.</p><p>All this is done with a single, simple keyword: yield. When a generator contains that keyword, the execution is halted.</p><p>A generator can contain many yield keywords, thus halting itself multiple times, and it&#39;s identified by the *function keyword, which is not to be confused with the pointer dereference operator used in lower level programming languages such as C, C++ or Go.</p><p>Generators enable whole new paradigms of programming in JavaScript, allowing:</p><ul><li>2-way communication while a generator is running</li><li>long-lived while loops which do not freeze your program</li></ul><p>Here is an example of a generator which explains how it all works.</p><pre>function *calculator(input) {<br>    var doubleThat = 2 * (yield (input / 2))<br>    var another = yield (doubleThat)<br>    return (input * doubleThat * another)<br>}</pre><p>We initialize it with</p><pre>const calc = calculator(10)</pre><p>Then we start the iterator on our generator:</p><pre>calc.next()</pre><p>This first iteration starts the iterator. The code returns this object:</p><pre>{<br>  done: false<br>  value: 5<br>}</pre><p>What happens is: the code runs the function, with input = 10 as it was passed in the generator constructor. It runs until it reaches the yield, and returns the content of yield: input / 2 = 5. So we got a value of 5, and the indication that the iteration is not done (the function is just paused).</p><p>In the second iteration we pass the value 7:</p><pre>calc.next(7)</pre><p>and what we got back is:</p><pre>{<br>  done: false<br>  value: 14<br>}</pre><p>7 was placed as the value of doubleThat. Important: you might read like input / 2 was the argument, but that&#39;s just the return value of the first iteration. We now skip that, and use the new input value, 7, and multiply it by 2.</p><p>We then reach the second yield, and that returns doubleThat, so the returned value is 14.</p><p>In the next, and last, iteration, we pass in 100</p><pre>calc.next(100)</pre><p>and in return we got</p><pre>{<br>  done: true<br>  value: 14000<br>}</pre><p>As the iteration is done (no more yield keywords found) and we just return (input * doubleThat * another) which amounts to 10 * 14 * 100.</p><p>Those were the features introduced in ES2015. Let’s now dive into ES2016 which is much smaller in scope.</p><h3>Array.prototype.includes()</h3><p>This feature introduces a more readable syntax for checking if an array contains an element.</p><p>With ES6 and lower, to check if an array contained an element you had to use indexOf, which checks the index in the array, and returns -1 if the element is not there.</p><p>Since -1 is evaluated as a true value, you could <strong>not</strong> do for example</p><pre>if (![1,2].indexOf(3)) {<br>  console.log(&#39;Not found&#39;)<br>}</pre><p>With this feature introduced in ES7 we can do</p><pre>if (![1,2].includes(3)) {<br>  console.log(&#39;Not found&#39;)<br>}</pre><h3>Exponentiation Operator</h3><p>The exponentiation operator ** is the equivalent of Math.pow(), but brought into the language instead of being a library function.</p><pre>Math.pow(4, 2) == 4 ** 2</pre><p>This feature is a nice addition for math intensive JS applications.</p><p>The ** operator is standardized across many languages including Python, Ruby, MATLAB, Lua, Perl and many others.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*ta8eBjBIGeJucahugjlopg.png" /></figure><p>Those were the features introduced in 2016. Let’s now dive into 2017</p><h3>String padding</h3><p>The purpose of string padding is to <strong>add characters to a string</strong>, so it <strong>reaches a specific length</strong>.</p><p>ES2017 introduces two String methods: padStart() and padEnd().</p><pre>padStart(targetLength [, padString])<br>padEnd(targetLength [, padString])</pre><p>Sample usage:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/809/1*dn9xi0ABHBNXUClPtUMPEg.png" /></figure><h3>Object.values()</h3><p>This method returns an array containing all the object own property values.</p><p>Usage:</p><pre>const person = { name: &#39;Fred&#39;, age: 87 }<br>Object.values(person) // [&#39;Fred&#39;, 87]</pre><p>Object.values() also works with arrays:</p><pre>const people = [&#39;Fred&#39;, &#39;Tony&#39;]<br>Object.values(people) // [&#39;Fred&#39;, &#39;Tony&#39;]</pre><h3>Object.entries()</h3><p>This method returns an array containing all the object own properties, as an array of [key, value] pairs.</p><p>Usage:</p><pre>const person = { name: &#39;Fred&#39;, age: 87 }<br>Object.entries(person) // [[&#39;name&#39;, &#39;Fred&#39;], [&#39;age&#39;, 87]]</pre><p>Object.entries() also works with arrays:</p><pre>const people = [&#39;Fred&#39;, &#39;Tony&#39;]<br>Object.entries(people) // [[&#39;0&#39;, &#39;Fred&#39;], [&#39;1&#39;, &#39;Tony&#39;]]</pre><h3>Object.getOwnPropertyDescriptors()</h3><p>This method returns all own (non-inherited) properties descriptors of an object.</p><p>Any object in JavaScript has a set of properties, and each of these properties has a descriptor.</p><p>A descriptor is a set of attributes of a property, and it’s composed by a subset of the following:</p><ul><li><strong>value</strong>: the value of the property</li><li><strong>writable</strong>: true the property can be changed</li><li><strong>get</strong>: a getter function for the property, called when the property is read</li><li><strong>set</strong>: a setter function for the property, called when the property is set to a value</li><li><strong>configurable</strong>: if false, the property cannot be removed nor any attribute can be changed, except its value</li><li><strong>enumerable</strong>: true if the property is enumerable</li></ul><p>Object.getOwnPropertyDescriptors(obj) accepts an object, and returns an object with the set of descriptors.</p><h4>In what way is this useful?</h4><p>ES6 gave us Object.assign(), which copies all enumerable own properties from one or more objects, and return a new object.</p><p>However there is a problem with that, because it does not correctly copies properties with non-default attributes.</p><p>If an object for example has just a setter, it’s not correctly copied to a new object, using Object.assign().</p><p>For example with</p><pre>const person1 = {<br>    set name(newName) {<br>        console.log(newName)<br>    }<br>}</pre><p>This won’t work:</p><pre>const person2 = {}<br>Object.assign(person2, person1)</pre><p>But this will work:</p><pre>const person3 = {}<br>Object.defineProperties(person3,<br>  Object.getOwnPropertyDescriptors(person1))</pre><p>As you can see with a simple console test:</p><pre>person1.name = &#39;x&#39;<br>&quot;x&quot;</pre><pre>person2.name = &#39;x&#39;</pre><pre>person3.name = &#39;x&#39;<br>&quot;x&quot;</pre><p>person2 misses the setter, it was not copied over.</p><p>The same limitation goes for shallow cloning objects with <strong>Object.create()</strong>.</p><h3>Trailing commas</h3><p>This feature allows to have trailing commas in function declarations, and in functions calls:</p><pre>const doSomething = (var1, var2,) =&gt; {<br>  //...<br>}</pre><pre>doSomething(&#39;test2&#39;, &#39;test2&#39;,)</pre><p>This change will encourage developers to stop the ugly “comma at the start of the line” habit.</p><h3>Async functions</h3><p>JavaScript evolved in a very short time from callbacks to promises (ES2015), and since ES2017 asynchronous JavaScript is even simpler with the async/await syntax.</p><p>Async functions are a combination of promises and generators, and basically, they are a higher level abstraction over promises. Let me repeat: <strong>async/await is built on promises</strong>.</p><h4>Why were async/await introduced?</h4><p>They reduce the boilerplate around promises, and the “don’t break the chain” limitation of chaining promises.</p><p>When Promises were introduced in ES2015, they were meant to solve a problem with asynchronous code, and they did, but over the 2 years that separated ES2015 and ES2017, it was clear that <em>promises could not be the final solution</em>.</p><p>Promises were introduced to solve the famous <em>callback hell</em> problem, but they introduced complexity on their own, and syntax complexity.</p><p>They were good primitives around which a better syntax could be exposed to developers, so when the time was right we got <strong>async functions</strong>.</p><p>They make the code look like it’s synchronous, but it’s asynchronous and non-blocking behind the scenes.</p><h4>How it works</h4><p>An async function returns a promise, like in this example:</p><pre>const doSomethingAsync = () =&gt; {<br>  return new Promise(resolve =&gt; {<br>    setTimeout(() =&gt; resolve(&#39;I did something&#39;), 3000)<br>  })<br>}</pre><p>When you want to <strong>call</strong> this function you prepend await, and <strong>the calling code will stop until the promise is resolved or rejected</strong>. One caveat: the client function must be defined as async. Here&#39;s an example:</p><pre>const doSomething = async () =&gt; {<br>  console.log(await doSomethingAsync())<br>}</pre><h4>A quick example</h4><p>This is a simple example of async/await used to run a function asynchronously:</p><pre>const doSomethingAsync = () =&gt; {<br>  return new Promise(resolve =&gt; {<br>    setTimeout(() =&gt; resolve(&#39;I did something&#39;), 3000)<br>  })<br>}</pre><pre>const doSomething = async () =&gt; {<br>  console.log(await doSomethingAsync())<br>}</pre><pre>console.log(&#39;Before&#39;)<br>doSomething()<br>console.log(&#39;After&#39;)</pre><p>The above code will print the following to the browser console:</p><pre>Before<br>After<br>I did something //after 3s</pre><h4>Promise all the things</h4><p>Prepending the async keyword to any function means that the function will return a promise.</p><p>Even if it’s not doing so explicitly, it will internally make it return a promise.</p><p>This is why this code is valid:</p><pre>const aFunction = async () =&gt; {<br>  return &#39;test&#39;<br>}</pre><pre>aFunction().then(alert) // This will alert &#39;test&#39;</pre><p>and it’s the same as:</p><pre>const aFunction = async () =&gt; {<br>  return Promise.resolve(&#39;test&#39;)<br>}</pre><pre>aFunction().then(alert) // This will alert &#39;test&#39;</pre><h4>The code is much simpler to read</h4><p>As you can see in the example above, our code looks very simple. Compare it to code using plain promises, with chaining and callback functions.</p><p>And this is a very simple example, the major benefits will arise when the code is much more complex.</p><p>For example here’s how you would get a JSON resource, and parse it, using promises:</p><pre>const getFirstUserData = () =&gt; {<br>  return fetch(&#39;/users.json&#39;) // get users list<br>    .then(response =&gt; response.json()) // parse JSON<br>    .then(users =&gt; users[0]) // pick first user<br>    .then(user =&gt; fetch(`/users/${user.name}`)) // get user data<br>    .then(userResponse =&gt; response.json()) // parse JSON<br>}</pre><pre>getFirstUserData()</pre><p>And here is the same functionality provided using await/async:</p><pre>const getFirstUserData = async () =&gt; {<br>  const response = await fetch(&#39;/users.json&#39;) // get users list<br>  const users = await response.json() // parse JSON<br>  const user = users[0] // pick first user<br>  const userResponse = await fetch(`/users/${user.name}`) // get user data<br>  const userData = await user.json() // parse JSON<br>  return userData<br>}</pre><pre>getFirstUserData()</pre><h4>Multiple async functions in series</h4><p>Async functions can be chained very easily, and the syntax is much more readable than with plain promises:</p><pre>const promiseToDoSomething = () =&gt; {<br>  return new Promise(resolve =&gt; {<br>    setTimeout(() =&gt; resolve(&#39;I did something&#39;), 10000)<br>  })<br>}</pre><pre>const watchOverSomeoneDoingSomething = async () =&gt; {<br>  const something = await promiseToDoSomething()<br>  return something + &#39; and I watched&#39;<br>}</pre><pre>const watchOverSomeoneWatchingSomeoneDoingSomething = async () =&gt; {<br>  const something = await watchOverSomeoneDoingSomething()<br>  return something + &#39; and I watched as well&#39;<br>}</pre><pre>watchOverSomeoneWatchingSomeoneDoingSomething().then(res =&gt; {<br>  console.log(res)<br>})</pre><p>Will print:</p><pre>I did something and I watched and I watched as well</pre><h4>Easier debugging</h4><p>Debugging promises is hard because the debugger will not step over asynchronous code.</p><p>Async/await makes this very easy because to the compiler it’s just like synchronous code.</p><h3>Shared Memory and Atomics</h3><p>WebWorkers are used to create multithreaded programs in the browser.</p><p>They offer a messaging protocol via events. Since ES2017, you can create a shared memory array between web workers and their creator, using a SharedArrayBuffer.</p><p>Since it’s unknown how much time writing to a shared memory portion takes to propagate, <strong>Atomics</strong> are a way to enforce that when reading a value, any kind of writing operation is completed.</p><p>Any more detail on this <a href="https://github.com/tc39/ecmascript_sharedmem/blob/master/TUTORIAL.md">can be found in the spec proposal</a>, which has since been implemented.</p><p>This was ES2017. Let me now introduce the ES2018 features</p><h3>Rest/Spread Properties</h3><p>ES2015 introduced the concept of a <strong>rest element</strong> when working with <strong>array destructuring</strong>:</p><pre>const numbers = [1, 2, 3, 4, 5]<br>[first, second, ...others] = numbers</pre><p>and <strong>spread elements</strong>:</p><pre>const numbers = [1, 2, 3, 4, 5]<br>const sum = (a, b, c, d, e) =&gt; a + b + c + d + e<br>const sum = sum(...numbers)</pre><p>ES2018 introduces the same but for objects.</p><p><strong>Rest properties</strong>:</p><pre>const { first, second, ...others } = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }</pre><pre>first // 1<br>second // 2<br>others // { third: 3, fourth: 4, fifth: 5 }</pre><p><strong>Spread properties</strong> allow to create a new object by combining the properties of the object passed after the spread operator:</p><pre>const items = { first, second, ...others }<br>items //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }</pre><h3>Asynchronous iteration</h3><p>The new construct for-await-of allows you to use an async iterable object as the loop iteration:</p><pre>for await (const line of readLines(filePath)) {<br>  console.log(line)<br>}</pre><p>Since this uses await, you can use it only inside async functions, like a normal await.</p><h3>Promise.prototype.finally()</h3><p>When a promise is fulfilled, successfully it calls the then() methods, one after another.</p><p>If something fails during this, the then() methods are jumped and the catch() method is executed.</p><p>finally() allow you to run some code regardless of the successful or not successful execution of the promise:</p><pre>fetch(&#39;file.json&#39;)<br>  .then(data =&gt; data.json())<br>  .catch(error =&gt; console.error(error))<br>  .finally(() =&gt; console.log(&#39;finished&#39;))</pre><h3>Regular Expression improvements</h3><p>ES2018 introduced a number of improvements regarding Regular Expressions. I recommend my tutorial on them, available at <a href="https://flaviocopes.com/javascript-regular-expressions/">https://flaviocopes.com/javascript-regular-expressions/</a>.</p><p>Here are the ES2018 specific additions.</p><h4>RegExp lookbehind assertions: match a string depending on what precedes it</h4><p>This is a lookahead: you use ?= to match a string that&#39;s followed by a specific substring:</p><pre>/Roger(?=Waters)/</pre><pre>/Roger(?= Waters)/.test(&#39;Roger is my dog&#39;) //false<br>/Roger(?= Waters)/.test(&#39;Roger is my dog and Roger Waters is a famous musician&#39;) //true</pre><p>?! performs the inverse operation, matching if a string is <strong>not</strong> followed by a specific substring:</p><pre>/Roger(?!Waters)/</pre><pre>/Roger(?! Waters)/.test(&#39;Roger is my dog&#39;) //true<br>/Roger(?! Waters)/.test(&#39;Roger Waters is a famous musician&#39;) //false</pre><p>Lookaheads use the ?= symbol. They were already available.</p><p><strong>Lookbehinds</strong>, a new feature, uses ?&lt;=.</p><pre>/(?&lt;=Roger) Waters/</pre><pre>/(?&lt;=Roger) Waters/.test(&#39;Pink Waters is my dog&#39;) //false<br>/(?&lt;=Roger) Waters/.test(&#39;Roger is my dog and Roger Waters is a famous musician&#39;) //true</pre><p>A lookbehind is negated using ?&lt;!:</p><pre>/(?&lt;!Roger) Waters/</pre><pre>/(?&lt;!Roger) Waters/.test(&#39;Pink Waters is my dog&#39;) //true<br>/(?&lt;!Roger) Waters/.test(&#39;Roger is my dog and Roger Waters is a famous musician&#39;) //false</pre><h4>Unicode property escapes \p{…} and \P{…}</h4><p>In a regular expression pattern you can use \d to match any digit, \s to match any character that&#39;s not a white space, \w to match any alphanumeric character, and so on.</p><p>This new feature extends this concept to all Unicode characters introducing \p{} and is negation \P{}.</p><p>Any unicode character has a set of properties. For example Script determines the language family, ASCII is a boolean that&#39;s true for ASCII characters, and so on. You can put this property in the graph parentheses, and the regex will check for that to be true:</p><pre>/^\p{ASCII}+$/u.test(&#39;abc&#39;)   //✅<br>/^\p{ASCII}+$/u.test(&#39;ABC@&#39;)  //✅<br>/^\p{ASCII}+$/u.test(&#39;ABC🙃&#39;) //❌</pre><p>ASCII_Hex_Digit is another boolean property, that checks if the string only contains valid hexadecimal digits:</p><pre>/^\p{ASCII_Hex_Digit}+$/u.test(&#39;0123456789ABCDEF&#39;) //✅<br>/^\p{ASCII_Hex_Digit}+$/u.test(&#39;h&#39;)                //❌</pre><p>There are many other boolean properties, which you just check by adding their name in the graph parentheses, including Uppercase, Lowercase, White_Space, Alphabetic, Emoji and more:</p><pre>/^\p{Lowercase}$/u.test(&#39;h&#39;) //✅<br>/^\p{Uppercase}$/u.test(&#39;H&#39;) //✅</pre><pre>/^\p{Emoji}+$/u.test(&#39;H&#39;)   //❌<br>/^\p{Emoji}+$/u.test(&#39;🙃🙃&#39;) //✅</pre><p>In addition to those binary properties, you can check any of the unicode character properties to match a specific value. In this example, I check if the string is written in the greek or latin alphabet:</p><pre>/^\p{Script=Greek}+$/u.test(&#39;ελληνικά&#39;) //✅<br>/^\p{Script=Latin}+$/u.test(&#39;hey&#39;) //✅</pre><p>Read more about all the properties you can use <a href="https://github.com/tc39/proposal-regexp-unicode-property-escapes">directly on the proposal</a>.</p><h4>Named capturing groups</h4><p>In ES2018 a capturing group can be assigned to a name, rather than just being assigned a slot in the result array:</p><pre>const re = /(?&lt;year&gt;\d{4})-(?&lt;month&gt;\d{2})-(?&lt;day&gt;\d{2})/<br>const result = re.exec(&#39;2015-01-02&#39;)</pre><pre>// result.groups.year === &#39;2015&#39;;<br>// result.groups.month === &#39;01&#39;;<br>// result.groups.day === &#39;02&#39;;</pre><h4>The s flag for regular expressions</h4><p>The s flag, short for <em>single line</em>, causes the . to match new line characters as well. Without it, the dot matches regular characters but not the new line:</p><pre>/hi.welcome/.test(&#39;hi\nwelcome&#39;) // false<br>/hi.welcome/s.test(&#39;hi\nwelcome&#39;) // true</pre><h3>ESNext</h3><p>What’s next? ESNext.</p><p>ESNext is a name that always indicates the next version of JavaScript.</p><p>The current ECMAScript version is <strong>ES2018</strong>. It was released in June 2018.</p><p>Historically JavaScript editions have been standardized during the summer, so we can expect <strong>ECMAScript 2019</strong> to be released in summer 2019.</p><p>So at the time of writing, ES2018 has been released, and <strong>ESNext is ES2019</strong></p><p>Proposals to the ECMAScript standard are organized in stages. Stages 1–3 are an incubator of new features, and features reaching Stage 4 are finalized as part of the new standard.</p><p>At the time of writing we have a number of features at <strong>Stage 4</strong>. I will introduce them in this section. The latest versions of the major browsers should already implement most of those.</p><p>Some of those changes are mostly for internal use, but it’s also good to know what is going on.</p><p>There are other features at Stage 3, which might be promoted to Stage 4 in the next few months, and you can check them out on this GitHub repository: <a href="https://github.com/tc39/proposals">https://github.com/tc39/proposals</a>.</p><h3>Array.prototype.{flat,flatMap}</h3><p>flat() is a new array instance method that can create a one-dimensional array from a multidimensional array.</p><p>Example:</p><pre>[&#39;Dog&#39;, [&#39;Sheep&#39;, &#39;Wolf&#39;]].flat()<br>//[ &#39;Dog&#39;, &#39;Sheep&#39;, &#39;Wolf&#39; ]</pre><p>By default it only “flats” up to one level, but you can add a parameter to set the number of levels you want to flat the array to. Set it to Infinity to have unlimited levels:</p><pre>[&#39;Dog&#39;, [&#39;Sheep&#39;, [&#39;Wolf&#39;]]].flat()<br>//[ &#39;Dog&#39;, &#39;Sheep&#39;, [ &#39;Wolf&#39; ] ]</pre><pre>[&#39;Dog&#39;, [&#39;Sheep&#39;, [&#39;Wolf&#39;]]].flat(2)<br>//[ &#39;Dog&#39;, &#39;Sheep&#39;, &#39;Wolf&#39; ]</pre><pre>[&#39;Dog&#39;, [&#39;Sheep&#39;, [&#39;Wolf&#39;]]].flat(Infinity)<br>//[ &#39;Dog&#39;, &#39;Sheep&#39;, &#39;Wolf&#39; ]</pre><p>If you are familiar with the JavaScript map() method of an array, you know that using it you can execute a function on every element of an array.</p><p>flatMap() is a new Array instance method that combines flat() with map(). It&#39;s useful when calling a function that returns an array in the map() callback, but you want your resulted array to be flat:</p><pre>[&#39;My dog&#39;, &#39;is awesome&#39;].map(words =&gt; words.split(&#39; &#39;))<br>//[ [ &#39;My&#39;, &#39;dog&#39; ], [ &#39;is&#39;, &#39;awesome&#39; ] ]</pre><pre>[&#39;My dog&#39;, &#39;is awesome&#39;].flatMap(words =&gt; words.split(&#39; &#39;))<br>//[ &#39;My&#39;, &#39;dog&#39;, &#39;is&#39;, &#39;awesome&#39; ]</pre><h3>Optional catch binding</h3><p>Sometimes we don’t need to have a parameter bound to the catch block of a try/catch.</p><p>We previously had to do:</p><pre>try {<br>  //...<br>} catch (e) {<br>  //handle error<br>}</pre><p>Even if we never had to use e to analyze the error. We can now simply omit it:</p><pre>try {<br>  //...<br>} catch {<br>  //handle error<br>}</pre><h3>Object.fromEntries()</h3><p>Objects have an entries() method, since ES2017.</p><p>It returns an array containing all the object own properties, as an array of [key, value] pairs:</p><pre>const person = { name: &#39;Fred&#39;, age: 87 }<br>Object.entries(person) // [[&#39;name&#39;, &#39;Fred&#39;], [&#39;age&#39;, 87]]</pre><p>ES2019 introduces a new Object.fromEntries() method, which can create a new object from such array of properties:</p><pre>const person = { name: &#39;Fred&#39;, age: 87 }<br>const entries = Object.entries(person)<br>const newPerson = Object.fromEntries(entries)<br><br>person !== newPerson //true </pre><h3>String.prototype.{trimStart,trimEnd}</h3><p>This feature has been part of v8/Chrome for almost a year now, and it’s going to be standardized in ES2019.</p><h4>trimStart()</h4><p>Return a new string with removed white space from the start of the original string</p><pre>&#39;Testing&#39;.trimStart() //&#39;Testing&#39;<br>&#39; Testing&#39;.trimStart() //&#39;Testing&#39;<br>&#39; Testing &#39;.trimStart() //&#39;Testing &#39;<br>&#39;Testing&#39;.trimStart() //&#39;Testing&#39;</pre><h4>trimEnd()</h4><p>Return a new string with removed white space from the end of the original string</p><pre>&#39;Testing&#39;.trimEnd() //&#39;Testing&#39;<br>&#39; Testing&#39;.trimEnd() //&#39; Testing&#39;<br>&#39; Testing &#39;.trimEnd() //&#39; Testing&#39;<br>&#39;Testing &#39;.trimEnd() //&#39;Testing&#39;</pre><h3>Symbol.prototype.description</h3><p>You can now retrieve the description of a symbol by accessing its description property instead of having to use the toString() method:</p><pre>const testSymbol = Symbol(&#39;Test&#39;)<br>testSymbol.description // &#39;Test&#39;</pre><h3>JSON improvements</h3><p>Before this change, the line separator (\u2028) and paragraph separator (\u2029) symbols were not allowed in strings parsed as JSON.</p><p>Using JSON.parse(), those characters resulted in a SyntaxError but now they parse correctly, as defined by the JSON standard.</p><h3>Well-formed JSON.stringify()</h3><p>Fixes the JSON.stringify() output when it processes surrogate UTF-8 code points (U+D800 to U+DFFF).</p><p>Before this change calling JSON.stringify() would return a malformed Unicode character (a &quot;�&quot;).</p><p>Now those surrogate code points can be safely represented as strings using JSON.stringify(), and transformed back into their original representation using JSON.parse().</p><h3>Function.prototype.toString()</h3><p>Functions have always had an instance method called toString() which return a string containing the function code.</p><p>ES2019 introduced a change to the return value to avoid stripping comments and other characters like whitespace, exactly representing the function as it was defined.</p><p>If previously we had</p><pre>function /* this is bar */ bar () {}</pre><p>The behavior was this:</p><pre>bar.toString() //&#39;function bar() {}</pre><p>now the new behavior is:</p><pre>bar.toString(); // &#39;function /* this is bar */ bar () {}&#39;</pre><p>Wrapping up, I hope this article helped you catch up on some of the latest JavaScript additions, and the new features we’ll see in 2019.</p><p><a href="https://flaviocopes.com/page/es5-to-esnext"><strong>Click here to get a PDF / ePub / Mobi version of this post to read offline</strong></a></p><p>Flavio</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d0c255e13c6e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/free-code-camp/es5-to-esnext-heres-every-feature-added-to-javascript-since-2015-d0c255e13c6e">ES5 to ESNext — here’s every feature added to JavaScript since 2015</a> was originally published in <a href="https://medium.com/free-code-camp">We’ve moved to freeCodeCamp.org/news</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The React Handbook]]></title>
            <link>https://medium.com/free-code-camp/the-react-handbook-b71c27b0a795?source=rss-fe1c14f6cde------2</link>
            <guid isPermaLink="false">https://medium.com/p/b71c27b0a795</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Flavio Copes]]></dc:creator>
            <pubDate>Tue, 08 Jan 2019 16:50:56 GMT</pubDate>
            <atom:updated>2019-02-22T10:29:35.498Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*m5aPLXkrWJs7xKsfYViJEg.png" /></figure><p>The React Handbook follows the 80/20 rule: learn in 20% of the time the 80% of a topic.</p><p>I find this approach gives a well-rounded overview. This book does not try to cover everything under the sun related to React, but it should give you the basic building blocks to get out there and become a great React developer. If you think some specific topic should be included, tell me. You can reach me on Twitter <a href="https://twitter.com/flaviocopes">@flaviocopes</a>.</p><p>I hope the contents of this book will help you achieve what you want: <strong>learn the basics of React</strong>.</p><p>You can get this ebook in PDF, ePub and Mobi format at <a href="https://reacthandbook.com">reacthandbook.com</a></p><h3>Book Index</h3><h4>Table of Contents</h4><p><a href="https://medium.com/p/b71c27b0a795#7612">An introduction to React</a><br><a href="https://medium.com/p/b71c27b0a795#a89f">How to use create-react-app</a></p><p><strong>SECTION 1</strong>: MODERN JAVASCRIPT CORE CONCEPTS YOU NEED TO KNOW TO USE REACT</p><ul><li><a href="https://medium.com/p/b71c27b0a795#1f25">Variables</a></li><li><a href="https://medium.com/p/b71c27b0a795#625c">Arrow functions</a></li><li><a href="https://medium.com/p/b71c27b0a795#5d57">Rest and spread</a></li><li><a href="https://medium.com/p/b71c27b0a795#87c9">Object and array destructuring</a></li><li><a href="https://medium.com/p/b71c27b0a795#cf4f">Template literals</a></li><li><a href="https://medium.com/p/b71c27b0a795#ef55">Classes</a></li><li><a href="https://medium.com/p/b71c27b0a795#6b71">Callbacks</a></li><li><a href="https://medium.com/p/b71c27b0a795#7899">Promises</a></li><li><a href="https://medium.com/p/b71c27b0a795#05d9">Async/Await</a></li><li><a href="https://medium.com/p/b71c27b0a795#634f">ES Modules</a></li></ul><p><strong>SECTION 2</strong>: REACT CONCEPTS</p><ul><li><a href="https://medium.com/p/b71c27b0a795#2435">Single Page Applications</a></li><li><a href="https://medium.com/p/b71c27b0a795#244f">Declarative</a></li><li><a href="https://medium.com/p/b71c27b0a795#c5a1">Immutability</a></li><li><a href="https://medium.com/p/b71c27b0a795#b75c">Purity</a></li><li><a href="https://medium.com/p/b71c27b0a795#ab50">Composition</a></li><li><a href="https://medium.com/p/b71c27b0a795#f042">The Virtual DOM</a></li><li><a href="https://medium.com/p/b71c27b0a795#0708">Unidirectional Data Flow</a></li></ul><p><strong>SECTION 3</strong>: IN-DEPTH REACT</p><ul><li><a href="https://medium.com/p/b71c27b0a795#2bb6">JSX</a></li><li><a href="https://medium.com/p/b71c27b0a795#8606">Components</a></li><li><a href="https://medium.com/p/b71c27b0a795#b70b">State</a></li><li><a href="https://medium.com/p/b71c27b0a795#2801">Props</a></li><li><a href="https://medium.com/p/b71c27b0a795#c422">Presentational vs container components</a></li><li><a href="https://medium.com/p/b71c27b0a795#831f">State vs props</a></li><li><a href="https://medium.com/p/b71c27b0a795#a8ba">PropTypes</a></li><li><a href="https://medium.com/p/b71c27b0a795#4c2f">React Fragment</a></li><li><a href="https://medium.com/p/b71c27b0a795#6f82">Events</a></li><li><a href="https://medium.com/p/b71c27b0a795#e98e">Lifecycle Events</a></li><li><a href="https://medium.com/p/b71c27b0a795#d8d9">Forms in React</a></li><li><a href="https://medium.com/p/b71c27b0a795#d9b8">Reference a DOM element</a></li><li><a href="https://medium.com/p/b71c27b0a795#d28b">Server side rendering</a></li><li><a href="https://medium.com/p/b71c27b0a795#5731">The Context API</a></li><li><a href="https://medium.com/p/b71c27b0a795#9008">Higher order components</a></li><li><a href="https://medium.com/p/b71c27b0a795#5b9b">Render Props</a></li><li><a href="https://medium.com/p/b71c27b0a795#073c">Hooks</a></li><li><a href="https://medium.com/p/b71c27b0a795#6982">Code splitting</a></li></ul><p><strong>SECTION 4</strong>: PRACTICAL EXAMPLES</p><ul><li><a href="https://medium.com/p/b71c27b0a795#61f3">Build a simple counter</a></li><li><a href="https://medium.com/p/b71c27b0a795#1f54">Fetch and display GitHub users information via API</a></li></ul><p><strong>SECTION 5</strong>: STYLING</p><ul><li><a href="https://medium.com/p/b71c27b0a795#c186">CSS in React</a></li><li><a href="https://medium.com/p/b71c27b0a795#a030">SASS in React</a></li><li><a href="https://medium.com/p/b71c27b0a795#9e55">Styled Components</a></li></ul><p><strong>SECTION 6</strong>: TOOLING</p><ul><li><a href="https://medium.com/p/b71c27b0a795#eb1b">Babel</a></li><li><a href="https://medium.com/p/b71c27b0a795#f0be">Webpack</a></li></ul><p><strong>SECTION 7</strong>: TESTING</p><ul><li><a href="https://medium.com/p/b71c27b0a795#d8af">Jest</a></li><li><a href="https://medium.com/p/b71c27b0a795#54c3">Testing React components</a></li></ul><p><strong>SECTION 8</strong>: THE REACT ECOSYSTEM</p><ul><li><a href="https://medium.com/p/b71c27b0a795#37c5">React Router</a></li><li><a href="https://medium.com/p/b71c27b0a795#8e78">Redux</a></li><li><a href="https://medium.com/p/b71c27b0a795#839c">Next.js</a></li><li><a href="https://medium.com/p/b71c27b0a795#555e">Gatsby</a></li></ul><p><a href="https://medium.com/p/b71c27b0a795#aff3">Wrapping up</a></p><h3>An introduction to the React view library</h3><h4>What is React?</h4><p>React is a JavaScript library that aims to simplify development of visual interfaces.</p><p>Developed at Facebook and released to the world in 2013, it drives some of the most widely used apps, powering Facebook and Instagram among countless other applications.</p><p>Its primary goal is to make it easy to reason about an interface and its state at any point in time, by dividing the UI into a collection of components.</p><h4>Why is React so popular?</h4><p>React has taken the frontend web development world by storm. Why?</p><h4>Less complex than the other alternatives</h4><p>At the time when React was announced, Ember.js and Angular 1.x were the predominant choices as a framework. Both these imposed so many conventions on the code that porting an existing app was not convenient at all.</p><p>React made a choice to be very easy to integrate into an existing project, because that’s how they had to do it at Facebook in order to introduce it to the existing codebase. Also, those 2 frameworks brought too much to the table, while React only chose to implement the View layer instead of the full MVC stack.</p><h4>Perfect timing</h4><p>At the time, Angular 2.x was announced by Google, along with the backwards incompatibility and major changes it was going to bring. Moving from Angular 1 to 2 was like moving to a different framework, so this, along with execution speed improvements that React promised, made it something developers were eager to try.</p><h4>Backed by Facebook</h4><p>Being backed by Facebook is, of course, going to benefit a project if it turns out to be successful.</p><p>Facebook currently has a strong interest in React, sees the value of it being Open Source, and this is a huge plus for all the developers using it in their own projects.</p><h4>Is React simple to learn?</h4><p>Even though I said that React is simpler than alternative frameworks, diving into React is still complicated, but mostly because of the corollary technologies that can be integrated with React, like Redux and GraphQL.</p><p>React in itself has a very small API, and you basically need to understand 4 concepts to get started:</p><ul><li>Components</li><li>JSX</li><li>State</li><li>Props</li></ul><p>All these (and more) are explained in this handbook.</p><h4>How to install React on your development computer</h4><p>How do you install React?</p><p>React is a library, so saying <em>install</em> might sound a bit weird. Maybe <em>setup</em> is a better word, but you get the concept.</p><p>There are various ways to setup React so that it can be used on your app or site.</p><h4>Load React directly in the web page</h4><p>The simplest one is to add the React JavaScript file into the page directly. This is best when your React app will interact with the elements present on a single page, and not actually controls the whole navigation aspect.</p><p>In this case, you add 2 script tags to the end of the body tag:</p><pre>&lt;html&gt;<br>  ...<br>  &lt;body&gt;<br>    ...<br>    &lt;script<br>      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.development.js&quot;<br>      crossorigin<br>    &gt;&lt;/script&gt;<br>    &lt;script<br>      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js&quot;<br>      crossorigin<br>    &gt;&lt;/script&gt;<br>  &lt;/body&gt;<br>&lt;/html&gt;</pre><blockquote><em>Please change the version number to the latest version of React available.</em></blockquote><p>Here we loaded both React and React DOM. Why 2 libraries? Because React is 100% independent from the browser and can be used outside it (for example on Mobile devices with React Native). Hence the need for React DOM, to add the wrappers for the browser.</p><p>After those tags you can load your JavaScript files that use React, or even inline JavaScript in a script tag:</p><pre>&lt;script src=&quot;app.js&quot;&gt;&lt;/script&gt;</pre><pre>&lt;!-- or --&gt;</pre><pre>&lt;script&gt;<br>  //my app<br>&lt;/script&gt;</pre><p>To use JSX you need an extra step: load Babel</p><pre>&lt;script src=&quot;https://unpkg.com/babel-standalone@6/babel.min.js&quot;&gt;&lt;/script&gt;</pre><p>and load your scripts with the special text/babel MIME type:</p><pre>&lt;script src=&quot;app.js&quot; type=&quot;text/babel&quot;&gt;&lt;/script&gt;</pre><p>Now you can add JSX in your app.js file:</p><pre>const Button = () =&gt; {<br>  return &lt;button&gt;Click me!&lt;/button&gt;<br>}</pre><pre>ReactDOM.render(&lt;Button /&gt;, document.getElementById(&#39;root&#39;))</pre><p>Check out this simple Glitch example: <a href="https://glitch.com/edit/#!/react-example-inline-jsx?path=script.js">https://glitch.com/edit/#!/react-example-inline-jsx?path=script.js</a></p><p>Starting in this way with script tags is good for building prototypes and enables a quick start without having to set up a complex workflow.</p><h3>How to use create-react-app</h3><p>create-react-app is a project aimed at getting you up to speed with React in no time, and any React app that needs to outgrow a single page will find that create-react-app meets that need.</p><p>You start by using <a href="https://flaviocopes.com/npx/">npx</a>, which is an easy way to download and execute Node.js commands without installing them. npx comes with npm (since version 5.2) and if you don&#39;t have npm installed already, do it now from <a href="https://nodejs.org/">https://nodejs.org</a> (npm is installed with Node).</p><p>If you are unsure which version of npm you have, run npm -v to check if you need to update.</p><blockquote><em>Tip: check out my </em><a href="https://flaviocopes.com/macos-terminal/"><em>OSX terminal tutorial</em></a><em> if you’re unfamiliar with using the terminal, applies to Linux as well — I’m sorry but I don’t have a tutorial for Windows at the moment, but Google is your friend.</em></blockquote><p>When you run npx create-react-app &lt;app-name&gt;, npx is going to <em>download</em> the most recent create-react-app release, run it, and then remove it from your system. This is great because you will never have an outdated version on your system, and every time you run it, you&#39;re getting the latest and greatest code available.</p><p>Let’s start then:</p><pre>npx create-react-app todolist</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*82mA8PcAuHQJvWWwlhCg7Q.png" /></figure><p>This is when it finished running:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bRy6qcDVTIgbFWJS6C7bNg.png" /></figure><p>create-react-app created a files structure in the folder you told (todolist in this case), and initialized a <a href="https://flaviocopes.com/git/">Git</a> repository.</p><p>It also added a few commands in the package.json file, so you can immediately start the app by going into the folder and run npm start.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/758/1*1TOBsLzp3-xqdCCAfWY2LQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/741/1*bXvL5nWlWtoqUM3hiTa6fQ.png" /></figure><p>In addition to npm start, create-react-app added a few other commands:</p><ul><li>npm run build: to build the React application files in the build folder, ready to be deployed to a server</li><li>npm test: to run the testing suite using <a href="https://flaviocopes.com/jest/">Jest</a></li><li>npm eject: to eject from create-react-app</li></ul><p>Ejecting is the act of deciding that create-react-app has done enough for you, but you want to do more than what it allows.</p><p>Since create-react-app is a set of common denominator conventions and a limited amount of options, it&#39;s probable that at some point your needs will demand something unique that outgrows the capabilities of create-react-app.</p><p>When you eject, you lose the ability of automatic updates but you gain more flexibility in the <a href="https://flaviocopes.com/babel/">Babel</a> and <a href="https://flaviocopes.com/webpack/">Webpack</a> configuration.</p><p>When you eject the action is irreversible. You will get 2 new folders in your application directory, config and scripts. Those contain the configurations - and now you can start editing them.</p><blockquote><em>If you already have a React app installed using an older version of React, first check the version by adding </em><em>console.log(React.version) in your app, then you can update by running </em><em>yarn add react@16.7, and yarn will prompt you to update (choose the latest version available). Repeat for </em><em>yarn add react-dom@16.7 (change &quot;16.7&quot; with whatever is the newest version of React at the moment)</em></blockquote><h4>CodeSandbox</h4><p>An easy way to have the create-react-app structure, without installing it, is to go to <a href="https://codesandbox.io/s">https://codesandbox.io/s</a> and choose &quot;React&quot;.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QHQH0Jz-XdmJ7XgM2p5FUQ.png" /></figure><p>CodeSandbox is a great way to start a React project without having to install it locally.</p><h4>Codepen</h4><p>Another great solution is <a href="https://codepen.io/">Codepen</a>.</p><p>You can use this Codepen starter project which already comes pre-configured with React, with support for Hooks: <a href="https://codepen.io/flaviocopes/pen/VqeaxB">https://codepen.io/flaviocopes/pen/VqeaxB</a></p><p>Codepen “pens” are great for quick projects with one JavaScript file, while “projects” are great for projects with multiple files, like the ones we’ll use the most when building React apps.</p><p>One thing to note is that in Codepen, due to how it works internally, you don’t use the regular ES Modules import syntax, but rather to import for example useState, you use</p><pre>const { useState } = React</pre><p>and not</p><pre>import { useState } from &#39;react&#39;</pre><h3>SECTION 1: MODERN JAVASCRIPT CORE CONCEPTS YOU NEED TO KNOW TO USE REACT</h3><h4>Find out if you have to learn something before diving into learning React</h4><p>If you are willing to learn React, you first need to have a few things under your belt. There are some prerequisite technologies you have to be familiar with, in particular related to some of the more recent JavaScript features you’ll use over and over in React.</p><p>Sometimes people think one particular feature is provided by React, but instead it’s just modern JavaScript syntax.</p><p>There is no point in being an expert in those topics right away, but the more you dive into React, the more you’ll need to master those.</p><p>I will mention a list of things to get you up to speed quickly.</p><h3>Variables</h3><p>A variable is a literal assigned to an identifier, so you can reference and use it later in the program.</p><p>Variables in JavaScript do not have any type attached. Once you assign a specific literal type to a variable, you can later reassign the variable to host any other type, without type errors or any issue.</p><p>This is why JavaScript is sometimes referred to as “untyped”.</p><p>A variable must be declared before you can use it. There are 3 ways to do this, using var, let or const, and those 3 ways differ in how you can interact with the variable later on.</p><h4>Using var</h4><p>Until ES2015, var was the only construct available for defining variables.</p><pre>var a = 0</pre><p>If you forget to add var you will be assigning a value to an undeclared variable, and the results might vary.</p><p>In modern environments, with strict mode enabled, you will get an error. In older environments (or with strict mode disabled) this will simply initialize the variable and assign it to the global object.</p><p>If you don’t initialize the variable when you declare it, it will have the undefined value until you assign a value to it.</p><pre>var a //typeof a === &#39;undefined&#39;</pre><p>You can redeclare the variable many times, overriding it:</p><pre>var a = 1<br>var a = 2</pre><p>You can also declare multiple variables at once in the same statement:</p><pre>var a = 1, b = 2</pre><p>The <strong>scope</strong> is the portion of code where the variable is visible.</p><p>A variable initialized with var outside of any function is assigned to the global object, has a global scope and is visible everywhere. A variable initialized with var inside a function is assigned to that function, it&#39;s local and is visible only inside it, just like a function parameter.</p><p>Any variable defined in a function with the same name as a global variable takes precedence over the global variable, shadowing it.</p><p>It’s important to understand that a block (identified by a pair of curly braces) does not define a new scope. A new scope is only created when a function is created, because var does not have block scope, but function scope.</p><p>Inside a function, any variable defined in it is visible throughout all the function code, even if the variable is declared at the end of the function it can still be referenced in the beginning, because JavaScript before executing the code actually <em>moves all variables on top</em> (something that is called <strong>hoisting</strong>). To avoid confusion, always declare variables at the beginning of a function.</p><h4>Using let</h4><p>let is a new feature introduced in ES2015 and it&#39;s essentially a block scoped version of var. Its scope is limited to the block, statement or expression where it&#39;s defined, and all the contained inner blocks.</p><p>Modern JavaScript developers might choose to only use let and completely discard the use of var.</p><blockquote><em>If </em><em>let seems an obscure term, just read </em><em>let color = &#39;red&#39; as </em>let the color be red<em> and it all makes much more sense</em></blockquote><p>Defining let outside of any function - contrary to var - does not create a global variable.</p><h4>Using const</h4><p>Variables declared with var or let can be changed later on in the program, and reassigned. Once a const is initialized, its value can never be changed again, and it can&#39;t be reassigned to a different value.</p><pre>const a = &#39;test&#39;</pre><p>We can’t assign a different literal to the a const. We can however mutate a if it&#39;s an object that provides methods that mutate its contents.</p><p>const does not provide immutability, just makes sure that the reference can&#39;t be changed.</p><p>const has block scope, same as let.</p><p>Modern JavaScript developers might choose to always use const for variables that don&#39;t need to be reassigned later in the program.</p><p>Why? Because we should always use the simplest construct available to avoid making errors down the road.</p><h3>Arrow functions</h3><p>Arrow functions were introduced in ES6 / ECMAScript 2015, and since their introduction they changed forever how JavaScript code looks (and works).</p><p>In my opinion this change was so welcoming that you now rarely see the usage of the function keyword in modern codebases.</p><p>Visually, it’s a simple and welcome change, which allows you to write functions with a shorter syntax, from:</p><pre>const myFunction = function() {<br>  //...<br>}</pre><p>to</p><pre>const myFunction = () =&gt; {<br>  //...<br>}</pre><p>If the function body contains just a single statement, you can omit the brackets and write all on a single line:</p><pre>const myFunction = () =&gt; doSomething()</pre><p>Parameters are passed in the parentheses:</p><pre>const myFunction = (param1, param2) =&gt; doSomething(param1, param2)</pre><p>If you have one (and just one) parameter, you could omit the parentheses completely:</p><pre>const myFunction = param =&gt; doSomething(param)</pre><p>Thanks to this short syntax, arrow functions <strong>encourage the use of small functions</strong>.</p><h3>Implicit return</h3><p>Arrow functions allow you to have an implicit return: values are returned without having to use the return keyword.</p><p>It works when there is a one-line statement in the function body:</p><pre>const myFunction = () =&gt; &#39;test&#39;</pre><pre>myFunction() //&#39;test&#39;</pre><p>Another example, when returning an object, remember to wrap the curly brackets in parentheses to avoid it being considered the wrapping function body brackets:</p><pre>const myFunction = () =&gt; ({ value: &#39;test&#39; })</pre><pre>myFunction() //{value: &#39;test&#39;}</pre><h3>How this works in arrow functions</h3><p>this is a concept that can be complicated to grasp, as it varies a lot depending on the context and also varies depending on the mode of JavaScript (<em>strict mode</em> or not).</p><p>It’s important to clarify this concept because arrow functions behave very differently compared to regular functions.</p><p>When defined as a method of an object, in a regular function this refers to the object, so you can do:</p><pre>const car = {<br>  model: &#39;Fiesta&#39;,<br>  manufacturer: &#39;Ford&#39;,<br>  fullName: function() {<br>    return `${this.manufacturer} ${this.model}`<br>  }<br>}</pre><p>calling car.fullName() will return &quot;Ford Fiesta&quot;.</p><p>The this scope with arrow functions is <strong>inherited</strong> from the execution context. An arrow function does not bind this at all, so its value will be looked up in the call stack, so in this code car.fullName() will not work, and will return the string &quot;undefined undefined&quot;:</p><pre>const car = {<br>  model: &#39;Fiesta&#39;,<br>  manufacturer: &#39;Ford&#39;,<br>  fullName: () =&gt; {<br>    return `${this.manufacturer} ${this.model}`<br>  }<br>}</pre><p>Due to this, arrow functions are not suited as object methods.</p><p>Arrow functions cannot be used as constructors either, when instantiating an object will raise a TypeError.</p><p>This is where regular functions should be used instead, <strong>when dynamic context is not needed</strong>.</p><p>This is also a problem when handling events. DOM Event listeners set this to be the target element, and if you rely on this in an event handler, a regular function is necessary:</p><pre>const link = document.querySelector(&#39;#link&#39;)<br>link.addEventListener(&#39;click&#39;, () =&gt; {<br>  // this === window<br>})</pre><pre>const link = document.querySelector(&#39;#link&#39;)<br>link.addEventListener(&#39;click&#39;, function() {<br>  // this === link<br>})</pre><h3>Rest and spread</h3><p>You can expand an array, an object or a string using the spread operator ....</p><p>Let’s start with an array example. Given</p><pre>const a = [1, 2, 3]</pre><p>you can create a new array using</p><pre>const b = [...a, 4, 5, 6]</pre><p>You can also create a copy of an array using</p><pre>const c = [...a]</pre><p>This works for objects as well. Clone an object with:</p><pre>const newObj = { ...oldObj }</pre><p>Using strings, the spread operator creates an array with each char in the string:</p><pre>const hey = &#39;hey&#39;<br>const arrayized = [...hey] // [&#39;h&#39;, &#39;e&#39;, &#39;y&#39;]</pre><p>This operator has some pretty useful applications. The most important one is the ability to use an array as function argument in a very simple way:</p><pre>const f = (foo, bar) =&gt; {}<br>const a = [1, 2]<br>f(...a)</pre><p>(in the past you could do this using f.apply(null, a) but that&#39;s not as nice and readable)</p><p>The <strong>rest element</strong> is useful when working with <strong>array destructuring</strong>:</p><pre>const numbers = [1, 2, 3, 4, 5]<br>[first, second, ...others] = numbers</pre><p>and <strong>spread elements</strong>:</p><pre>const numbers = [1, 2, 3, 4, 5]<br>const sum = (a, b, c, d, e) =&gt; a + b + c + d + e<br>const sumOfNumbers = sum(...numbers)</pre><p>ES2018 introduces rest properties, which are the same but for objects.</p><p><strong>Rest properties</strong>:</p><pre>const { first, second, ...others } = {<br>  first: 1,<br>  second: 2,<br>  third: 3,<br>  fourth: 4,<br>  fifth: 5<br>}</pre><pre>first // 1<br>second // 2<br>others // { third: 3, fourth: 4, fifth: 5 }</pre><p><strong>Spread properties</strong> allow to create a new object by combining the properties of the object passed after the spread operator:</p><pre>const items = { first, second, ...others }<br>items //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }</pre><h3>Object and array destructuring</h3><p>Given an object, using the destructuring syntax you can extract just some values and put them into named variables:</p><pre>const person = {<br>  firstName: &#39;Tom&#39;,<br>  lastName: &#39;Cruise&#39;,<br>  actor: true,<br>  age: 54 //made up<br>}</pre><pre>const { firstName: name, age } = person //name: Tom, age: 54</pre><p>name and age contain the desired values.</p><p>The syntax also works on arrays:</p><pre>const a = [1, 2, 3, 4, 5]<br>const [first, second] = a</pre><p>This statement creates 3 new variables by getting the items with index 0, 1, 4 from the array a:</p><pre>const [first, second, , , fifth] = a</pre><h3>Template literals</h3><p>Template Literals are a new ES2015 / ES6 feature that allows you to work with strings in a novel way compared to ES5 and below.</p><p>The syntax at a first glance is very simple, just use backticks instead of single or double quotes:</p><pre>const a_string = `something`</pre><p>They are unique because they provide a lot of features that normal strings built with quotes do not, in particular:</p><ul><li>they offer a great syntax to define multiline strings</li><li>they provide an easy way to interpolate variables and expressions in strings</li><li>they allow you to create DSLs with template tags (DSL means domain specific language, and it’s for example used in React by Styled Components, to define CSS for a component)</li></ul><p>Let’s dive into each of these in detail.</p><h4>Multiline strings</h4><p>Pre-ES6, to create a string spanning over two lines you had to use the \ character at the end of a line:</p><pre>const string =<br>  &#39;first part \<br>second part&#39;</pre><p>This allows to create a string on 2 lines, but it’s rendered on just one line:</p><p>first part second part</p><p>To render the string on multiple lines as well, you explicitly need to add \n at the end of each line, like this:</p><pre>const string =<br>  &#39;first line\n \<br>second line&#39;</pre><p>or</p><pre>const string = &#39;first line\n&#39; + &#39;second line&#39;</pre><p>Template literals make multiline strings much simpler.</p><p>Once a template literal is opened with the backtick, you just press enter to create a new line, with no special characters, and it’s rendered as-is:</p><pre>const string = `Hey<br>this</pre><pre>string<br>is awesome!`</pre><p>Keep in mind that space is meaningful, so doing this:</p><pre>const string = `First<br>                Second`</pre><p>is going to create a string like this:</p><pre>First<br>                Second</pre><p>an easy way to fix this problem is by having an empty first line, and appending the trim() method right after the closing backtick, which will eliminate any space before the first character:</p><pre>const string = `<br>First<br>Second`.trim()</pre><h4>Interpolation</h4><p>Template literals provide an easy way to interpolate variables and expressions into strings.</p><p>You do so by using the ${...} syntax:</p><pre>const myVariable = &#39;test&#39;<br>const string = `something ${myVariable}` //something test</pre><p>inside the ${} you can add anything, even expressions:</p><pre>const string = `something ${1 + 2 + 3}`<br>const string2 = `something ${foo() ? &#39;x&#39; : &#39;y&#39;}`</pre><h3>Classes</h3><p>In 2015 the ECMAScript 6 (ES6) standard introduced classes.</p><p>JavaScript has a quite uncommon way to implement inheritance: prototypical inheritance. <a href="https://flaviocopes.com/javascript-prototypal-inheritance/">Prototypal inheritance</a>, while in my opinion great, is unlike most other popular programming language’s implementation of inheritance, which is class-based.</p><p>People coming from Java or Python or other languages had a hard time understanding the intricacies of prototypal inheritance, so the ECMAScript committee decided to sprinkle syntactic sugar on top of prototypical inheritance so that it resembles how class-based inheritance works in other popular implementations.</p><p>This is important: JavaScript under the hood is still the same, and you can access an object prototype in the usual way.</p><h4>A class definition</h4><p>This is how a class looks.</p><pre>class Person {<br>  constructor(name) {<br>    this.name = name<br>  }</pre><pre>  hello() {<br>    return &#39;Hello, I am &#39; + this.name + &#39;.&#39;<br>  }<br>}</pre><p>A class has an identifier, which we can use to create new objects using new ClassIdentifier().</p><p>When the object is initialized, the constructor method is called, with any parameters passed.</p><p>A class also has as many methods as it needs. In this case hello is a method and can be called on all objects derived from this class:</p><pre>const flavio = new Person(&#39;Flavio&#39;)<br>flavio.hello()</pre><h4>Class inheritance</h4><p>A class can extend another class, and objects initialized using that class inherit all the methods of both classes.</p><p>If the inherited class has a method with the same name as one of the classes higher in the hierarchy, the closest method takes precedence:</p><pre>class Programmer extends Person {<br>  hello() {<br>    return super.hello() + &#39; I am a programmer.&#39;<br>  }<br>}</pre><pre>const flavio = new Programmer(&#39;Flavio&#39;)<br>flavio.hello()</pre><p>(the above program prints “<em>Hello, I am Flavio. I am a programmer.</em>”)</p><p>Classes do not have explicit class variable declarations, but you must initialize any variable in the constructor.</p><p>Inside a class, you can reference the parent class calling super().</p><h4>Static methods</h4><p>Normally methods are defined on the instance, not on the class.</p><p>Static methods are executed on the class instead:</p><pre>class Person {<br>  static genericHello() {<br>    return &#39;Hello&#39;<br>  }<br>}</pre><pre>Person.genericHello() //Hello</pre><h4>Private methods</h4><p>JavaScript does not have a built-in way to define private or protected methods.</p><p>There are workarounds, but I won’t describe them here.</p><h4>Getters and setters</h4><p>You can add methods prefixed with get or set to create a getter and setter, which are two different pieces of code that are executed based on what you are doing: accessing the variable, or modifying its value.</p><pre>class Person {<br>  constructor(name) {<br>    this.name = name<br>  }</pre><pre>  set name(value) {<br>    this.name = value<br>  }</pre><pre>  get name() {<br>    return this.name<br>  }<br>}</pre><p>If you only have a getter, the property cannot be set, and any attempt at doing so will be ignored:</p><pre>class Person {<br>  constructor(name) {<br>    this.name = name<br>  }</pre><pre>  get name() {<br>    return this.name<br>  }<br>}</pre><p>If you only have a setter, you can change the value but not access it from the outside:</p><pre>class Person {<br>  constructor(name) {<br>    this.name = name<br>  }</pre><pre>  set name(value) {<br>    this.name = value<br>  }<br>}</pre><h3>Callbacks</h3><p>Computers are asynchronous by design.</p><p>Asynchronous means that things can happen independently of the main program flow.</p><p>In the current consumer computers, every program runs for a specific time slot, and then it stops its execution to let another program continue its execution. This thing runs in a cycle so fast that’s impossible to notice, and we think our computers run many programs simultaneously, but this is an illusion (except on multiprocessor machines).</p><p>Programs internally use <em>interrupts</em>, a signal that’s emitted to the processor to gain the attention of the system.</p><p>I won’t go into the internals of this, but just keep in mind that it’s normal for programs to be asynchronous, and halt their execution until they need attention, and the computer can execute other things in the meantime. When a program is waiting for a response from the network, it cannot halt the processor until the request finishes.</p><p>Normally, programming languages are synchronous, and some provide a way to manage asynchronicity, in the language or through libraries. C, Java, C#, PHP, Go, Ruby, Swift, Python, they are all synchronous by default. Some of them handle async by using threads, spawning a new process.</p><p>JavaScript is <strong>synchronous</strong> by default and is single threaded. This means that code cannot create new threads and run in parallel.</p><p>Lines of code are executed in series, one after another, for example:</p><pre>const a = 1<br>const b = 2<br>const c = a * b<br>console.log(c)<br>doSomething()</pre><p>But JavaScript was born inside the browser, its main job, in the beginning, was to respond to user actions, like onClick, onMouseOver, onChange, onSubmit and so on. How could it do this with a synchronous programming model?</p><p>The answer was in its environment. The <strong>browser</strong> provides a way to do it by providing a set of APIs that can handle this kind of functionality.</p><p>More recently, Node.js introduced a non-blocking I/O environment to extend this concept to file access, network calls and so on.</p><p>You can’t know when a user is going to click a button, so what you do is, you <strong>define an event handler for the click event</strong>. This event handler accepts a function, which will be called when the event is triggered:</p><pre>document.getElementById(&#39;button&#39;).addEventListener(&#39;click&#39;, () =&gt; {<br>  //item clicked<br>})</pre><p>This is the so-called <strong>callback</strong>.</p><p>A callback is a simple function that’s passed as a value to another function, and will only be executed when the event happens. We can do this because JavaScript has first-class functions, which can be assigned to variables and passed around to other functions (called <strong>higher-order functions</strong>)</p><p>It’s common to wrap all your client code in a load event listener on the windowobject, which runs the callback function only when the page is ready:</p><pre>window.addEventListener(&#39;load&#39;, () =&gt; {<br>  //window loaded<br>  //do what you want<br>})</pre><p>Callbacks are used everywhere, not just in DOM events.</p><p>One common example is by using timers:</p><pre>setTimeout(() =&gt; {<br>  // runs after 2 seconds<br>}, 2000)</pre><p>XHR requests also accept a callback, in this example by assigning a function to a property that will be called when a particular event occurs (in this case, the state of the request changes):</p><pre>const xhr = new XMLHttpRequest()<br>xhr.onreadystatechange = () =&gt; {<br>  if (xhr.readyState === 4) {<br>    xhr.status === 200 ? console.log(xhr.responseText) : console.error(&#39;error&#39;)<br>  }<br>}<br>xhr.open(&#39;GET&#39;, &#39;https://yoursite.com&#39;)<br>xhr.send()</pre><h4>Handling errors in callbacks</h4><p>How do you handle errors with callbacks? One very common strategy is to use what Node.js adopted: the first parameter in any callback function is the error object: <strong>error-first callbacks</strong></p><p>If there is no error, the object is null. If there is an error, it contains some description of the error and other information.</p><pre>fs.readFile(&#39;/file.json&#39;, (err, data) =&gt; {<br>  if (err !== null) {<br>    //handle error<br>    console.log(err)<br>    return<br>  }</pre><pre>  //no errors, process data<br>  console.log(data)<br>})</pre><h4>The problem with callbacks</h4><p>Callbacks are great for simple cases!</p><p>However every callback adds a level of nesting, and when you have lots of callbacks, the code starts to be complicated very quickly:</p><pre>window.addEventListener(&#39;load&#39;, () =&gt; {<br>  document.getElementById(&#39;button&#39;).addEventListener(&#39;click&#39;, () =&gt; {<br>    setTimeout(() =&gt; {<br>      items.forEach(item =&gt; {<br>        //your code here<br>      })<br>    }, 2000)<br>  })<br>})</pre><p>This is just a simple 4-levels code, but I’ve seen much more levels of nesting and it’s not fun.</p><p>How do we solve this?</p><h3>ALTERNATIVES TO CALLBACKS</h3><p>Starting with ES6, JavaScript introduced several features that help us with asynchronous code that do not involve using callbacks:</p><ul><li>Promises (ES6)</li><li>Async/Await (ES8)</li></ul><h3>Promises</h3><p>Promises are one way to deal with asynchronous code, without writing too many callbacks in your code.</p><p>Although they’ve been around for years, they were standardized and introduced in ES2015, and now they have been superseded in ES2017 by async functions.</p><p><strong>Async functions</strong> use the promises API as their building block, so understanding them is fundamental even if in newer code you’ll likely use async functions instead of promises.</p><h4>How promises work, in brief</h4><p>Once a promise has been called, it will start in <strong>pending state</strong>. This means that the caller function continues the execution, while it waits for the promise to do its own processing, and give the caller function some feedback.</p><p>At this point, the caller function waits for it to either return the promise in a <strong>resolved state</strong>, or in a <strong>rejected state</strong>, but as you know JavaScript is asynchronous, so <em>the function continues its execution while the promise does it work</em>.</p><h4>Which JS API use promises?</h4><p>In addition to your own code and library code, promises are used by standard modern Web APIs like <a href="https://flaviocopes.com/fetch-api/">Fetch</a> or <a href="https://flaviocopes.com/service-workers/">Service Workers</a>.</p><p>It’s unlikely that in modern JavaScript you’ll find yourself <em>not</em> using promises, so let’s start diving right into them.</p><h4>Creating a promise</h4><p>The Promise API exposes a Promise constructor, which you initialize using new Promise():</p><pre>let done = true</pre><pre>const isItDoneYet = new Promise((resolve, reject) =&gt; {<br>  if (done) {<br>    const workDone = &#39;Here is the thing I built&#39;<br>    resolve(workDone)<br>  } else {<br>    const why = &#39;Still working on something else&#39;<br>    reject(why)<br>  }<br>})</pre><p>As you can see the promise checks the done global constant, and if that&#39;s true, we return a resolved promise, otherwise a rejected promise.</p><p>Using resolve and reject we can communicate back a value, in the above case we just return a string, but it could be an object as well.</p><h4>Consuming a promise</h4><p>In the last section, we introduced how a promise is created.</p><p>Now let’s see how the promise can be <em>consumed</em> or used.</p><pre>const isItDoneYet = new Promise()<br>//...</pre><pre>const checkIfItsDone = () =&gt; {<br>  isItDoneYet<br>    .then(ok =&gt; {<br>      console.log(ok)<br>    })<br>    .catch(err =&gt; {<br>      console.error(err)<br>    })<br>}</pre><p>Running checkIfItsDone() will execute the isItDoneYet() promise and will wait for it to resolve, using the then callback, and if there is an error, it will handle it in the catch callback.</p><h4>Chaining promises</h4><p>A promise can be returned to another promise, creating a chain of promises.</p><p>A great example of chaining promises is given by the <a href="https://flaviocopes.com/fetch-api/">Fetch API</a>, a layer on top of the XMLHttpRequest API, which we can use to get a resource and queue a chain of promises to execute when the resource is fetched.</p><p>The Fetch API is a promise-based mechanism, and calling fetch() is equivalent to defining our own promise using new Promise().</p><p>Example:</p><pre>const status = response =&gt; {<br>  if (response.status &gt;= 200 &amp;&amp; response.status &lt; 300) {<br>    return Promise.resolve(response)<br>  }<br>  return Promise.reject(new Error(response.statusText))<br>}</pre><pre>const json = response =&gt; response.json()</pre><pre>fetch(&#39;/todos.json&#39;)<br>  .then(status)<br>  .then(json)<br>  .then(data =&gt; {<br>    console.log(&#39;Request succeeded with JSON response&#39;, data)<br>  })<br>  .catch(error =&gt; {<br>    console.log(&#39;Request failed&#39;, error)<br>  })</pre><p>In this example, we call fetch() to get a list of TODO items from the todos.json file found in the domain root, and we create a chain of promises.</p><p>Running fetch() returns a <a href="https://fetch.spec.whatwg.org/#concept-response">response</a>, which has many properties, and within those we reference:</p><ul><li>status, a numeric value representing the HTTP status code</li><li>statusText, a status message, which is OK if the request succeeded</li></ul><p>response also has a json() method, which returns a promise that will resolve with the content of the body processed and transformed into JSON.</p><p>So given those premises, this is what happens: the first promise in the chain is a function that we defined, called status(), that checks the response status and if it&#39;s not a success response (between 200 and 299), it rejects the promise.</p><p>This operation will cause the promise chain to skip all the chained promises listed and will skip directly to the catch() statement at the bottom, logging the Request failed text along with the error message.</p><p>If that succeeds instead, it calls the json() function we defined. Since the previous promise, when successful, returned the response object, we get it as an input to the second promise.</p><p>In this case, we return the data JSON processed, so the third promise receives the JSON directly:</p><pre>.then((data) =&gt; {<br>  console.log(&#39;Request succeeded with JSON response&#39;, data)<br>})</pre><p>and we simply log it to the console.</p><h4>Handling errors</h4><p>In the above example, in the previous section, we had a catch that was appended to the chain of promises.</p><p>When anything in the chain of promises fails and raises an error or rejects the promise, the control goes to the nearest catch() statement down the chain.</p><pre>new Promise((resolve, reject) =&gt; {<br>  throw new Error(&#39;Error&#39;)<br>}).catch(err =&gt; {<br>  console.error(err)<br>})</pre><pre>// or</pre><pre>new Promise((resolve, reject) =&gt; {<br>  reject(&#39;Error&#39;)<br>}).catch(err =&gt; {<br>  console.error(err)<br>})</pre><h4>Cascading errors</h4><p>If inside the catch() you raise an error, you can append a second catch() to handle it, and so on.</p><pre>new Promise((resolve, reject) =&gt; {<br>  throw new Error(&#39;Error&#39;)<br>})<br>  .catch(err =&gt; {<br>    throw new Error(&#39;Error&#39;)<br>  })<br>  .catch(err =&gt; {<br>    console.error(err)<br>  })</pre><h4>Orchestrating promises with Promise.all()</h4><p>If you need to synchronize different promises, Promise.all() helps you define a list of promises, and execute something when they are all resolved.</p><p>Example:</p><pre>const f1 = fetch(&#39;/something.json&#39;)<br>const f2 = fetch(&#39;/something2.json&#39;)</pre><pre>Promise.all([f1, f2])<br>  .then(res =&gt; {<br>    console.log(&#39;Array of results&#39;, res)<br>  })<br>  .catch(err =&gt; {<br>    console.error(err)<br>  })</pre><p>The ES2015 destructuring assignment syntax allows you to also do</p><pre>Promise.all([f1, f2]).then(([res1, res2]) =&gt; {<br>  console.log(&#39;Results&#39;, res1, res2)<br>})</pre><p>You are not limited to using fetch of course, <strong>any promise is good to go</strong>.</p><h4>Orchestrating promises with Promise.race()</h4><p>Promise.race() runs as soon as one of the promises you pass to it resolves, and it runs the attached callback just once with the result of the first promise resolved.</p><p>Example:</p><pre>const promiseOne = new Promise((resolve, reject) =&gt; {<br>  setTimeout(resolve, 500, &#39;one&#39;)<br>})<br>const promiseTwo = new Promise((resolve, reject) =&gt; {<br>  setTimeout(resolve, 100, &#39;two&#39;)<br>})</pre><pre>Promise.race([promiseOne, promiseTwo]).then(result =&gt; {<br>  console.log(result) // &#39;two&#39;<br>})</pre><h3>Async/Await</h3><p>JavaScript evolved in a very short time from callbacks to promises (ES2015), and since ES2017 asynchronous JavaScript is even simpler with the async/await syntax.</p><p>Async functions are a combination of promises and generators, and basically, they are a higher level abstraction over promises. Let me repeat: <strong>async/await is built on promises</strong>.</p><h4>Why were async/await introduced?</h4><p>They reduce the boilerplate around promises, and the “don’t break the chain” limitation of chaining promises.</p><p>When Promises were introduced in ES2015, they were meant to solve a problem with asynchronous code, and they did, but over the 2 years that separated ES2015 and ES2017, it was clear that <em>promises could not be the final solution</em>.</p><p>Promises were introduced to solve the famous <em>callback hell</em> problem, but they introduced complexity on their own, and syntax complexity.</p><p>They were good primitives around which a better syntax could be exposed to developers, so when the time was right we got <strong>async functions</strong>.</p><p>They make the code look like it’s synchronous, but it’s asynchronous and non-blocking behind the scenes.</p><h4>How it works</h4><p>An async function returns a promise, like in this example:</p><pre>const doSomethingAsync = () =&gt; {<br>  return new Promise(resolve =&gt; {<br>    setTimeout(() =&gt; resolve(&#39;I did something&#39;), 3000)<br>  })<br>}</pre><p>When you want to <strong>call</strong> this function you prepend await, and <strong>the calling code will stop until the promise is resolved or rejected</strong>. One caveat: the client function must be defined as async. Here&#39;s an example:</p><pre>const doSomething = async () =&gt; {<br>  console.log(await doSomethingAsync())<br>}</pre><h4>A quick example</h4><p>This is a simple example of async/await used to run a function asynchronously:</p><pre>const doSomethingAsync = () =&gt; {<br>  return new Promise(resolve =&gt; {<br>    setTimeout(() =&gt; resolve(&#39;I did something&#39;), 3000)<br>  })<br>}</pre><pre>const doSomething = async () =&gt; {<br>  console.log(await doSomethingAsync())<br>}</pre><pre>console.log(&#39;Before&#39;)<br>doSomething()<br>console.log(&#39;After&#39;)</pre><p>The above code will print the following to the browser console:</p><pre>Before<br>After<br>I did something //after 3s</pre><h4>Promise all the things</h4><p>Prepending the async keyword to any function means that the function will return a promise.</p><p>Even if it’s not doing so explicitly, it will internally make it return a promise.</p><p>This is why this code is valid:</p><pre>const aFunction = async () =&gt; {<br>  return &#39;test&#39;<br>}</pre><pre>aFunction().then(alert) // This will alert &#39;test&#39;</pre><p>and it’s the same as:</p><pre>const aFunction = async () =&gt; {<br>  return Promise.resolve(&#39;test&#39;)<br>}</pre><pre>aFunction().then(alert) // This will alert &#39;test&#39;</pre><h4>The code is much simpler to read</h4><p>As you can see in the example above, our code looks very simple. Compare it to code using plain promises, with chaining and callback functions.</p><p>And this is a very simple example, the major benefits will arise when the code is much more complex.</p><p>For example here’s how you would get a JSON resource, and parse it, using promises:</p><pre>const getFirstUserData = () =&gt; {<br>  return fetch(&#39;/users.json&#39;) // get users list<br>    .then(response =&gt; response.json()) // parse JSON<br>    .then(users =&gt; users[0]) // pick first user<br>    .then(user =&gt; fetch(`/users/${user.name}`)) // get user data<br>    .then(userResponse =&gt; userResponse.json()) // parse JSON<br>}</pre><pre>getFirstUserData()</pre><p>And here is the same functionality provided using await/async:</p><pre>const getFirstUserData = async () =&gt; {<br>  const response = await fetch(&#39;/users.json&#39;) // get users list<br>  const users = await response.json() // parse JSON<br>  const user = users[0] // pick first user<br>  const userResponse = await fetch(`/users/${user.name}`) // get user data<br>  const userData = await userResponse.json() // parse JSON<br>  return userData<br>}</pre><pre>getFirstUserData()</pre><h4>Multiple async functions in series</h4><p>Async functions can be chained very easily, and the syntax is much more readable than with plain promises:</p><pre>const promiseToDoSomething = () =&gt; {<br>  return new Promise(resolve =&gt; {<br>    setTimeout(() =&gt; resolve(&#39;I did something&#39;), 10000)<br>  })<br>}</pre><pre>const watchOverSomeoneDoingSomething = async () =&gt; {<br>  const something = await promiseToDoSomething()<br>  return something + &#39; and I watched&#39;<br>}</pre><pre>const watchOverSomeoneWatchingSomeoneDoingSomething = async () =&gt; {<br>  const something = await watchOverSomeoneDoingSomething()<br>  return something + &#39; and I watched as well&#39;<br>}</pre><pre>watchOverSomeoneWatchingSomeoneDoingSomething().then(res =&gt; {<br>  console.log(res)<br>})</pre><p>Will print:</p><pre>I did something and I watched and I watched as well</pre><h4>Easier debugging</h4><p>Debugging promises is hard because the debugger will not step over asynchronous code.</p><p>Async/await makes this very easy because to the compiler it’s just like synchronous code.</p><h3>ES Modules</h3><p>ES Modules is the ECMAScript standard for working with modules.</p><p>While Node.js has been using the CommonJS standard for years, the browser never had a module system, as every major decision such as a module system must be first standardized by ECMAScript and then implemented by the browser.</p><p>This standardization process completed with ES6 and browsers started implementing this standard trying to keep everything well aligned, working all in the same way, and now ES Modules are supported in Chrome, Safari, Edge and Firefox (since version 60).</p><p>Modules are very cool, because they let you encapsulate all sorts of functionality, and expose this functionality to other JavaScript files, as libraries.</p><h4>The ES Modules Syntax</h4><p>The syntax to import a module is:</p><pre>import package from &#39;module-name&#39;</pre><p>while CommonJS uses</p><pre>const package = require(&#39;module-name&#39;)</pre><p>A module is a JavaScript file that <strong>exports</strong> one or more values (objects, functions or variables), using the export keyword. For example, this module exports a function that returns a string uppercase:</p><blockquote><em>uppercase.js</em></blockquote><pre>export default str =&gt; str.toUpperCase()</pre><p>In this example, the module defines a single, <strong>default export</strong>, so it can be an anonymous function. Otherwise it would need a name to distinguish it from other exports.</p><p>Now, <strong>any other JavaScript module</strong> can import the functionality offered by uppercase.js by importing it.</p><p>An HTML page can add a module by using a &lt;script&gt; tag with the special type=&quot;module&quot; attribute:</p><pre>&lt;script type=&quot;module&quot; src=&quot;index.js&quot;&gt;&lt;/script&gt;</pre><blockquote><em>Note: this module import behaves like a </em><em>defer script load. See </em><a href="https://flaviocopes.com/javascript-async-defer/"><em>efficiently load JavaScript with defer and async</em></a></blockquote><p>It’s important to note that any script loaded with type=&quot;module&quot; is loaded in <a href="https://flaviocopes.com/javascript-strict-mode/">strict mode</a>.</p><p>In this example, the uppercase.js module defines a <strong>default export</strong>, so when we import it, we can assign it a name we prefer:</p><pre>import toUpperCase from &#39;./uppercase.js&#39;</pre><p>and we can use it:</p><pre>toUpperCase(&#39;test&#39;) //&#39;TEST&#39;</pre><p>You can also use an absolute path for the module import, to reference modules defined on another domain:</p><pre>import toUpperCase from &#39;https://flavio-es-modules-example.glitch.me/uppercase.js&#39;</pre><p>This is also valid import syntax:</p><pre>import { foo } from &#39;/uppercase.js&#39;<br>import { foo } from &#39;../uppercase.js&#39;</pre><p>This is not:</p><pre>import { foo } from &#39;uppercase.js&#39;<br>import { foo } from &#39;utils/uppercase.js&#39;</pre><p>It’s either absolute, or has a ./ or / before the name.</p><h3>Other import/export options</h3><p>We saw this example above:</p><pre>export default str =&gt; str.toUpperCase()</pre><p>This creates one default export. In a file however you can export more than one thing, by using this syntax:</p><pre>const a = 1<br>const b = 2<br>const c = 3</pre><pre>export { a, b, c }</pre><p>Another module can import all those exports using</p><pre>import * from &#39;module&#39;</pre><p>You can import just a few of those exports, using the destructuring assignment:</p><pre>import { a } from &#39;module&#39;<br>import { a, b } from &#39;module&#39;</pre><p>You can rename any import, for convenience, using as:</p><pre>import { a, b as two } from &#39;module&#39;</pre><p>You can import the default export, and any non-default export by name, like in this common React import:</p><pre>import React, { Component } from &#39;react&#39;</pre><p>You can see an ES Modules example here: <a href="https://glitch.com/edit/#!/flavio-es-modules-example?path=index.html">https://glitch.com/edit/#!/flavio-es-modules-example?path=index.html</a></p><h4>CORS</h4><p>Modules are fetched using <a href="https://flaviocopes.com/cors/">CORS</a>. This means that if you reference scripts from other domains, they must have a valid CORS header that allows cross-site loading (like Access-Control-Allow-Origin: *)</p><h4>What about browsers that do not support modules?</h4><p>Use a combination of type=&quot;module&quot; and nomodule:</p><pre>&lt;script type=&quot;module&quot; src=&quot;module.js&quot;&gt;&lt;/script&gt;<br>&lt;script nomodule src=&quot;fallback.js&quot;&gt;&lt;/script&gt;</pre><p>ES Modules are one of the biggest features introduced in modern browsers. They are part of ES6 but the road to implement them has been long.</p><p>We can now use them! But we must also remember that having more than a few modules is going to have a performance hit on our pages, as it’s one more step that the browser must perform at runtime.</p><p>Webpack is probably going to still be a huge player even if ES Modules land in the browser, but having such a feature directly built in the language is huge for a unification of how modules work client-side and on Node.js as well.</p><h3>SECTION 2: REACT CONCEPTS</h3><h3>Single Page Applications</h3><p>React Applications are also called Single Page Applications. What does this mean?</p><p>In the past, when browsers were much less capable than today, and JavaScript performance was poor, every page was coming from a server. Every time you clicked something, a new request was made to the server and the browser subsequently loaded the new page.</p><p>Only very innovative products worked differently, and experimented with new approaches.</p><p>Today, popularized by modern frontend JavaScript frameworks like React, an app is usually built as a single page application: you only load the application code (HTML, <a href="https://flaviocopes.com/css/">CSS</a>, <a href="https://flaviocopes.com/javascript/">JavaScript</a>) once, and when you interact with the application, what generally happens is that JavaScript intercepts the browser events and instead of making a new request to the server that then returns a new document, the client requests some JSON or performs an action on the server but the page that the user sees is never completely wiped away, and behaves more like a desktop application.</p><p>Single page applications are built in JavaScript (or at least compiled to JavaScript) and work in the browser.</p><p>The technology is always the same, but the philosophy and some key components of how the application works are different.</p><h4>Examples of Single Page Applications</h4><p>Some notable examples:</p><ul><li>Gmail</li><li>Google Maps</li><li>Facebook</li><li>Twitter</li><li>Google Drive</li></ul><h4>Pros and cons of SPAs</h4><p>An SPA feels much faster to the user, because instead of waiting for the client-server communication to happen, and wait for the browser to re-render the page, you can now have instant feedback. This is the responsibility of the application maker, but you can have transitions and spinners and any kind of UX improvement that is certainly better than the traditional workflow.</p><p>In addition to making the experience faster to the user, the server will consume less resources because you can focus on providing an efficient API instead of building the layouts server-side.</p><p>This makes it ideal if you also build a mobile app on top of the API, as you can completely reuse your existing server-side code.</p><p>Single Page Applications are easy to transform into Progressive Web Apps, which in turn enables you to provide local caching and to support offline experiences for your services (or simply a better error message if your users need to be online).</p><p>SPAs are best used when there is no need for SEO (search engine optimization). For example for apps that work behind a login.</p><p>Search engines, while improving every day, still have trouble indexing sites built with an SPA approach rather than the traditional server-rendered pages. This is the case for blogs. If you are going to rely on search engines, don’t even bother with creating a single page application without having a server rendered part as well.</p><p>When coding an SPA, you are going to write a great deal of JavaScript. Since the app can be long-running, you are going to need to pay a lot more attention to possible memory leaks — if in the past your page had a lifespan that was counted in minutes, now an SPA might stay open for hours at a time and if there is any memory issue that’s going to increase the browser memory usage by a lot more and it’s going to cause an unpleasantly slow experience if you don’t take care of it.</p><p>SPAs are great when working in teams. Backend developers can just focus on the API, and frontend developers can focus on creating the best user experience, making use of the API built in the backend.</p><p>As a con, Single Page Apps rely heavily on JavaScript. This might make using an application running on low power devices a poor experience in terms of speed. Also, some of your visitors might just have JavaScript disabled, and you also need to consider accessibility for anything you build.</p><h4>Overriding the navigation</h4><p>Since you get rid of the default browser navigation, URLs must be managed manually.</p><p>This part of an application is called the router. Some frameworks already take care of them for you (like Ember), others require libraries that will do this job (like <a href="https://flaviocopes.com/react-router/">React Router</a>).</p><p>What’s the problem? In the beginning, this was an afterthought for developers building Single Page Applications. This caused the common “broken back button” issue: when navigating inside the application the URL didn’t change (since the browser default navigation was hijacked) and hitting the back button, a common operation that users do to go to the previous screen, might move to a website you visited a long time ago.</p><p>This problem can now be solved using the <a href="https://flaviocopes.com/history-api/">History API</a> offered by browsers, but most of the time you’ll use a library that internally uses that API, like <strong>React Router</strong>.</p><h3>Declarative</h3><p>What does it mean when you read that React is declarative? You’ll run across articles describing React as a <strong>declarative approach to building UIs</strong>.</p><p>React made its “declarative approach” quite popular and upfront so it permeated the frontend world along with React.</p><p>It’s really not a new concept, but React took building UIs a lot more declaratively than with HTML templates:</p><ul><li>you can build Web interfaces without even touching the DOM directly</li><li>you can have an event system without having to interact with the actual DOM Events.</li></ul><p>The opposite of declarative is <strong>imperative</strong>. A common example of an imperative approach is looking up elements in the DOM using jQuery or DOM events. You tell the browser exactly what to do, instead of telling it what you need.</p><p>The React declarative approach abstracts that for us. We just tell React we want a component to be rendered in a specific way, and we never have to interact with the DOM to reference it later.</p><h3>Immutability</h3><p>One concept you will likely meet when programming in React is immutability (and its opposite, mutability).</p><p>It’s a controversial topic, but whatever you might think about the concept of immutability, React and most of its ecosystem kind of forces this, so you need to at least have a grasp of why it’s so important and the implications of it.</p><p>In programming, a variable is immutable when its value cannot change after it’s created.</p><p>You are already using immutable variables without knowing it when you manipulate a string. Strings are immutable by default, when you change them in reality you create a new string and assign it to the same variable name.</p><p>An immutable variable can never be changed. To update its value, you create a new variable.</p><p>The same applies to objects and arrays.</p><p>Instead of changing an array, to add a new item you create a new array by concatenating the old array, plus the new item.</p><p>An object is never updated, but copied before changing it.</p><p>This applies to React in many places.</p><p>For example, you should never mutate the state property of a component directly, but only through the setState() method.</p><p>In Redux, you never mutate the state directly, but only through reducers, which are functions.</p><p>The question is, why?</p><p>There are various reasons, the most important of which are:</p><ul><li>Mutations can be centralized, like in the case of Redux, which improves your debugging capabilities and reduces sources of errors.</li><li>Code looks cleaner and simpler to understand. You never expect a function to change some value without you knowing, which gives you <strong>predictability</strong>. When a function does not mutate objects but just returns a new object, it’s called a pure function.</li><li>The library can optimize the code because for example JavaScript is faster when swapping an old object reference for an entirely new object, rather than mutating an existing object. This gives you <strong>performance</strong>.</li></ul><h3>Purity</h3><p>In JavaScript, when a function does not mutate objects but just returns a new object, it’s called a pure function.</p><p>A function, or a method, in order to be called <em>pure</em> should not cause side effects and should return the same output when called multiple times with the same input.</p><p>A pure function takes an input and returns an output without changing the input nor anything else.</p><p>Its output is only determined by the arguments. You could call this function 1M times, and given the same set of arguments, the output will always be the same.</p><p>React applies this concept to components. A React component is a pure component when its output is only dependant on its props.</p><p>All functional components are pure components:</p><pre>const Button = props =&gt; {<br>  return &lt;button&gt;{props.message}&lt;/button&gt;<br>}</pre><p>Class components can be pure if their output only depends on the props:</p><pre>class Button extends React.Component {<br>  render() {<br>    return &lt;button&gt;{this.props.message}&lt;/button&gt;<br>  }<br>}</pre><h3>Composition</h3><p>In programming, composition allows you to build more complex functionality by combining small and focused functions.</p><p>For example, think about using map() to create a new array from an initial set, and then filtering the result using filter():</p><pre>const list = [&#39;Apple&#39;, &#39;Orange&#39;, &#39;Egg&#39;]<br>list.map(item =&gt; item[0]).filter(item =&gt; item === &#39;A&#39;) //&#39;A&#39;</pre><p>In React, composition allows you to have some pretty cool advantages.</p><p>You create small and lean components and use them to <em>compose</em> more functionality on top of them. How?</p><h4>Create specialized version of a component</h4><p>Use an outer component to expand and specialize a more generic component:</p><pre>const Button = props =&gt; {<br>  return &lt;button&gt;{props.text}&lt;/button&gt;<br>}</pre><pre>const SubmitButton = () =&gt; {<br>  return &lt;Button text=&quot;Submit&quot; /&gt;<br>}</pre><pre>const LoginButton = () =&gt; {<br>  return &lt;Button text=&quot;Login&quot; /&gt;<br>}</pre><h4>Pass methods as props</h4><p>A component can focus on tracking a click event, for example, and what actually happens when the click event happens is up to the container component:</p><pre>const Button = props =&gt; {<br>  return &lt;button onClick={props.onClickHandler}&gt;{props.text}&lt;/button&gt;<br>}</pre><pre>const LoginButton = props =&gt; {<br>  return &lt;Button text=&quot;Login&quot; onClickHandler={props.onClickHandler} /&gt;<br>}</pre><pre>const Container = () =&gt; {<br>  const onClickHandler = () =&gt; {<br>    alert(&#39;clicked&#39;)<br>  }</pre><pre>  return &lt;LoginButton onClickHandler={onClickHandler} /&gt;<br>}</pre><h4>Using children</h4><p>The props.children property allows you to inject components inside other components.</p><p>The component needs to output props.children in its JSX:</p><pre>const Sidebar = props =&gt; {<br>  return &lt;aside&gt;{props.children}&lt;/aside&gt;<br>}</pre><p>and you embed more components into it in a transparent way:</p><pre>&lt;Sidebar&gt;<br>  &lt;Link title=&quot;First link&quot; /&gt;<br>  &lt;Link title=&quot;Second link&quot; /&gt;<br>&lt;/Sidebar&gt;</pre><h4>Higher order components</h4><p>When a component receives a component as a prop and returns a component, it’s called higher order component.</p><p>We’ll see them in a little while.</p><h3>The Virtual DOM</h3><p>Many existing frameworks, before React came on the scene, were directly manipulating the DOM on every change.</p><p>First, what is the DOM?</p><p>The DOM (<em>Document Object Model</em>) is a Tree representation of the page, starting from the &lt;html&gt; tag, going down into every child, which are called nodes.</p><p>It’s kept in the browser memory, and directly linked to what you see in a page. The DOM has an API that you can use to traverse it, access every single node, filter them, modify them.</p><p>The API is the familiar syntax you have likely seen many times, if you were not using the abstract API provided by jQuery and friends:</p><pre>document.getElementById(id)<br>document.getElementsByTagName(name)<br>document.createElement(name)<br>parentNode.appendChild(node)<br>element.innerHTML<br>element.style.left<br>element.setAttribute()<br>element.getAttribute()<br>element.addEventListener()<br>window.content<br>window.onload<br>window.dump()<br>window.scrollTo()</pre><p>React keeps a copy of the DOM representation, for what concerns the React rendering: the Virtual DOM</p><h4>The Virtual DOM Explained</h4><p>Every time the DOM changes, the browser has to do two intensive operations: repaint (visual or content changes to an element that do not affect the layout and positioning relative to other elements) and reflow (recalculate the layout of a portion of the page — or the whole page layout).</p><p>React uses a Virtual DOM to help the browser use less resources when changes need to be done on a page.</p><p>When you call setState() on a Component, specifying a state different than the previous one, React marks that Component as <strong>dirty</strong>. This is key: React only updates when a Component changes the state explicitly.</p><p>What happens next is:</p><ul><li>React updates the Virtual DOM relative to the components marked as dirty (with some additional checks, like triggering shouldComponentUpdate())</li><li>Runs the diffing algorithm to reconcile the changes</li><li>Updates the real DOM</li></ul><h4>Why is the Virtual DOM helpful: batching</h4><p>The key thing is that React batches much of the changes and performs a unique update to the real DOM, by changing all the elements that need to be changed at the same time, so the repaint and reflow the browser must perform to render the changes are executed just once.</p><h3>Unidirectional Data Flow</h3><p>Working with React you might encounter the term Unidirectional Data Flow. What does it mean? Unidirectional Data Flow is not a concept unique to React, but as a JavaScript developer this might be the first time you hear it.</p><p>In general this concept means that data has one, and only one, way to be transferred to other parts of the application.</p><p>In React this means that:</p><ul><li>state is passed to the view and to child components</li><li>actions are triggered by the view</li><li>actions can update the state</li><li>the state change is passed to the view and to child components</li></ul><p>The view is a result of the application state. State can only change when actions happen. When actions happen, the state is updated.</p><p>Thanks to one-way bindings, data cannot flow in the opposite way (as would happen with two-way bindings, for example), and this has some key advantages:</p><ul><li>it’s less error prone, as you have more control over your data</li><li>it’s easier to debug, as you know <em>what</em> is coming from <em>where</em></li><li>it’s more efficient, as the library already knows what the boundaries are of each part of the system</li></ul><p>A state is always owned by one Component. Any data that’s affected by this state can only affect Components below it: its children.</p><p>Changing state on a Component will never affect its parent, or its siblings, or any other Component in the application: just its children.</p><p>This is the reason that the state is often moved up in the Component tree, so that it can be shared between components that need to access it.</p><h3>SECTION 3: IN-DEPTH REACT</h3><h3>JSX</h3><p>JSX is a technology that was introduced by React.</p><p>Although React can work completely fine without using JSX, it’s an ideal technology to work with components, so React benefits a lot from JSX.</p><p>At first, you might think that using JSX is like mixing HTML and <a href="https://flaviocopes.com/javascript/">JavaScript</a> (and as you’ll see CSS).</p><p>But this is not true, because what you are really doing when using JSX syntax is writing a declarative syntax of what a component UI should be.</p><p>And you’re describing that UI not using strings, but instead using JavaScript, which allows you to do many nice things.</p><h4>A JSX primer</h4><p>Here is how you define a h1 tag containing a string:</p><pre>const element = &lt;h1&gt;Hello, world!&lt;/h1&gt;</pre><p>It looks like a strange mix of JavaScript and HTML, but in reality it’s all JavaScript.</p><p>What looks like HTML, is actually syntactic sugar for defining components and their positioning inside the markup.</p><p>Inside a JSX expression, attributes can be inserted very easily:</p><pre>const myId = &#39;test&#39;<br>const element = &lt;h1 id={myId}&gt;Hello, world!&lt;/h1&gt;</pre><p>You just need to pay attention when an attribute has a dash (-) which is converted to camelCase syntax instead, and these 2 special cases:</p><ul><li>class becomes className</li><li>for becomes htmlFor</li></ul><p>because they are reserved words in JavaScript.</p><p>Here’s a JSX snippet that wraps two components into a div tag:</p><pre>&lt;div&gt;<br>  &lt;BlogPostsList /&gt;<br>  &lt;Sidebar /&gt;<br>&lt;/div&gt;</pre><p>A tag always needs to be closed, because this is more XML than HTML (if you remember the XHTML days, this will be familiar, but since then the HTML5 loose syntax won). In this case a self-closing tag is used.</p><p>Notice how I wrapped the 2 components into a div. Why? Because <strong>the render() function can only return a single node</strong>, so in case you want to return 2 siblings, just add a parent. It can be any tag, not just div.</p><h4>Transpiling JSX</h4><p>A browser cannot execute JavaScript files containing JSX code. They must be first transformed to regular JS.</p><p>How? By doing a process called <strong>transpiling</strong>.</p><p>We already said that JSX is optional, because to every JSX line, a corresponding plain JavaScript alternative is available, and that’s what JSX is transpiled to.</p><p>For example the following two constructs are equivalent:</p><blockquote><em>Plain JS</em></blockquote><pre>ReactDOM.render(<br>  React.DOM.div(<br>    { id: &#39;test&#39; },<br>    React.DOM.h1(null, &#39;A title&#39;),<br>    React.DOM.p(null, &#39;A paragraph&#39;)<br>  ),<br>  document.getElementById(&#39;myapp&#39;)<br>)</pre><blockquote><em>JSX</em></blockquote><pre>ReactDOM.render(<br>  &lt;div id=&quot;test&quot;&gt;<br>    &lt;h1&gt;A title&lt;/h1&gt;<br>    &lt;p&gt;A paragraph&lt;/p&gt;<br>  &lt;/div&gt;,<br>  document.getElementById(&#39;myapp&#39;)<br>)</pre><p>This very basic example is just the starting point, but you can already see how more complicated the plain JS syntax is compared to using JSX.</p><p>At the time of writing the most popular way to perform the <strong>transpilation</strong> is to use <strong>Babel</strong>, which is the default option when running create-react-app, so if you use it you don&#39;t have to worry, everything happens under the hood for you.</p><p>If you don’t use create-react-app you need to setup Babel yourself.</p><h4>JS in JSX</h4><p>JSX accepts any kind of JavaScript mixed into it.</p><p>Whenever you need to add some JS, just put it inside curly braces {}. For example here&#39;s how to use a constant value defined elsewhere:</p><pre>const paragraph = &#39;A paragraph&#39;<br>ReactDOM.render(<br>  &lt;div id=&quot;test&quot;&gt;<br>    &lt;h1&gt;A title&lt;/h1&gt;<br>    &lt;p&gt;{paragraph}&lt;/p&gt;<br>  &lt;/div&gt;,<br>  document.getElementById(&#39;myapp&#39;)<br>)</pre><p>This is a basic example. Curly braces accept <em>any</em> JS code:</p><pre>const paragraph = &#39;A paragraph&#39;<br>ReactDOM.render(<br>  &lt;table&gt;<br>    {rows.map((row, i) =&gt; {<br>      return &lt;tr&gt;{row.text}&lt;/tr&gt;<br>    })}<br>  &lt;/table&gt;,<br>  document.getElementById(&#39;myapp&#39;)<br>)</pre><p>As you can see <em>we nested JavaScript inside JSX defined inside JavaScript nested in JSX</em>. You can go as deep as you need.</p><h4>HTML in JSX</h4><p>JSX resembles HTML a lot, but it’s actually XML syntax.</p><p>In the end you render HTML, so you need to know a few differences between how you would define some things in HTML, and how you define them in JSX.</p><h4>You need to close all tags</h4><p>Just like in XHTML, if you have ever used it, you need to close all tags: no more &lt;br&gt; but instead use the self-closing tag: &lt;br /&gt; (the same goes for other tags)</p><h4>camelCase is the new standard</h4><p>In HTML you’ll find attributes without any case (e.g. onchange). In JSX, they are renamed to their camelCase equivalent:</p><ul><li>onchange =&gt; onChange</li><li>onclick =&gt; onClick</li><li>onsubmit =&gt; onSubmit</li></ul><h4>class becomes className</h4><p>Due to the fact that JSX is JavaScript, and class is a reserved word, you can&#39;t write</p><pre>&lt;p class=&quot;description&quot;&gt;</pre><p>but you need to use</p><pre>&lt;p className=&quot;description&quot;&gt;</pre><p><strong>The same applies to </strong><strong>for</strong> which is translated to htmlFor.</p><h4>CSS in React</h4><p>JSX provides a cool way to define CSS.</p><p>If you have a little experience with HTML inline styles, at first glance you’ll find yourself pushed back 10 or 15 years, to a world where inline CSS was completely normal (nowadays it’s demonized and usually just a “quick fix” go-to solution).</p><p>JSX style is not the same thing: first of all, instead of accepting a string containing CSS properties, the JSX style attribute only accepts an object. This means you define properties in an object:</p><pre>var divStyle = {<br>  color: &#39;white&#39;<br>}</pre><pre>ReactDOM.render(&lt;div style={divStyle}&gt;Hello World!&lt;/div&gt;, mountNode)</pre><p>or</p><pre>ReactDOM.render(&lt;div style={{ color: &#39;white&#39; }}&gt;Hello World!&lt;/div&gt;, mountNode)</pre><p>The CSS values you write in JSX are slightly different from plain CSS:</p><ul><li>the keys property names are camelCased</li><li>values are just strings</li><li>you separate each tuple with a comma</li></ul><h4>Why is this preferred over plain CSS / SASS / LESS?</h4><p>CSS is an <strong>unsolved problem</strong>. Since its inception, dozens of tools around it rose and then fell. The main problem with JS is that there is no scoping and it’s easy to write CSS that is not enforced in any way, thus a “quick fix” can impact elements that should not be touched.</p><p>JSX allows components (defined in React for example) to completely encapsulate their style.</p><h4>Is this the go-to solution?</h4><p>Inline styles in JSX are good until you need to</p><ol><li>write media queries</li><li>style animations</li><li>reference pseudo classes (e.g. :hover)</li><li>reference pseudo elements (e.g. ::first-letter)</li></ol><p>In short, they cover the basics, but it’s not the final solution.</p><h4>Forms in JSX</h4><p>JSX adds some changes to how HTML forms work, with the goal of making things easier for the developer.</p><h4>value and defaultValue</h4><p>The value attribute always holds the current value of the field.</p><p>The defaultValue attribute holds the default value that was set when the field was created.</p><p><em>This helps solve some weird behavior of regular </em><a href="https://flaviocopes.com/dom/"><em>DOM</em></a><em> interaction when inspecting </em><em>input.value and </em><em>input.getAttribute(&#39;value&#39;) returning one the current value and one the original default value.</em></p><p>This also applies to the textarea field, e.g.</p><pre>&lt;textarea&gt;Some text&lt;/textarea&gt;</pre><p>but instead</p><pre>&lt;textarea defaultValue={&#39;Some text&#39;} /&gt;</pre><p>For select fields, instead of using</p><pre>&lt;select&gt;<br>  &lt;option value=&quot;x&quot; selected&gt;<br>    ...<br>  &lt;/option&gt;<br>&lt;/select&gt;</pre><p>use</p><pre>&lt;select defaultValue=&quot;x&quot;&gt;<br>  &lt;option value=&quot;x&quot;&gt;...&lt;/option&gt;<br>&lt;/select&gt;</pre><h4>A more consistent onChange</h4><p>Passing a function to the onChange attribute you can subscribe to events on form fields.</p><p>It works consistently across fields, even radio, select and checkbox input fields fire a onChange event.</p><p>onChange also fires when typing a character into an input or textarea field.</p><h4>JSX auto escapes</h4><p>To mitigate the ever present risk of XSS exploits, JSX forces automatic escaping in expressions.</p><p>This means that you might run into issues when using an HTML entity in a string expression.</p><p>You expect the following to print © 2017:</p><pre>&lt;p&gt;{&#39;&amp;copy; 2017&#39;}&lt;/p&gt;</pre><p>But it’s not, it’s printing &amp;copy; 2017 because the string is escaped.</p><p>To fix this you can either move the entities outside the expression:</p><pre>&lt;p&gt;&amp;copy; 2017&lt;/p&gt;</pre><p>or by using a constant that prints the Unicode representation corresponding to the HTML entity you need to print:</p><pre>&lt;p&gt;{&#39;\u00A9 2017&#39;}&lt;/p&gt;</pre><h4>White space in JSX</h4><p>To add white space in JSX there are 2 rules:</p><p><strong>Rule 1: Horizontal white space is trimmed to 1</strong></p><p>If you have white space between elements in the same line, it’s all trimmed to 1 white space.</p><pre>&lt;p&gt;Something       becomes               this&lt;/p&gt;</pre><p>becomes</p><pre>&lt;p&gt;Something becomes this&lt;/p&gt;</pre><p><strong>Rule 2: Vertical white space is eliminated</strong></p><pre>&lt;p&gt;<br>  Something<br>  becomes<br>  this<br>&lt;/p&gt;</pre><p>becomes</p><pre>&lt;p&gt;Somethingbecomesthis&lt;/p&gt;</pre><p>To fix this problem you need to explicitly add white space, by adding a space expression like this:</p><pre>&lt;p&gt;<br>  Something<br>  {&#39; &#39;}becomes<br>  {&#39; &#39;}this<br>&lt;/p&gt;</pre><p>or by embedding the string in a space expression:</p><pre>&lt;p&gt;<br>  Something<br>  {&#39; becomes &#39;}<br>  this<br>&lt;/p&gt;</pre><h4>Adding comments in JSX</h4><p>You can add comments to JSX by using the normal JavaScript comments inside an expression:</p><pre>&lt;p&gt;<br>  {/* a comment */}<br>  {<br>    //another comment<br>  }<br>&lt;/p&gt;</pre><h4>Spread attributes</h4><p>In JSX a common operation is assigning values to attributes.</p><p>Instead of doing it manually, e.g.</p><pre>&lt;div&gt;<br>  &lt;BlogPost title={data.title} date={data.date} /&gt;<br>&lt;/div&gt;</pre><p>you can pass</p><pre>&lt;div&gt;<br>  &lt;BlogPost {...data} /&gt;<br>&lt;/div&gt;</pre><p>and the properties of the data object will be used as attributes automatically, thanks to the <em>ES6 spread operator</em>.</p><h4>How to loop in JSX</h4><p>If you have a set of elements you need to loop upon to generate a JSX partial, you can create a loop, and then add JSX to an array:</p><pre>const elements = [] //..some array</pre><pre>const items = []</pre><pre>for (const [index, value] of elements.entries()) {<br>  items.push(&lt;Element key={index} /&gt;)<br>}</pre><p>Now when rendering the JSX you can embed the items array simply by wrapping it in curly braces:</p><pre>const elements = [&#39;one&#39;, &#39;two&#39;, &#39;three&#39;];</pre><pre>const items = []</pre><pre>for (const [index, value] of elements.entries()) {<br>  items.push(&lt;li key={index}&gt;{value}&lt;/li&gt;)<br>}</pre><pre>return (<br>  &lt;div&gt;<br>    {items}<br>  &lt;/div&gt;<br>)</pre><p>You can do the same directly in the JSX, using map instead of a for-of loop:</p><pre>const elements = [&#39;one&#39;, &#39;two&#39;, &#39;three&#39;];<br>return (<br>  &lt;ul&gt;<br>    {elements.map((value, index) =&gt; {<br>      return &lt;li key={index}&gt;{value}&lt;/li&gt;<br>    })}<br>  &lt;/ul&gt;<br>)</pre><h3>Components</h3><p>A component is one isolated piece of interface. For example in a typical blog homepage you might find the Sidebar component, and the Blog Posts List component. They are in turn composed of components themselves, so you could have a list of Blog post components, each for every blog post, and each with its own peculiar properties.</p><p>React makes it very simple: everything is a component.</p><p>Even plain HTML tags are component on their own, and they are added by default.</p><p>The next 2 lines are equivalent, they do the same thing. One with <strong>JSX</strong>, one without, by injecting &lt;h1&gt;Hello World!&lt;/h1&gt; into an element with id app.</p><pre>import React from &#39;react&#39;<br>import ReactDOM from &#39;react-dom&#39;</pre><pre>ReactDOM.render(&lt;h1&gt;Hello World!&lt;/h1&gt;, document.getElementById(&#39;app&#39;))</pre><pre>ReactDOM.render(<br>  React.DOM.h1(null, &#39;Hello World!&#39;),<br>  document.getElementById(&#39;app&#39;)<br>)</pre><p>See, React.DOM exposed us an h1 component. Which other HTML tags are available? All of them! You can inspect what React.DOM offers by typing it in the Browser Console:</p><p>(the list is longer)</p><p>The built-in components are nice, but you’ll quickly outgrow them. What React excels in is letting us compose a UI by composing custom components.</p><h4>Custom components</h4><p>There are 2 ways to define a component in React.</p><p>A function component:</p><pre>const BlogPostExcerpt = () =&gt; {<br>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Title&lt;/h1&gt;<br>      &lt;p&gt;Description&lt;/p&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>A class component:</p><pre>import React, { Component } from &#39;react&#39;</pre><pre>class BlogPostExcerpt extends Component {<br>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;h1&gt;Title&lt;/h1&gt;<br>        &lt;p&gt;Description&lt;/p&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><p>Up until recently, class components were the only way to define a component that had its own state, and could access the lifecycle methods so you could do things when the component was first rendered, updated or removed.</p><p>React Hooks changed this, so our function components are now much more powerful than ever and I believe we’ll see fewer and fewer class components in the future, although it will still be perfectly valid way to create components.</p><p>There is also a third syntax which uses the ES5 syntax, without the classes:</p><pre>import React from &#39;react&#39;</pre><pre>React.createClass({<br>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;h1&gt;Title&lt;/h1&gt;<br>        &lt;p&gt;Description&lt;/p&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>})</pre><p>You’ll rarely see this in modern, &gt; ES6 codebases.</p><h3>State</h3><h4>Setting the default state of a component</h4><p>In the Component constructor, initialize this.state. For example the BlogPostExcerpt component might have a clicked state:</p><pre>class BlogPostExcerpt extends Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { clicked: false }<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;h1&gt;Title&lt;/h1&gt;<br>        &lt;p&gt;Description&lt;/p&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><h4>Accessing the state</h4><p>The <em>clicked</em> state can be accessed by referencing this.state.clicked:</p><pre>class BlogPostExcerpt extends Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { clicked: false }<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;h1&gt;Title&lt;/h1&gt;<br>        &lt;p&gt;Description&lt;/p&gt;<br>        &lt;p&gt;Clicked: {this.state.clicked}&lt;/p&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><h4>Mutating the state</h4><p>A state should never be mutated by using</p><pre>this.state.clicked = true</pre><p>Instead, you should always use setState() instead, passing it an object:</p><pre>this.setState({ clicked: true })</pre><p>The object can contain a subset, or a superset, of the state. Only the properties you pass will be mutated, the ones omitted will be left in their current state.</p><h4>Why you should always use setState()</h4><p>The reason is that using this method, React knows that the state has changed. It will then start the series of events that will lead to the Component being re-rendered, along with any <a href="https://flaviocopes.com/dom/">DOM</a> update.</p><h4>Unidirectional Data Flow</h4><p>A state is always owned by one Component. Any data that’s affected by this state can only affect Components below it: its children.</p><p>Changing the state on a Component will never affect its parent, or its siblings, or any other Component in the application: just its children.</p><p>This is the reason the state is often moved up in the Component tree.</p><h4>Moving the State Up in the Tree</h4><p>Because of the Unidirectional Data Flow rule, if two components need to share state, the state needs to be moved up to a common ancestor.</p><p>Many times the closest ancestor is the best place to manage the state, but it’s not a mandatory rule.</p><p>The state is passed down to the components that need that value via props:</p><pre>class Converter extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { currency: &#39;€&#39; }<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;Display currency={this.state.currency} /&gt;<br>        &lt;CurrencySwitcher currency={this.state.currency} /&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><p>The state can be mutated by a child component by passing a mutating function down as a prop:</p><pre>class Converter extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { currency: &#39;€&#39; }<br>  }</pre><pre>  handleChangeCurrency = event =&gt; {<br>    this.setState({ currency: this.state.currency === &#39;€&#39; ? &#39;$&#39; : &#39;€&#39; })<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;Display currency={this.state.currency} /&gt;<br>        &lt;CurrencySwitcher<br>          currency={this.state.currency}<br>          handleChangeCurrency={this.handleChangeCurrency}<br>        /&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><pre>const CurrencySwitcher = props =&gt; {<br>  return (<br>    &lt;button onClick={props.handleChangeCurrency}&gt;<br>      Current currency is {props.currency}. Change it!<br>    &lt;/button&gt;<br>  )<br>}</pre><pre>const Display = props =&gt; {<br>  return &lt;p&gt;Current currency is {props.currency}.&lt;/p&gt;<br>}</pre><h3>Props</h3><p>Props is how Components get their properties. Starting from the top component, every child component gets its props from the parent. In a function component, props is all it gets passed, and they are available by adding props as the function argument:</p><pre>const BlogPostExcerpt = props =&gt; {<br>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;{props.title}&lt;/h1&gt;<br>      &lt;p&gt;{props.description}&lt;/p&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>In a class component, props are passed by default. There is no need to add anything special, and they are accessible as this.props in a Component instance.</p><pre>import React, { Component } from &#39;react&#39;</pre><pre>class BlogPostExcerpt extends Component {<br>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;h1&gt;{this.props.title}&lt;/h1&gt;<br>        &lt;p&gt;{this.props.description}&lt;/p&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><p>Passing props down to child components is a great way to pass values around in your application. A component either holds data (has state) or receives data through its props.</p><p>It gets complicated when:</p><ul><li>you need to access the state of a component from a child that’s several levels down (all the previous children need to act as a pass-through, even if they do not need to know the state, complicating things)</li><li>you need to access the state of a component from a completely unrelated component.</li></ul><h4>Default values for props</h4><p>If any value is not required we need to specify a default value for it if it’s missing when the Component is initialized.</p><pre>BlogPostExcerpt.propTypes = {<br>  title: PropTypes.string,<br>  description: PropTypes.string<br>}</pre><pre>BlogPostExcerpt.defaultProps = {<br>  title: &#39;&#39;,<br>  description: &#39;&#39;<br>}</pre><p>Some tooling like <a href="https://flaviocopes.com/eslint/">ESLint</a> have the ability to enforce defining the defaultProps for a Component with some propTypes not explicitly required.</p><h4>How props are passed</h4><p>When initializing a component, pass the props in a way similar to HTML attributes:</p><pre>const desc = &#39;A description&#39;<br>//...<br>&lt;BlogPostExcerpt title=&quot;A blog post&quot; description={desc} /&gt;</pre><p>We passed the title as a plain string (something we can <em>only</em> do with strings!), and description as a variable.</p><h4>Children</h4><p>A special prop is children. That contains the value of anything that is passed in the body of the component, for example:</p><pre>&lt;BlogPostExcerpt title=&quot;A blog post&quot; description=&quot;{desc}&quot;&gt;<br>  Something<br>&lt;/BlogPostExcerpt&gt;</pre><p>In this case, inside BlogPostExcerpt we could access &quot;Something&quot; by looking up this.props.children.</p><p>While Props allow a Component to receive properties from its parent, to be “instructed” to print some data for example, state allows a component to take on life itself, and be independent of the surrounding environment.</p><h3>Presentational vs container components</h3><p>In React, components are often divided into 2 big buckets: <strong>presentational components</strong> and <strong>container components</strong>.</p><p>Each of those have their unique characteristics.</p><p>Presentational components are mostly concerned with generating some markup to be outputted.</p><p>They don’t manage any kind of state, except for state related the the presentation</p><p>Container components are mostly concerned with the “backend” operations.</p><p>They might handle the state of various sub-components. They might wrap several presentational components. They might interface with Redux.</p><p>As a way to simplify the distinction, we can say <strong>presentational components are concerned with the look</strong>, <strong>container components are concerned with making things work</strong>.</p><p>For example, this is a presentational component. It gets data from its props, and just focuses on showing an element:</p><pre>const Users = props =&gt; (<br>  &lt;ul&gt;<br>    {props.users.map(user =&gt; (<br>      &lt;li&gt;{user}&lt;/li&gt;<br>    ))}<br>  &lt;/ul&gt;<br>)</pre><p>On the other hand this is a container component. It manages and stores its own data, and uses the presentational component to display it.</p><pre>class UsersContainer extends React.Component {<br>  constructor() {<br>    this.state = {<br>      users: []<br>    }<br>  }</pre><pre>  componentDidMount() {<br>    axios.get(&#39;/users&#39;).then(users =&gt;<br>      this.setState({ users: users }))<br>    )<br>  }</pre><pre>  render() {<br>    return &lt;Users users={this.state.users} /&gt;<br>  }<br>}</pre><h3>State vs props</h3><p>In a React component, <strong>props</strong> are variables passed to it by its parent component. <strong>State</strong> on the other hand is still variables, but directly initialized and managed by the component.</p><p>The state can be initialized by props.</p><p>For example, a parent component might include a child component by calling</p><pre>&lt;ChildComponent /&gt;</pre><p>The parent can pass a prop by using this syntax:</p><pre>&lt;ChildComponent color=green /&gt;</pre><p>Inside the ChildComponent constructor we could access the prop:</p><pre>class ChildComponent extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    console.log(props.color)<br>  }<br>}</pre><p>and any other method in this class can reference the props using this.props.</p><p>Props can be used to set the internal state based on a prop value in the constructor, like this:</p><pre>class ChildComponent extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state.colorName = props.color<br>  }<br>}</pre><p>Of course a component can also initialize the state without looking at props.</p><p>In this case there’s nothing useful going on, but imagine doing something different based on the prop value, probably setting a state value is best.</p><p>Props should never be changed in a child component, so if there’s something going on that alters some variable, that variable should belong to the component state.</p><p>Props are also used to allow child components to access methods defined in the parent component. This is a good way to centralize managing the state in the parent component, and avoid children having the need to have their own state.</p><p>Most of your components will just display some kind of information based on the props they received, and stay <strong>stateless</strong>.</p><h3>PropTypes</h3><p>Since JavaScript is a dynamically typed language, we don’t really have a way to enforce the type of a variable at compile time, and if we pass invalid types, they will fail at runtime or give weird results if the types are compatible but not what we expect.</p><p>Flow and TypeScript help a lot, but React has a way to directly help with props types, and even before running the code, our tools (editors, linters) can detect when we are passing the wrong values:</p><pre>import PropTypes from &#39;prop-types&#39;<br>import React from &#39;react&#39;</pre><pre>class BlogPostExcerpt extends Component {<br>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;h1&gt;{this.props.title}&lt;/h1&gt;<br>        &lt;p&gt;{this.props.description}&lt;/p&gt;<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><pre>BlogPostExcerpt.propTypes = {<br>  title: PropTypes.string,<br>  description: PropTypes.string<br>}</pre><pre>export default BlogPostExcerpt</pre><h4>Which types can we use</h4><p>These are the fundamental types we can accept:</p><ul><li>PropTypes.array</li><li>PropTypes.bool</li><li>PropTypes.func</li><li>PropTypes.number</li><li>PropTypes.object</li><li>PropTypes.string</li><li>PropTypes.symbol</li></ul><p>We can accept one of two types:</p><pre>PropTypes.oneOfType([<br>  PropTypes.string,<br>  PropTypes.number<br>]),</pre><p>We can accept one of many values:</p><pre>PropTypes.oneOf([&#39;Test1&#39;, &#39;Test2&#39;]),</pre><p>We can accept an instance of a class:</p><pre>PropTypes.instanceOf(Something)</pre><p>We can accept any React node:</p><pre>PropTypes.node</pre><p>or even any type at all:</p><pre>PropTypes.any</pre><p>Arrays have a special syntax that we can use to accept an array of a particular type:</p><pre>PropTypes.arrayOf(PropTypes.string)</pre><p>We can compose object properties by using</p><pre>PropTypes.shape({<br>  color: PropTypes.string,<br>  fontSize: PropTypes.number<br>})</pre><h4>Requiring properties</h4><p>Appending isRequired to any PropTypes option will cause React to return an error if that property is missing:</p><pre>PropTypes.arrayOf(PropTypes.string).isRequired,<br>PropTypes.string.isRequired,</pre><h3>React Fragment</h3><p>Notice how I wrap return values in a div. This is because a component can only return one single element, and if you want more than one, you need to wrap it with another container tag.</p><p>This, however, causes an unnecessary div in the output. You can avoid this by using React.Fragment:</p><pre>import React, { Component } from &#39;react&#39;</pre><pre>class BlogPostExcerpt extends Component {<br>  render() {<br>    return (<br>      &lt;React.Fragment&gt;<br>        &lt;h1&gt;{this.props.title}&lt;/h1&gt;<br>        &lt;p&gt;{this.props.description}&lt;/p&gt;<br>      &lt;/React.Fragment&gt;<br>    )<br>  }<br>}</pre><p>which also has a very nice shorthand syntax &lt;&gt;&lt;/&gt; that is supported only in recent releases (and Babel 7+):</p><pre>import React, { Component } from &#39;react&#39;</pre><pre>class BlogPostExcerpt extends Component {<br>  render() {<br>    return (<br>      &lt;&gt;<br>        &lt;h1&gt;{this.props.title}&lt;/h1&gt;<br>        &lt;p&gt;{this.props.description}&lt;/p&gt;<br>      &lt;/&gt;<br>    )<br>  }<br>}</pre><h3>Events</h3><p>React provides an easy way to manage events. Prepare to say goodbye to addEventListener.</p><p>In the previous article about the State you saw this example:</p><pre>const CurrencySwitcher = props =&gt; {<br>  return (<br>    &lt;button onClick={props.handleChangeCurrency}&gt;<br>      Current currency is {props.currency}. Change it!<br>    &lt;/button&gt;<br>  )<br>}</pre><p>If you’ve been using JavaScript for a while, this is just like plain old <a href="https://flaviocopes.com/javascript-events/">JavaScript event handlers</a>, except that this time you’re defining everything in JavaScript, not in your HTML, and you’re passing a function, not a string.</p><p>The actual event names are a little bit different because in React you use camelCase for everything, so onclick becomes onClick, onsubmit becomes onSubmit.</p><p>For reference, this is old school HTML with JavaScript events mixed in:</p><pre>&lt;button onclick=&quot;handleChangeCurrency()&quot;&gt;...&lt;/button&gt;</pre><h4>Event handlers</h4><p>It’s a convention to have event handlers defined as methods on the Component class:</p><pre>class Converter extends React.Component {<br>  handleChangeCurrency = event =&gt; {<br>    this.setState({ currency: this.state.currency === &#39;€&#39; ? &#39;$&#39; : &#39;€&#39; })<br>  }<br>}</pre><p>All handlers receive an event object that adheres, cross-browser, to the <a href="https://www.w3.org/TR/DOM-Level-3-Events/">W3C UI Events spec</a>.</p><h4>Bind this in methods</h4><p>If you use class components, don’t forget to bind methods. The methods of ES6 classes by default are not bound. What this means is that this is not defined unless you define methods as arrow functions:</p><pre>class Converter extends React.Component {<br>  handleClick = e =&gt; {<br>    /* ... */<br>  }<br>  //...<br>}</pre><p>when using the the property initializer syntax with Babel (enabled by default in create-react-app), otherwise you need to bind it manually in the constructor:</p><pre>class Converter extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.handleClick = this.handleClick.bind(this)<br>  }<br>  handleClick(e) {}<br>}</pre><h3>The events reference</h3><p>There are lots of events supported, here’s a summary list.</p><h4>Clipboard</h4><ul><li>onCopy</li><li>onCut</li><li>onPaste</li></ul><h4>Composition</h4><ul><li>onCompositionEnd</li><li>onCompositionStart</li><li>onCompositionUpdate</li></ul><h4>Keyboard</h4><ul><li>onKeyDown</li><li>onKeyPress</li><li>onKeyUp</li></ul><h4>Focus</h4><ul><li>onFocus</li><li>onBlur</li></ul><h4>Form</h4><ul><li>onChange</li><li>onInput</li><li>onSubmit</li></ul><h4>Mouse</h4><ul><li>onClick</li><li>onContextMenu</li><li>onDoubleClick</li><li>onDrag</li><li>onDragEnd</li><li>onDragEnter</li><li>onDragExit</li><li>onDragLeave</li><li>onDragOver</li><li>onDragStart</li><li>onDrop</li><li>onMouseDown</li><li>onMouseEnter</li><li>onMouseLeave</li><li>onMouseMove</li><li>onMouseOut</li><li>onMouseOver</li><li>onMouseUp</li></ul><h4>Selection</h4><ul><li>onSelect</li></ul><h4>Touch</h4><ul><li>onTouchCancel</li><li>onTouchEnd</li><li>onTouchMove</li><li>onTouchStart</li></ul><h4>UI</h4><ul><li>onScroll</li></ul><h4>Mouse Wheel</h4><ul><li>onWheel</li></ul><h4>Media</h4><ul><li>onAbort</li><li>onCanPlay</li><li>onCanPlayThrough</li><li>onDurationChange</li><li>onEmptied</li><li>onEncrypted</li><li>onEnded</li><li>onError</li><li>onLoadedData</li><li>onLoadedMetadata</li><li>onLoadStart</li><li>onPause</li><li>onPlay</li><li>onPlaying</li><li>onProgress</li><li>onRateChange</li><li>onSeeked</li><li>onSeeking</li><li>onStalled</li><li>onSuspend</li><li>onTimeUpdate</li><li>onVolumeChange</li><li>onWaiting</li></ul><h4>Image</h4><ul><li>onLoad</li><li>onError</li></ul><h4>Animation</h4><ul><li>onAnimationStart</li><li>onAnimationEnd</li><li>onAnimationIteration</li></ul><h4>Transition</h4><ul><li>onTransitionEnd</li></ul><h3>Lifecycle Events</h3><p>React class components can have hooks for several lifecycle events.</p><blockquote><em>Hooks allow function components to access them too, in a different way.</em></blockquote><p>During the lifetime of a component, there’s a series of events that gets called, and to each event you can hook and provide custom functionality.</p><p>What hook is best for what functionality is something we’re going to see here.</p><p>First, there are 3 phases in a React component lifecycle:</p><ul><li>Mounting</li><li>Updating</li><li>Unmounting</li></ul><p>Let’s see those 3 phases in detail and the methods that get called for each.</p><h4>Mounting</h4><p>When mounting you have 4 lifecycle methods before the component is mounted in the DOM: the constructor, getDerivedStateFromProps, render and componentDidMount.</p><h4>Constructor</h4><p>The constructor is the first method that is called when mounting a component.</p><p>You usually use the constructor to set up the initial state using this.state = ....</p><h4>getDerivedStateFromProps()</h4><p>When the state depends on props, getDerivedStateFromProps can be used to update the state based on the props value.</p><p>It was added in React 16.3, aiming to replace the componentWillReceiveProps deprecated method.</p><p>In this method you haven’t access to this as it&#39;s a static method.</p><p>It’s a pure method, so it should not cause side effects and should return the same output when called multiple times with the same input.</p><p>Returns an object with the updated elements of the state (or null if the state does not change)</p><h4>render()</h4><p>From the render() method you return the JSX that builds the component interface.</p><p>It’s a pure method, so it should not cause side effects and should return the same output when called multiple times with the same input.</p><h4>componentDidMount()</h4><p>This method is the one that you will use to perform API calls, or process operations on the DOM.</p><h4>Updating</h4><p>When updating you have 5 lifecycle methods before the component is mounted in the DOM: the getDerivedStateFromProps, shouldComponentUpdate, render, getSnapshotBeforeUpdate and componentDidUpdate.</p><h4>getDerivedStateFromProps()</h4><p>See the above description for this method.</p><h4>shouldComponentUpdate()</h4><p>This method returns a boolean, true or false. You use this method to tell React if it should go on with the rerendering, and defaults to true. You will return false when rerendering is expensive and you want to have more control on when this happens.</p><h4>render()</h4><p>See the above description for this method.</p><h4>getSnapshotBeforeUpdate()</h4><p>In this method you have access to the props and state of the previous render, and of the current render.</p><p>Its use cases are very niche, and it’s probably the one that you will use less.</p><h4>componentDidUpdate()</h4><p>This method is called when the component has been updated in the DOM. Use this to run any 3rd party DOM API or call APIs that must be updated when the DOM changes.</p><p>It corresponds to the componentDidMount() method from the mounting phase.</p><h4>Unmounting</h4><p>In this phase we only have one method, componentWillUnmount.</p><h4>componentWillUnmount()</h4><p>The method is called when the component is removed from the DOM. Use this to do any sort of cleanup you need to perform.</p><h4>Legacy</h4><p>If you are working on an app that uses componentWillMount, componentWillReceiveProps or componentWillUpdate, those were deprecated in React 16.3 and you should migrate to other lifecycle methods.</p><h3>Forms in React</h3><p>Forms are one of the few HTML elements that are interactive by default.</p><p>They were designed to allow the user to interact with a page.</p><p>Common uses of forms?</p><ul><li>Search</li><li>Contact forms</li><li>Shopping carts checkout</li><li>Login and registration</li><li>and more!</li></ul><p>Using React we can make our forms much more interactive and less static.</p><p>There are two main ways of handling forms in React, which differ on a fundamental level: how data is managed.</p><ul><li>if the data is handled by the DOM, we call them <strong>uncontrolled components</strong></li><li>if the data is handled by the components we call them <strong>controlled components</strong></li></ul><p>As you can imagine, controlled components is what you will use most of the time. The component state is the single source of truth, rather than the DOM. Some form fields are inherently uncontrolled because of their behavior, like the &lt;input type=&quot;file&quot;&gt; field.</p><p>When an element state changes in a form field managed by a component, we track it using the onChange attribute.</p><pre>class Form extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { username: &#39;&#39; }<br>  }</pre><pre>  handleChange(event) {}</pre><pre>  render() {<br>    return (<br>      &lt;form&gt;<br>        Username:<br>        &lt;input<br>          type=&quot;text&quot;<br>          value={this.state.username}<br>          onChange={this.handleChange}<br>        /&gt;<br>      &lt;/form&gt;<br>    )<br>  }<br>}</pre><p>In order to set the new state, we must bind this to the handleChange method, otherwise this is not accessible from within that method:</p><pre>class Form extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { username: &#39;&#39; }<br>    this.handleChange = this.handleChange.bind(this)<br>  }</pre><pre>  handleChange(event) {<br>    this.setState({ value: event.target.value })<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;form&gt;<br>        &lt;input<br>          type=&quot;text&quot;<br>          value={this.state.username}<br>          onChange={this.handleChange}<br>        /&gt;<br>      &lt;/form&gt;<br>    )<br>  }<br>}</pre><p>Similarly, we use the onSubmit attribute on the form to call the handleSubmit method when the form is submitted:</p><pre>class Form extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { username: &#39;&#39; }<br>    this.handleChange = this.handleChange.bind(this)<br>    this.handleSubmit = this.handleSubmit.bind(this)<br>  }</pre><pre>  handleChange(event) {<br>    this.setState({ value: event.target.value })<br>  }</pre><pre>  handleSubmit(event) {<br>    alert(this.state.username)<br>    event.preventDefault()<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;form onSubmit={this.handleSubmit}&gt;<br>        &lt;input<br>          type=&quot;text&quot;<br>          value={this.state.username}<br>          onChange={this.handleChange}<br>        /&gt;<br>        &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;<br>      &lt;/form&gt;<br>    )<br>  }<br>}</pre><p>Validation in a form can be handled in the handleChange method: you have access to the old value of the state, and the new one. You can check the new value and if not valid reject the updated value (and communicate it in some way to the user).</p><p>HTML Forms are inconsistent. They have a long history, and it shows. React however makes things more consistent for us, and you can get (and update) fields using its value attribute.</p><p>Here’s a textarea, for example:</p><pre>&lt;textarea value={this.state.address} onChange={this.handleChange} /&gt;</pre><p>The same goes for the select tag:</p><pre>&lt;select value=&quot;{this.state.age}&quot; onChange=&quot;{this.handleChange}&quot;&gt;<br>  &lt;option value=&quot;teen&quot;&gt;Less than 18&lt;/option&gt;<br>  &lt;option value=&quot;adult&quot;&gt;18+&lt;/option&gt;<br>&lt;/select&gt;</pre><p>Previously we mentioned the &lt;input type=&quot;file&quot;&gt; field. That works a bit differently.</p><p>In this case you need to get a reference to the field by assigning the ref attribute to a property defined in the constructor with React.createRef(), and use that to get the value of it in the submit handler:</p><pre>class FileInput extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.curriculum = React.createRef()<br>    this.handleSubmit = this.handleSubmit.bind(this)<br>  }</pre><pre>  handleSubmit(event) {<br>    alert(this.curriculum.current.files[0].name)<br>    event.preventDefault()<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;form onSubmit={this.handleSubmit}&gt;<br>        &lt;input type=&quot;file&quot; ref={this.curriculum} /&gt;<br>        &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;<br>      &lt;/form&gt;<br>    )<br>  }<br>}</pre><p>This is the <strong>uncontrolled components</strong> way. The state is stored in the DOM rather than in the component state (notice we used this.curriculum to access the uploaded file, and have not touched the state.</p><p>I know what you’re thinking — beyond those basics, there must be a library that simplifies all this form handling stuff and automates validation, error handling and more, right? There is a great one, <a href="https://github.com/jaredpalmer/formik">Formik</a>.</p><h3>Reference a DOM element</h3><p>React is great at abstracting away the DOM from you when building apps.</p><p>But what if you want to access the DOM element that a React component represents?</p><p>Maybe you have to add a library that interacts directly with the DOM like a chart library, maybe you need to call some DOM API, or add focus on an element.</p><blockquote><em>Whatever the reason is, a good practice is making sure there’s no other way of doing so without accessing the DOM directly.</em></blockquote><p>In the JSX of your component, you can assign the reference of the DOM element to a component property using this attribute:</p><pre>ref={el =&gt; this.someProperty = el}</pre><p>Put this into context, for example with a button element:</p><pre>&lt;button ref={el =&gt; (this.button = el)} /&gt;</pre><p>button refers to a property of the component, which can then be used by the component&#39;s lifecycle methods (or other methods) to interact with the DOM:</p><pre>class SomeComponent extends Component {<br>  render() {<br>    return &lt;button ref={el =&gt; (this.button = el)} /&gt;<br>  }<br>}</pre><p>In a function component the mechanism is the same, you just avoid using this (since it does not point to the component instance) and use a property instead:</p><pre>function SomeComponent() {<br>  let button<br>  return &lt;button ref={el =&gt; (button = el)} /&gt;<br>}</pre><h3>Server side rendering</h3><p><strong>Server Side Rendering</strong>, also called <strong>SSR</strong>, is the ability of a JavaScript application to render on the server rather than in the browser.</p><p>Why would we ever want to do so?</p><ul><li>it allows your site to have a faster first page load time, which is the key to a good user experience</li><li>it is essential for SEO: search engines cannot (yet?) efficiently and correctly index applications that exclusively render client-side. Despite the latest improvements to indexing in Google, there are other search engines too, and Google is not perfect at it in any case. Also, Google favors sites with fast load times, and having to load client-side is not good for speed</li><li>it’s great when people share a page of your site on social media, as they can easily gather the metadata needed to nicely share the link (images, title, description..)</li></ul><p>Without Server Side Rendering, all your server ships is an HTML page with no body, just some script tags that are then used by the browser to render the application.</p><p>Client-rendered apps are great at any subsequent user interaction after the first page load. Server Side Rendering allows us to get the sweet spot in the middle of client-rendered apps and backend-rendered apps: the page is generated server-side, but all interactions with the page once it’s been loaded are handled client-side.</p><p>However Server Side Rendering has its drawback too:</p><ul><li>it’s fair to say that a simple SSR proof of concept is simple, but the complexity of SSR can grow with the complexity of your application</li><li>rendering a big application server-side can be quite resource-intensive, and under heavy load it could even provide a slower experience than client-side rendering, since you have a single bottleneck</li></ul><h3>A very simplistic example of what it takes to Server-Side render a React app</h3><p>SSR setups can grow very, very complex and most tutorials will bake in Redux, React Router and many other concepts from the start.</p><p>To understand how SSR works, let’s start from the basics to implement a proof of concept.</p><blockquote><em>Feel free to skip this paragraph if you just want to look into the libraries that provide SSR and not bother with the ground work</em></blockquote><p>To implement basic SSR we’re going to use Express.</p><blockquote><em>If you are new to Express, or need some catch-up, check out my free Express Handbook here: </em><a href="https://flaviocopes.com/page/ebooks/"><em>https://flaviocopes.com/page/ebooks/</em></a><em>.</em></blockquote><p>Warning: the complexity of SSR can grow with the complexity of your application. This is the bare minimum setup to render a basic React app. For more complex needs you might need to do a bit more work or also check out SSR libraries for React.</p><p>I assume you started a React app with create-react-app. If you are just trying, install one now using npx create-react-app ssr.</p><p>Go to the main app folder with the terminal, then run:</p><pre>npm install express</pre><p>You have a set of folders in your app directory. Create a new folder called server, then go into it and create a file named server.js.</p><p>Following the create-react-app conventions, the app lives in the src/App.js file. We&#39;re going to load that component, and render it to a string using <a href="https://reactjs.org/docs/react-dom-server.html">ReactDOMServer.renderToString()</a>, which is provided by react-dom.</p><p>You get the contents of the ./build/index.html file, and replace the &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;placeholder, which is the tag where the application hooks by default, with `&lt;div id=&quot;root&quot;&gt;\${ReactDOMServer.renderToString(&lt;App /&gt;)}&lt;/div&gt;.</p><p>All the content inside the build folder is going to be served as-is, statically by Express.</p><pre>import path from &#39;path&#39;<br>import fs from &#39;fs&#39;</pre><pre>import express from &#39;express&#39;<br>import React from &#39;react&#39;<br>import ReactDOMServer from &#39;react-dom/server&#39;</pre><pre>import App from &#39;../src/App&#39;</pre><pre>const PORT = 8080<br>const app = express()</pre><pre>const router = express.Router()</pre><pre>const serverRenderer = (req, res, next) =&gt; {<br>  fs.readFile(path.resolve(&#39;./build/index.html&#39;), &#39;utf8&#39;, (err, data) =&gt; {<br>    if (err) {<br>      console.error(err)<br>      return res.status(500).send(&#39;An error occurred&#39;)<br>    }<br>    return res.send(<br>      data.replace(<br>        &#39;&lt;div id=&quot;root&quot;&gt;&lt;/div&gt;&#39;,<br>        `&lt;div id=&quot;root&quot;&gt;${ReactDOMServer.renderToString(&lt;App /&gt;)}&lt;/div&gt;`<br>      )<br>    )<br>  })<br>}<br>router.use(&#39;^/$&#39;, serverRenderer)</pre><pre>router.use(<br>  express.static(path.resolve(__dirname, &#39;..&#39;, &#39;build&#39;), { maxAge: &#39;30d&#39; })<br>)</pre><pre>// tell the app to use the above rules<br>app.use(router)</pre><pre>// app.use(express.static(&#39;./build&#39;))<br>app.listen(PORT, () =&gt; {<br>  console.log(`SSR running on port ${PORT}`)<br>})</pre><p>Now, in the client application, in your src/index.js, instead of calling ReactDOM.render():</p><pre>ReactDOM.render(&lt;App /&gt;, document.getElementById(&#39;root&#39;))</pre><p>call <a href="https://reactjs.org/docs/react-dom.html#hydrate">ReactDOM.hydrate()</a>, which is the same but has the additional ability to attach event listeners to existing markup once React loads:</p><pre>ReactDOM.hydrate(&lt;App /&gt;, document.getElementById(&#39;root&#39;))</pre><p>All the Node.js code needs to be transpiled by Babel, as server-side Node.js code does not know anything about JSX, nor ES Modules (which we use for the include statements).</p><p>Install these 3 packages:</p><pre>npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles express</pre><p><a href="https://www.npmjs.com/package/ignore-styles">ignore-styles</a> is a Babel utility that will tell it to ignore CSS files imported using the import syntax.</p><p>Let’s create an entry point in server/index.js:</p><pre>require(&#39;ignore-styles&#39;)</pre><pre>require(&#39;@babel/register&#39;)({<br>  ignore: [/(node_modules)/],<br>  presets: [&#39;@babel/preset-env&#39;, &#39;@babel/preset-react&#39;]<br>})</pre><pre>require(&#39;./server&#39;)</pre><p>Build the React application, so that the build/ folder is populated:</p><pre>npm run build</pre><p>and let’s run this:</p><pre>node server/index.js</pre><p>I said this is a simplistic approach, and it is:</p><ul><li>it does not handle rendering images correctly when using imports, which need Webpack in order to work (and which complicates the process a lot)</li><li>it does not handle page header metadata, which is essential for SEO and social sharing purposes (among other things)</li></ul><p>So while this is a good example of using ReactDOMServer.renderToString() and ReactDOM.hydrate to get this basic server-side rendering, it&#39;s not enough for real world usage.</p><h4>Server Side Rendering using libraries</h4><p>SSR is hard to do right, and React has no de-facto way to implement it.</p><p>It’s still very much debatable if it’s worth the trouble, complication and overhead to get the benefits, rather than using a different technology to serve those pages. <a href="https://www.reddit.com/r/reactjs/comments/7o6oj6/serverside_rendering_not_worth_it/">This discussion on Reddit</a> has lots of opinions in that regard.</p><p>When Server Side Rendering is an important matter, my suggestion is to rely on pre-made libraries and tools that have had this goal in mind since the beginning.</p><p>In particular, I suggest <strong>Next.js</strong> and <strong>Gatsby</strong>, two projects we’ll see later on.</p><h3>The Context API</h3><p>The Context API is a neat way to pass state across the app without having to use props. It was introduced to allow you to pass state (and enable the state to update) across the app, without having to use props for it.</p><p>The React team suggests to stick to props if you have just a few levels of children to pass, because it’s still a much less complicated API than the Context API.</p><p>In many cases, it enables us to avoid using Redux, simplifying our apps a lot, and also learning how to use React.</p><p>How does it work?</p><p>You create a context using React.createContext(), which returns a Context object:</p><pre>const { Provider, Consumer } = React.createContext()</pre><p>Then you create a wrapper component that returns a <strong>Provider</strong> component, and you add as children all the components from which you want to access the context:</p><pre>class Container extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = {<br>      something: &#39;hey&#39;<br>    }<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;Provider value={{ state: this.state }}&gt;{this.props.children}&lt;/Provider&gt;<br>    )<br>  }<br>}</pre><pre>class HelloWorld extends React.Component {<br>  render() {<br>    return (<br>      &lt;Container&gt;<br>        &lt;Button /&gt;<br>      &lt;/Container&gt;<br>    )<br>  }<br>}</pre><p>I used Container as the name of this component because this will be a global provider. You can also create smaller contexts.</p><p>Inside a component that’s wrapped in a Provider, you use a <strong>Consumer</strong> component to make use of the context:</p><pre>class Button extends React.Component {<br>  render() {<br>    return (<br>      &lt;Consumer&gt;<br>        {context =&gt; &lt;button&gt;{context.state.something}&lt;/button&gt;}<br>      &lt;/Consumer&gt;<br>    )<br>  }<br>}</pre><p>You can also pass functions into a Provider value, and those functions will be used by the Consumer to update the context state:</p><pre>&lt;Provider value={{<br>  state: this.state,<br>  updateSomething: () =&gt; this.setState({something: &#39;ho!&#39;})<br>  {this.props.children}<br>&lt;/Provider&gt;</pre><pre>/* ... */<br>&lt;Consumer&gt;<br>  {(context) =&gt; (<br>    &lt;button onClick={context.updateSomething}&gt;{context.state.something}&lt;/button&gt;<br>  )}<br>&lt;/Consumer&gt;</pre><p>You can see this in action <a href="https://glitch.com/edit/#!/flavio-react-context-api-example?path=app/components/HelloWorld.jsx">in this Glitch</a>.</p><p>You can create multiple contexts, to make your state distributed across components, yet expose it and make it reachable by any component you want.</p><p>When using multiple files, you create the content in one file, and import it in all the places you use it:</p><pre>//context.js<br>import React from &#39;react&#39;<br>export default React.createContext()</pre><pre>//component1.js<br>import Context from &#39;./context&#39;<br>//... use Context.Provider</pre><pre>//component2.js<br>import Context from &#39;./context&#39;<br>//... use Context.Consumer</pre><h3>Higher order components</h3><p>You might be familiar with Higher Order Functions in JavaScript. Those are functions that accept functions as arguments, and/or return functions.</p><p>Two examples of those functions are Array.map() or Array.filter().</p><p>In React, we extend this concept to components, and so we have a <strong>Higher Order Component (HOC)</strong>when the component accepts a component as input and returns a component as its output.</p><p>In general, higher order components allow you to create code that’s composable and reusable, and also more encapsulated.</p><p>We can use a HOC to add methods or properties to the state of a component, or a Redux store for example.</p><p>You might want to use Higher Order Components when you want to enhance an existing component, operate on the state or props, or its rendered markup.</p><p>There is a convention of prepending a Higher Order Component with the with string (it&#39;s a convention, so it&#39;s not mandatory), so if you have a Button component, its HOC counterpart should be called withButton.</p><p>Let’s create one.</p><p>The simplest example ever of a HOC is one that simply returns the component unaltered:</p><pre>const <strong>withElement</strong> = Element =&gt; () =&gt; &lt;<strong>Element</strong> /&gt;</pre><p>Let’s make this a little bit more useful and add a property to that button, in addition to all the props it already came with, the color:</p><pre>const <strong>withColor</strong> = Element =&gt; props =&gt; &lt;<strong>Element</strong> {...props} <em>color</em>=&quot;red&quot; /&gt;</pre><p>We use this HOC in a component JSX:</p><pre>const Button = () =&gt; {<br>  return &lt;button&gt;test&lt;/button&gt;<br>}</pre><pre>const ColoredButton = withColor(Button)</pre><p>and we can finally render the ColoredButton component in our app JSX:</p><pre>function App() {<br>  return (<br>    &lt;div className=&quot;App&quot;&gt;<br>      &lt;h1&gt;Hello&lt;/h1&gt;<br>      &lt;ColoredButton /&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>This is a very simple example but hopefully you can get the gist of HOCs before applying those concepts to more complex scenarios.</p><h3>Render Props</h3><p>A common pattern used to share state between components is to use the children prop.</p><p>Inside a component JSX you can render {this.props.children} which automatically injects any JSX passed in the parent component as a children:</p><pre>class Parent extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = {<br>      /*...*/<br>    }<br>  }</pre><pre>  render() {<br>    return &lt;div&gt;{this.props.children}&lt;/div&gt;<br>  }<br>}</pre><pre>const Children1 = () =&gt; {}</pre><pre>const Children2 = () =&gt; {}</pre><pre>const App = () =&gt; (<br>  &lt;Parent&gt;<br>    &lt;Children1 /&gt;<br>    &lt;Children2 /&gt;<br>  &lt;/Parent&gt;<br>)</pre><p>However, there is a problem here: the state of the parent component cannot be accessed from the children.</p><p>To be able to share the state, you need to use a render prop component, and instead of passing components as children of the parent component, you pass a function which you then execute in {this.props.children()}. The function can accept arguments:</p><pre>class Parent extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { name: &#39;Flavio&#39; }<br>  }</pre><pre>  render() {<br>    return &lt;div&gt;{this.props.children(this.state.name)}&lt;/div&gt;<br>  }<br>}</pre><pre>const Children1 = props =&gt; {<br>  return &lt;p&gt;{props.name}&lt;/p&gt;<br>}</pre><pre>const App = () =&gt; &lt;Parent&gt;{name =&gt; &lt;Children1 name={name} /&gt;}&lt;/Parent&gt;</pre><p>Instead of using the children prop, which has a very specific meaning, you can use any prop, and so you can use this pattern multiple times on the same component:</p><pre>class Parent extends React.Component {<br>  constructor(props) {<br>    super(props)<br>    this.state = { name: &#39;Flavio&#39;, age: 35 }<br>  }</pre><pre>  render() {<br>    return (<br>      &lt;div&gt;<br>        &lt;p&gt;Test&lt;/p&gt;<br>        {this.props.someprop1(this.state.name)}<br>        {this.props.someprop2(this.state.age)}<br>      &lt;/div&gt;<br>    )<br>  }<br>}</pre><pre>const Children1 = props =&gt; {<br>  return &lt;p&gt;{props.name}&lt;/p&gt;<br>}</pre><pre>const Children2 = props =&gt; {<br>  return &lt;p&gt;{props.age}&lt;/p&gt;<br>}</pre><pre>const App = () =&gt; (<br>  &lt;Parent<br>    someprop1={name =&gt; &lt;Children1 name={name} /&gt;}<br>    someprop2={age =&gt; &lt;Children2 age={age} /&gt;}<br>  /&gt;<br>)</pre><pre>ReactDOM.render(&lt;App /&gt;, document.getElementById(&#39;app&#39;))</pre><h3>Hooks</h3><p>Hooks is a feature that will be introduced in React 16.7, and is going to change how we write React apps in the future.</p><p>Before Hooks appeared, some key things in components were only possible using class components: having their own state, and using lifecycle events. Function components, lighter and more flexible, were limited in functionality.</p><p><strong>Hooks allow function components to have state and to respond to lifecycle events</strong> too, and kind of make class components obsolete. They also allow function components to have a good way to handle events.</p><h4>Access state</h4><p>Using the useState() API, you can create a new state variable, and have a way to alter it. useState() accepts the initial value of the state item and returns an array containing the state variable, and the function you call to alter the state. Since it returns an array we use <a href="https://flaviocopes.com/es6/#destructuring-assignments">array destructuring</a> to access each individual item, like this: const [count, setCount] = useState(0)</p><p>Here’s a practical example:</p><pre>import { useState } from &#39;react&#39;</pre><pre>const Counter = () =&gt; {<br>  const [count, setCount] = useState(0)</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;p&gt;You clicked {count} times&lt;/p&gt;<br>      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;Click me&lt;/button&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>ReactDOM.render(&lt;Counter /&gt;, document.getElementById(&#39;app&#39;))</pre><p>You can add as many useState() calls you want, to create as many state variables as you want. Just make sure you call it in the top level of a component (not in an if or in any other block).</p><p><a href="https://codepen.io/flaviocopes/pen/maVPKa">Example on Codepen</a></p><h4>Access lifecycle hooks</h4><p>Another very important feature of Hooks is allowing function components to have access to the lifecycle hooks.</p><p>Using class components you can register a function on the componentDidMount, componentWillUnmount and componentDidUpdate events, and those will serve many use cases, from variables initialization to API calls to cleanup.</p><p>Hooks provide the useEffect() API. The call accepts a function as argument.</p><p>The function runs when the component is first rendered, and on every subsequent re-render/update. React first updates the DOM, then calls any function passed to useEffect(). All without blocking the UI rendering even on blocking code, unlike the old componentDidMount and componentDidUpdate, which makes our apps feel faster.</p><p>Example:</p><pre>const { useEffect, useState } = React</pre><pre>const CounterWithNameAndSideEffect = () =&gt; {<br>  const [count, setCount] = useState(0)<br>  const [name, setName] = useState(&#39;Flavio&#39;)</pre><pre>  useEffect(() =&gt; {<br>    console.log(`Hi ${name} you clicked ${count} times`)<br>  })</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;p&gt;<br>        Hi {name} you clicked {count} times<br>      &lt;/p&gt;<br>      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;Click me&lt;/button&gt;<br>      &lt;button onClick={() =&gt; setName(name === &#39;Flavio&#39; ? &#39;Roger&#39; : &#39;Flavio&#39;)}&gt;<br>        Change name<br>      &lt;/button&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>ReactDOM.render(<br>  &lt;CounterWithNameAndSideEffect /&gt;,<br>  document.getElementById(&#39;app&#39;)<br>)</pre><p>The same componentWillUnmount job can be achieved by optionally <strong>returning</strong> a function from our useEffect() parameter:</p><pre>useEffect(() =&gt; {<br>  console.log(`Hi ${name} you clicked ${count} times`)<br>  return () =&gt; {<br>    console.log(`Unmounted`)<br>  }<br>})</pre><p>useEffect() can be called multiple times, which is nice to separate unrelated logic (something that plagues the class component lifecycle events).</p><p>Since the useEffect() functions are run on every subsequent re-render/update, we can tell React to skip a run, for performance purposes, by adding a second parameter which is an array that contains a list of state variables to watch for. React will only re-run the side effect if one of the items in this array changes.</p><pre>useEffect(<br>  () =&gt; {<br>    console.log(`Hi ${name} you clicked ${count} times`)<br>  },<br>  [name, count]<br>)</pre><p>Similarly you can tell React to only execute the side effect once (at mount time), by passing an empty array:</p><pre>useEffect(() =&gt; {<br>  console.log(`Component mounted`)<br>}, [])</pre><p>useEffect() is great for adding logs, accessing 3rd party APIs and much more.</p><p><a href="https://codepen.io/flaviocopes/pen/WLrxXp">Example on Codepen</a></p><h4>Handle events in function components</h4><p>Before hooks, you either used class components, or you passed an event handler using props.</p><p>Now we can use the useCallback() built-in API:</p><pre>const Button = () =&gt; {<br>  const handleClick = useCallback(() =&gt; {<br>    //...do something<br>  })<br>  return &lt;button onClick={handleClick} /&gt;<br>}</pre><p>Any parameter used inside the function must be passed through a second parameter to useCallback(), in an array:</p><pre>const Button = () =&gt; {<br>  let name = &#39;&#39; //... add logic<br>  const handleClick = useCallback(<br>    () =&gt; {<br>      //...do something<br>    },<br>    [name]<br>  )<br>  return &lt;button onClick={handleClick} /&gt;<br>}</pre><h4>Enable cross-component communication using custom hooks</h4><p>The ability to write your own hooks is the feature that is going to significantly alter how you write React apps in the future.</p><p>Using custom hooks you have one more way to share state and logic between components, adding a significant improvement to the patterns of render props and higher order components. Which are still great, but now with custom hooks have less relevance in many use cases.</p><p>How do you create a custom hook?</p><p>A hook is just a function that conventionally starts with use. It can accept an arbitrary number of arguments, and return anything it wants.</p><p>Examples:</p><pre>const useGetData() {<br>  //...<br>  return data<br>}</pre><p>or</p><pre>const useGetUser(username) {<br>  //...const user = fetch(...)<br>  //...const userData = ...<br>  return [user, userData]<br>}</pre><p>In your own components, you can use the hook like this:</p><pre>const MyComponent = () =&gt; {<br>  const data = useGetData()<br>  const [user, userData] = useGetUser(&#39;flavio&#39;)<br>  //...<br>}</pre><p>When exactly to add hooks instead of regular functions should be determined on a use case basis, and only experience will tell.</p><h3>Code splitting</h3><p>Modern JavaScript applications can be quite huge in terms of bundle size. You don’t want your users to have to download a 1MB package of JavaScript (your code and the libraries you use) just to load the first page, right? But this is what happens by default when you ship a modern Web App built with Webpack bundling.</p><p>That bundle will contain code that might never run because the user only stops on the login page and never sees the rest of your app.</p><p>Code splitting is the practice of only loading the JavaScript you need the moment when you need it.</p><p>This improves:</p><ul><li>the performance of your app</li><li>the impact on memory, and so battery usage on mobile devices</li><li>the downloaded KiloBytes (or MegaBytes) size</li></ul><p>React 16.6.0, released in October 2018, introduced a way of performing code splitting that should take the place of every previously used tool or library: <strong>React.lazy</strong> and <strong>Suspense</strong>.</p><p>React.lazy and Suspense form the perfect way to lazily load a dependency and only load it when needed.</p><p>Let’s start with React.lazy. You use it to import any component:</p><pre>import React from &#39;react&#39;</pre><pre>const TodoList = React.lazy(() =&gt; import(&#39;./TodoList&#39;))</pre><pre>export default () =&gt; {<br>  return (<br>    &lt;div&gt;<br>      &lt;TodoList /&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>the TodoList component will be dynamically added to the output as soon as it’s available. Webpack will create a separate bundle for it, and will take care of loading it when necessary.</p><p>Suspense is a component that you can use to wrap any lazily loaded component:</p><pre>import React from &#39;react&#39;</pre><pre>const TodoList = React.lazy(() =&gt; import(&#39;./TodoList&#39;))</pre><pre>export default () =&gt; {<br>  return (<br>    &lt;div&gt;<br>      &lt;React.Suspense&gt;<br>        &lt;TodoList /&gt;<br>      &lt;/React.Suspense&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>It takes care of handling the output while the lazy loaded component is fetched and rendered.</p><p>Use its fallback prop to output some JSX or a component output:</p><pre>...<br>      &lt;React.Suspense fallback={&lt;p&gt;Please wait&lt;/p&gt;}&gt;<br>        &lt;TodoList /&gt;<br>      &lt;/React.Suspense&gt;<br>...</pre><p>All this plays well with React Router:</p><pre>import React from &#39;react&#39;<br>import { BrowserRouter as Router, Route, Switch } from &#39;react-router-dom&#39;</pre><pre>const TodoList = React.lazy(() =&gt; import(&#39;./routes/TodoList&#39;))<br>const NewTodo = React.lazy(() =&gt; import(&#39;./routes/NewTodo&#39;))</pre><pre>const App = () =&gt; (<br>  &lt;Router&gt;<br>    &lt;React.Suspense fallback={&lt;p&gt;Please wait&lt;/p&gt;}&gt;<br>      &lt;Switch&gt;<br>        &lt;Route exact path=&quot;/&quot; component={TodoList} /&gt;<br>        &lt;Route path=&quot;/new&quot; component={NewTodo} /&gt;<br>      &lt;/Switch&gt;<br>    &lt;/React.Suspense&gt;<br>  &lt;/Router&gt;<br>)</pre><h3>SECTION 4: PRACTICAL EXAMPLES</h3><p>2 very simple applications to explain some of the concepts introduced so far.</p><h3>A very simple example of building a counter in React</h3><p>In this short example we’ll build a very simple example of a counter in React, applying many of the concepts and theory outlined before.</p><p>Let’s use Codepen for this. We start by forking the <a href="https://codepen.io/flaviocopes/pen/VqeaxB">React template pen</a>.</p><blockquote><em>In Codepen we don’t need to import React and ReactDOM as they are already added in the scope.</em></blockquote><p>We show the count in a div, and we add a few buttons to increment this count:</p><pre>const Button = ({ increment }) =&gt; {<br>  return &lt;button&gt;+{increment}&lt;/button&gt;<br>}</pre><pre>const App = () =&gt; {<br>  let count = 0</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;Button increment={1} /&gt;<br>      &lt;Button increment={10} /&gt;<br>      &lt;Button increment={100} /&gt;<br>      &lt;Button increment={1000} /&gt;<br>      &lt;span&gt;{count}&lt;/span&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>ReactDOM.render(&lt;App /&gt;, document.getElementById(&#39;app&#39;))</pre><p>Let’s add the functionality that lets us change the count by clicking the buttons, by adding a onClickFunction prop:</p><pre>const Button = ({ increment, onClickFunction }) =&gt; {<br>  const handleClick = () =&gt; {<br>    onClickFunction(increment)<br>  }<br>  return &lt;button onClick={handleClick}&gt;+{increment}&lt;/button&gt;<br>}</pre><pre>const App = () =&gt; {<br>  let count = 0</pre><pre>  const incrementCount = increment =&gt; {<br>    //TODO<br>  }</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;Button increment={1} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={10} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={100} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={1000} onClickFunction={incrementCount} /&gt;<br>      &lt;span&gt;{count}&lt;/span&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>ReactDOM.render(&lt;App /&gt;, document.getElementById(&#39;app&#39;))</pre><p>Here, every Button element has 2 props: increment and onClickFunction. We create 4 different buttons, with 4 increment values: 1, 10 100, 1000.</p><p>When the button in the Button component is clicked, the incrementCount function is called.</p><p>This function must increment the local count. How can we do so? We can use hooks:</p><pre>const { useState } = React</pre><pre>const Button = ({ increment, onClickFunction }) =&gt; {<br>  const handleClick = () =&gt; {<br>    onClickFunction(increment)<br>  }<br>  return &lt;button onClick={handleClick}&gt;+{increment}&lt;/button&gt;<br>}</pre><pre>const App = () =&gt; {<br>  const [count, setCount] = useState(0)</pre><pre>  const incrementCount = increment =&gt; {<br>    setCount(count + increment)<br>  }</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;Button increment={1} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={10} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={100} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={1000} onClickFunction={incrementCount} /&gt;<br>      &lt;span&gt;{count}&lt;/span&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>ReactDOM.render(&lt;App /&gt;, document.getElementById(&#39;app&#39;))</pre><p>useState() initializes the count variable at 0 and provides us the setCount() method to update its value.</p><p>We use both in the incrementCount() method implementation, which calls setCount() updating the value to the existing value of count, plus the increment passed by each Button component.</p><p>The complete example code can be seen at <a href="https://codepen.io/flaviocopes/pen/QzEQPR">https://codepen.io/flaviocopes/pen/QzEQPR</a></p><h3>Fetch and display GitHub users information via API</h3><p>Very simple example of a form that accepts a GitHub username and once it receives a submit event, it asks the GitHub API for the user information, and prints them.</p><p>This code creates a reusable <strong>Card</strong> component. When you enter a name in the input field managed by the <strong>Form</strong> component, this name is <em>bound to its state</em>.</p><p>When <em>Add card</em> is pressed, the input form is cleared by clearing the userName state of the <strong>Form </strong>component.</p><p>The example uses, in addition to React, the <a href="https://flaviocopes.com/axios/">Axios</a> library. It’s a nice useful and lightweight library to handle network requests. Add it to the Pen settings in Codepen, or install it locally using npm install axios.</p><p>We start by creating the Card component, the one that will display our image and details as gathered from GitHub. It gets its data via props, using</p><ul><li>props.avatar_url the user avatar</li><li>props.name the user name</li><li>props.blog the user website URL</li></ul><pre>const Card = props =&gt; {<br>  return (<br>    &lt;div style={{ margin: &#39;1em&#39; }}&gt;<br>      &lt;img alt=&quot;avatar&quot; style={{ width: &#39;70px&#39; }} src={props.avatar_url} /&gt;<br>      &lt;div&gt;<br>        &lt;div style={{ fontWeight: &#39;bold&#39; }}&gt;{props.name}&lt;/div&gt;<br>        &lt;div&gt;{props.blog}&lt;/div&gt;<br>      &lt;/div&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>We create a list of those components, which will be passed by a parent component in the cards prop to CardList, which simply iterates on it using map() and outputs a list of cards:</p><pre>const CardList = props =&gt; (<br>  &lt;div&gt;<br>    {props.cards.map(card =&gt; (<br>      &lt;Card {...card} /&gt;<br>    ))}<br>  &lt;/div&gt;<br>)</pre><p>The parent component is App, which stores the cards array in its own state, managed using the useState() Hook:</p><pre>const App = () =&gt; {<br>  const [cards, setCards] = useState([])</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;CardList cards={cards} /&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>Cool! We must have a way now to ask GitHub for the details of a single username. We’ll do so using a Form component, where we manage our own state (username), and we ask GitHub for information about a user using their public APIs, via Axios:</p><pre>const Form = props =&gt; {<br>  const [username, setUsername] = useState(&#39;&#39;)</pre><pre>  handleSubmit = event =&gt; {<br>    event.preventDefault()</pre><pre>    axios.get(`https://api.github.com/users/${username}`).then(resp =&gt; {<br>      props.onSubmit(resp.data)<br>      setUsername(&#39;&#39;)<br>    })<br>  }</pre><pre>  return (<br>    &lt;form onSubmit={handleSubmit}&gt;<br>      &lt;input<br>        type=&quot;text&quot;<br>        value={username}<br>        onChange={event =&gt; setUsername(event.target.value)}<br>        placeholder=&quot;GitHub username&quot;<br>        required<br>      /&gt;<br>      &lt;button type=&quot;submit&quot;&gt;Add card&lt;/button&gt;<br>    &lt;/form&gt;<br>  )<br>}</pre><p>When the form is submitted we call the handleSubmit event, and after the network call we call props.onSubmit passing the parent (App) the data we got from GitHub.</p><p>We add it to App, passing a method to add a new card to the list of cards, addNewCard, as its onSubmit prop:</p><pre>const App = () =&gt; {<br>  const [cards, setCards] = useState([])</pre><pre>  addNewCard = cardInfo =&gt; {<br>    setCards(cards.concat(cardInfo))<br>  }</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;Form onSubmit={addNewCard} /&gt;<br>      &lt;CardList cards={cards} /&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>Finally we render the app:</p><pre>ReactDOM.render(&lt;App /&gt;, document.getElementById(&#39;app&#39;))</pre><p>Here is the full source code of our little React app:</p><pre>const { useState } = React</pre><pre>const Card = props =&gt; {<br>  return (<br>    &lt;div style={{ margin: &#39;1em&#39; }}&gt;<br>      &lt;img alt=&quot;avatar&quot; style={{ width: &#39;70px&#39; }} src={props.avatar_url} /&gt;<br>      &lt;div&gt;<br>        &lt;div style={{ fontWeight: &#39;bold&#39; }}&gt;{props.name}&lt;/div&gt;<br>        &lt;div&gt;{props.blog}&lt;/div&gt;<br>      &lt;/div&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>const CardList = props =&gt; &lt;div&gt;{props.cards.map(card =&gt; &lt;Card {...card} /&gt;)}&lt;/div&gt;</pre><pre>const Form = props =&gt; {<br>  const [username, setUsername] = useState(&#39;&#39;)</pre><pre>  handleSubmit = event =&gt; {<br>    event.preventDefault()</pre><pre>    axios<br>      .get(`https://api.github.com/users/${username}`)<br>      .then(resp =&gt; {<br>        props.onSubmit(resp.data)<br>        setUsername(&#39;&#39;)<br>      })<br>  }</pre><pre>  return (<br>    &lt;form onSubmit={handleSubmit}&gt;<br>      &lt;input<br>        type=&quot;text&quot;<br>        value={username}<br>        onChange={event =&gt; setUsername(event.target.value)}<br>        placeholder=&quot;GitHub username&quot;<br>        required<br>      /&gt;<br>      &lt;button type=&quot;submit&quot;&gt;Add card&lt;/button&gt;<br>    &lt;/form&gt;<br>  )<br>}</pre><pre>const App = () =&gt; {<br>  const [cards, setCards] = useState([])</pre><pre>  addNewCard = cardInfo =&gt; {<br>    setCards(cards.concat(cardInfo))<br>  }</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;Form onSubmit={addNewCard} /&gt;<br>      &lt;CardList cards={cards} /&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>ReactDOM.render(&lt;App /&gt;, document.getElementById(&#39;app&#39;))</pre><p>This is the final result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/677/1*T_xooVI_KPH6fv2lpXekNw.png" /></figure><p>Check it out on Codepen at <a href="https://codepen.io/flaviocopes/pen/oJLyeY">https://codepen.io/flaviocopes/pen/oJLyeY</a></p><h3>SECTION 5: STYLING</h3><h3>CSS in React</h3><p>Using React you have various ways to add styling to your components.</p><h4>Using classes and CSS</h4><p>The first and most simple is to use classes, and use a normal CSS file to target those classes:</p><pre>const Button = () =&gt; {<br>  return &lt;button className=&quot;button&quot;&gt;A button&lt;/button&gt;<br>}</pre><pre>.button {<br>  background-color: yellow;<br>}</pre><p>You can import the stylesheet using an import statement, like this:</p><pre>import &#39;./style.css&#39;</pre><p>and <a href="https://flaviocopes.com/webpack/">Webpack</a> will take care of adding the CSS property to the bundle.</p><h4>Using the style attribute</h4><p>A second method is to use the style attribute attached to a JSX element. Using this approach you don&#39;t need a separate CSS file.</p><pre>const Button = () =&gt; {<br>  return &lt;button style={{ backgroundColor: &#39;yellow&#39; }}&gt;A button&lt;/button&gt;<br>}</pre><p>CSS is defined in a slightly different way now. First, notice the double curly brackets: it’s because style accepts an object. We pass in a JavaScript object, which is defined in curly braces. We could also do this:</p><pre>const buttonStyle = { backgroundColor: &#39;yellow&#39; }<br>const Button = () =&gt; {<br>  return &lt;button style={buttonStyle}&gt;A button&lt;/button&gt;<br>}</pre><p>When using create-react-app, those styles are autoprefixed by default thanks to its use of <a href="https://github.com/postcss/autoprefixer">Autoprefixer</a>.</p><p>Also, the style now is camelCased instead of using dashes. Every time a CSS property has a dash, remove it and start the next word capitalized.</p><p>Styles have the benefit of being local to the component, and they cannot leak to other components in other parts of the app, something that using classes and an external CSS file can’t provide.</p><h4>Using CSS Modules</h4><p><strong>CSS Modules</strong> seem to be a perfect spot in the middle: you use classes, but CSS is scoped to the component, which means that any styling you add cannot be applied to other components without your permission. And yet your styles are defined in a separate CSS file, which is easier to maintain than CSS in JavaScript (and you can use your good old CSS property names).</p><p>Start by creating a CSS file that ends with .module.css, for example Button.module.css. A great choice is to give it the same name as the component you are going to style</p><p>Add your CSS here, then import it inside the component file you want to style:</p><pre>import style from &#39;./Button.module.css&#39;</pre><p>now you can use it in your JSX:</p><pre>const Button = () =&gt; {<br>  return &lt;button className={style.content}&gt;A button&lt;/button&gt;<br>}</pre><p>That’s it! In the resulting markup, React will generate a specific, unique class for each rendered component, and assign the CSS to that class, so that the CSS is not affecting other markup.</p><h3>SASS in React</h3><p>When you build a React application using <a href="https://flaviocopes.com/react-create-react-app/">create-react-app</a>, you have many options at your disposal when it comes to styling.</p><blockquote><em>Of course, if not using </em><em>create-react-app, you have all the choices in the world, but we limit the discussion to the </em><em>create-react-app-provided options.</em></blockquote><p>You can style using plain classes and CSS files, using the style attribute or CSS Modules, to start with.</p><p>SASS/SCSS is a very popular option, a much loved one by many developers.</p><p>You can use it without any configuration at all, starting with create-react-app 2.</p><p>All you need is a .sass or .scss file, and you just import it in a component:</p><pre>import &#39;./styles.scss&#39;</pre><p>You can see an example of it working at <a href="https://codesandbox.io/s/18qq31rp3">https://codesandbox.io/s/18qq31rp3</a>.</p><h3>Styled Components</h3><p>Styled Components are one of the new ways to use CSS in modern JavaScript. It is the meant to be a successor of CSS Modules, a way to write CSS that’s scoped to a single component, and not leak to any other element in the page</p><h4>A brief history</h4><p>Once upon a time, the Web was really simple and CSS didn’t even exist. We laid out pages using <strong>tables </strong>and frames. Good times.</p><p>Then <strong>CSS</strong> came to life, and after some time it became clear that frameworks could greatly help especially in building grids and layouts, Bootstrap and Foundation playing a big part in this.</p><p>Preprocessors like <strong>SASS</strong> and others helped a lot to slow down the adoption of frameworks, and to better organize the code, conventions like <strong>BEM</strong> and <strong>SMACSS</strong> grew in use, especially within teams.</p><p>Conventions are not a solution to everything, and they are complex to remember, so in the last few years with the increasing adoption of <a href="https://flaviocopes.com/javascript/">JavaScript</a> and build processes in every frontend project, CSS found its way into JavaScript (<strong>CSS-in-JS</strong>).</p><p>New tools explored new ways of doing CSS-in-JS and a few succeeded with increasing popularity:</p><ul><li>React Style</li><li>jsxstyle</li><li>Radium</li></ul><p>and more.</p><h4>Introducing Styled Components</h4><p>One of the most popular of these tools is <strong>Styled Components</strong>.</p><p>It is the meant to be a successor to <strong>CSS Modules</strong>, a way to write CSS that’s scoped to a single component, and not leak to any other element in the page.</p><p>(more on CSS modules <a href="https://css-tricks.com/css-modules-part-1-need/">here</a> and <a href="https://glenmaddern.com/articles/css-modules">here</a>)</p><p>Styled Components allow you to write plain CSS in your components without worrying about class name collisions.</p><h4>Installation</h4><p>Simply install styled-components using <a href="https://flaviocopes.com/npm/">npm</a> or <a href="https://flaviocopes.com/yarn/">yarn</a>:</p><pre>npm install styled-components<br>yarn add styled-components</pre><p>That’s it! Now all you have to do is to add this import:</p><pre>import styled from &#39;styled-components&#39;</pre><h4>Your first styled component</h4><p>With the styled object imported, you can now start creating Styled Components. Here&#39;s the first one:</p><pre>const Button = styled.button`<br>  font-size: 1.5em;<br>  background-color: black;<br>  color: white;<br>`</pre><p>Button is now a React Component in all its greatness.</p><p>We created it using a function of the styled object, called button in this case, and passing some CSS properties in a <a href="https://flaviocopes.com/ecmascript/#template-literals">template literal</a>.</p><p>Now this component can be rendered in our container using the normal React syntax:</p><pre>render(&lt;Button /&gt;)</pre><p>Styled Components offer other functions you can use to create other components, not just button, like section, h1, input and many others.</p><p>The syntax used, with the backtick, might be weird at first, but it’s called <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">Tagged Templates</a>, it’s plain JavaScript and it’s a way to pass an argument to the function.</p><h4>Using props to customize components</h4><p>When you pass some props to a Styled Component, it will pass them down to the <a href="https://flaviocopes.com/dom/">DOM</a> node mounted.</p><p>For example here’s how we pass the placeholder and type props to an input component:</p><pre>const Input = styled.input`<br>  //...<br>`</pre><pre>render(<br>  &lt;div&gt;<br>    &lt;Input placeholder=&quot;...&quot; type=&quot;text&quot; /&gt;<br>  &lt;/div&gt;<br>)</pre><p>This will do just what you think, inserting those props as HTML attributes.</p><p>Props instead of just being blindly passed down to the <a href="https://flaviocopes.com/dom/">DOM</a> can also be used to customize a component based on the prop value. Here’s an example:</p><pre>const Button = styled.button`<br>  background: ${props =&gt; (props.primary ? &#39;black&#39; : &#39;white&#39;)};<br>  color: ${props =&gt; (props.primary ? &#39;white&#39; : &#39;black&#39;)};<br>`</pre><pre>render(<br>  &lt;div&gt;<br>    &lt;Button&gt;A normal button&lt;/Button&gt;<br>    &lt;Button&gt;A normal button&lt;/Button&gt;<br>    &lt;Button primary&gt;The primary button&lt;/Button&gt;<br>  &lt;/div&gt;<br>)</pre><p>Setting the primary prop changes the color of the button.</p><h4>Extending an existing Styled Component</h4><p>If you have one component and you want to create a similar one, just styled slightly differently, you can use extend:</p><pre>const Button = styled.button`<br>  color: black;<br>  //...<br>`</pre><pre>const WhiteButton = Button.extend`<br>  color: white;<br>`</pre><pre>render(<br>  &lt;div&gt;<br>    &lt;Button&gt;A black button, like all buttons&lt;/Button&gt;<br>    &lt;WhiteButton&gt;A white button&lt;/WhiteButton&gt;<br>  &lt;/div&gt;<br>)</pre><h4>It’s Regular CSS</h4><p>In Styled Components, you can use the CSS you already know and love. It’s just plain CSS. It is not pseudo CSS nor inline CSS with its limitations.</p><p>You can use media queries, <a href="https://tabatkins.github.io/specs/css-nesting/">nesting</a> and anything else you might need.</p><h4>Using Vendor Prefixes</h4><p>Styled Components automatically add all the vendor prefixes needed, so you don’t need to worry about this problem.</p><h3>SECTION 6: TOOLING</h3><h3>Babel</h3><p>Babel is an awesome tool, and it’s been around for quite some time, but nowadays almost every JavaScript developer relies on it. This will continue, because Babel is now indispensable and has solved a big problem for everyone.</p><p>Which problem?</p><p>The problem that every Web Developer has surely had: a feature of JavaScript is available in the latest release of a browser, but not in the older versions. Or maybe Chrome or Firefox implement it, but Safari iOS and Edge do not.</p><p>For example, ES6 introduced the <strong>arrow function</strong>:</p><pre>[1, 2, 3].map((n) =&gt; n + 1)</pre><p>Which is now supported by all modern browsers. IE11 does not support it, nor Opera Mini (How do I know? By checking the <a href="http://kangax.github.io/compat-table/es6/#test-arrow_functions">ES6 Compatibility Table</a>).</p><p>So how should you deal with this problem? Should you move on and leave those customers with older/incompatible browsers behind, or should you write older JavaScript code to make all your users happy?</p><p>Enter Babel. Babel is a <strong>compiler</strong>: it takes code written in one standard, and it transpiles it to code written into another standard.</p><p>You can configure Babel to transpile modern ES2017 JavaScript into JavaScript ES5 syntax:</p><pre>[1, 2, 3].map(function(n) {<br>  return n + 1<br>})</pre><p>This must happen at build time, so you must setup a workflow that handles this for you. <a href="https://flaviocopes.com/webpack/">Webpack</a> is a common solution.</p><p>(P.S. if all this <em>ES</em> thing sounds confusing to you, see more about ES versions <a href="https://flaviocopes.com/ecmascript/">in the ECMAScript guide</a>)</p><h4>Installing Babel</h4><p>Babel is easily installed using <a href="https://flaviocopes.com/npm/">npm</a>, locally in a project:</p><pre>npm install --save-dev @babel/core @babel/cli</pre><p>Since npm now comes with <a href="https://flaviocopes.com/node/npx/">npx</a>, locally installed CLI packages can run by typing the command in the project folder:</p><p>So we can run Babel by just running</p><pre>npx babel script.js</pre><h4>An example Babel configuration</h4><p>Babel out of the box does not do anything useful, you need to configure it and add plugins.</p><blockquote><a href="https://babeljs.io/docs/en/plugins"><em>Here is a list of Babel plugins</em></a></blockquote><p>To solve the problem we talked about in the introduction (using arrow functions in every browser), we can run</p><pre>npm install --save-dev \<br>    @babel/plugin-transform-es2015-arrow-functions</pre><p>to download the package in the node_modules folder of our app, then we need to add</p><pre>{<br>  &quot;plugins&quot;: [&quot;transform-es2015-arrow-functions&quot;]<br>}</pre><p>to the .babelrc file present in the application root folder. If you don&#39;t have that file already, you just create a blank file, and put that content into it.</p><blockquote><em>TIP: If you have never seen a dot file (a file starting with a dot) it might be odd at first because that file might not appear in your file manager, as it’s a hidden file.</em></blockquote><p>Now if we have a script.js file with this content:</p><pre>var a = () =&gt; {};<br>var a = (b) =&gt; b;</pre><pre>const double = [1,2,3].map((num) =&gt; num * 2);<br>console.log(double); // [2,4,6]</pre><pre>var bob = {<br>  _name: &quot;Bob&quot;,<br>  _friends: [&quot;Sally&quot;, &quot;Tom&quot;],<br>  printFriends() {<br>    this._friends.forEach(f =&gt;<br>      console.log(this._name + &quot; knows &quot; + f));<br>  }<br>};<br>console.log(bob.printFriends());</pre><p>running babel script.js will output the following code:</p><pre>var a = function () {};var a = function (b) {<br>  return b;<br>};</pre><pre>const double = [1, 2, 3].map(function (num) {<br>  return num * 2;<br>});console.log(double); // [2,4,6]</pre><pre>var bob = {<br>  _name: &quot;Bob&quot;,<br>  _friends: [&quot;Sally&quot;, &quot;Tom&quot;],<br>  printFriends() {<br>    var _this = this;</pre><pre>    this._friends.forEach(function (f) {<br>      return console.log(_this._name + &quot; knows &quot; + f);<br>    });<br>  }<br>};<br>console.log(bob.printFriends());</pre><p>As you can see arrow functions have all been converted to JavaScript ES5 functions.</p><h4>Babel presets</h4><p>We just saw in the previous article how Babel can be configured to transpile specific JavaScript features.</p><p>You can add much more plugins, but you can’t add to the configuration features one by one, it’s not practical.</p><p>This is why Babel offers <strong>presets</strong>.</p><p>The most popular presets are env and react.</p><blockquote><em>Tip: Babel 7 deprecated (and removed) yearly presets like </em><em>preset-es2017, and stage presets. Use </em><em>@babel/preset-env instead.</em></blockquote><h4>env preset</h4><p>The env preset is very nice: you tell it which environments you want to support, and it does everything for you, <strong>supporting all modern JavaScript features</strong>.</p><p>E.g. “support the last 2 versions of every browser, but for Safari let’s support all versions since Safari 7”</p><pre>{<br>  &quot;presets&quot;: [<br>    [&quot;env&quot;, {<br>      &quot;targets&quot;: {<br>        &quot;browsers&quot;: [&quot;last 2 versions&quot;, &quot;safari &gt;= 7&quot;]<br>      }<br>    }]<br>  ]<br>}</pre><p>or “I don’t need browser support, just let me work with <a href="https://flaviocopes.com/node/">Node.js</a> 6.10”</p><pre>{<br>  &quot;presets&quot;: [<br>    [&quot;env&quot;, {<br>      &quot;targets&quot;: {<br>        &quot;node&quot;: &quot;6.10&quot;<br>      }<br>    }]<br>  ]<br>}</pre><h4>react preset</h4><p>The react preset is very convenient when writing React apps: adding preset-flow, syntax-jsx, transform-react-jsx, transform-react-display-name.</p><p>By including it, you are all ready to go developing React apps, with JSX transforms and Flow support.</p><h4>More info on presets</h4><p><a href="https://babeljs.io/docs/plugins/">https://babeljs.io/docs/plugins/</a></p><h4>Using Babel with webpack</h4><p>If you want to run modern JavaScript in the browser, Babel on its own is not enough, you also need to bundle the code. Webpack is the perfect tool for this.</p><p>Modern JS needs two different stages: a compile stage, and a runtime stage. This is because some ES6+ features need a polyfill or a runtime helper.</p><p>To install the Babel polyfill runtime functionality, run</p><pre>npm install @babel/polyfill \<br>            @babel/runtime \<br>            @babel/plugin-transform-runtime</pre><p>Now in your webpack.config.js file add:</p><pre>entry: [<br>  &#39;babel-polyfill&#39;,<br>  // your app scripts should be here<br>],</pre><pre>module: {<br>  loaders: [<br>    // Babel loader compiles ES2015 into ES5 for<br>    // complete cross-browser support<br>    {<br>      loader: &#39;babel-loader&#39;,<br>      test: /\.js$/,<br>      // only include files present in the `src` subdirectory<br>      include: [path.resolve(__dirname, &quot;src&quot;)],<br>      // exclude node_modules, equivalent to the above line<br>      exclude: /node_modules/,<br>      query: {<br>        // Use the default ES2015 preset<br>        // to include all ES2015 features<br>        presets: [&#39;es2015&#39;],<br>        plugins: [&#39;transform-runtime&#39;]<br>      }<br>    }<br>  ]<br>}</pre><p>By keeping the presets and plugins information inside the webpack.config.js file, we can avoid having a .babelrc file.</p><h3>Webpack</h3><p>Webpack is a tool that lets you compile JavaScript modules, also known as <strong>module bundler</strong>. Given a large number of files, it generates a single file (or a few files) that run your app.</p><p>It can perform many operations:</p><ul><li>helps you bundle your resources.</li><li>watches for changes and re-runs the tasks.</li><li>can run Babel transpilation to ES5, allowing you to use the latest JavaScript features without worrying about browser support.</li><li>can transpile CoffeeScript to JavaScript</li><li>can convert inline images to data URIs.</li><li>allows you to use require() for CSS files.</li><li>can run a development webserver.</li><li>can handle hot module replacement.</li><li>can split the output files into multiple files, to avoid having a huge js file to load in the first page hit.</li><li>can perform <a href="https://flaviocopes.com/javascript-glossary/#tree-shaking">tree shaking</a>.</li></ul><p>Webpack is not limited to be use on the frontend, it’s also useful in backend Node.js development as well.</p><p>Predecessors of webpack, and still widely used tools, include:</p><ul><li>Grunt</li><li>Broccoli</li><li>Gulp</li></ul><p>There are lots of similarities in what those and Webpack can do, but the main difference is that those are known as <strong>task runners</strong>, while webpack was born as a module bundler.</p><p>It’s a more focused tool: you specify an entry point to your app (it could even be an HTML file with script tags) and webpack analyzes the files and bundles all you need to run the app in a single JavaScript output file (or in more files if you use code splitting).</p><h4>Installing webpack</h4><p>Webpack can be installed globally or locally for each project.</p><h4>Global install</h4><p>Here’s how to install it globally with <a href="https://flaviocopes.com/yarn/">Yarn</a>:</p><pre>yarn global add webpack webpack-cli</pre><p>with <a href="https://flaviocopes.com/npm/">npm</a>:</p><pre>npm i -g webpack webpack-cli</pre><p>once this is done, you should be able to run</p><pre>webpack-cli</pre><h4>Local install</h4><p>Webpack can be installed locally as well. It’s the recommended setup, because webpack can be updated per-project, and you have less resistance to using the latest features just for a small project rather than updating all the projects you have that use webpack.</p><p>With <a href="https://flaviocopes.com/yarn/">Yarn</a>:</p><pre>yarn add webpack webpack-cli -D</pre><p>with <a href="https://flaviocopes.com/npm/">npm</a>:</p><pre>npm i webpack webpack-cli --save-dev</pre><p>Once this is done, add this to your package.json file:</p><pre>{<br>  //...<br>  &quot;scripts&quot;: {<br>    &quot;build&quot;: &quot;webpack&quot;<br>  }<br>}</pre><p>once this is done, you can run webpack by typing</p><pre>yarn build</pre><p>in the project root.</p><h4>Webpack configuration</h4><p>By default, webpack (starting from version 4) does not require any config if you respect these conventions:</p><ul><li>the <strong>entry point</strong> of your app is ./src/index.js</li><li>the output is put in ./dist/main.js.</li><li>Webpack works in production mode</li></ul><p>You can customize every little bit of webpack of course, when you need. The webpack configuration is stored in the webpack.config.js file, in the project root folder.</p><h4>The entry point</h4><p>By default the entry point is ./src/index.js This simple example uses the ./index.js file as a starting point:</p><pre>module.exports = {<br>  /*...*/<br>  entry: &#39;./index.js&#39;<br>  /*...*/<br>}</pre><h4>The output</h4><p>By default the output is generated in ./dist/main.js. This example puts the output bundle into app.js:</p><pre>module.exports = {<br>  /*...*/<br>  output: {<br>    path: path.resolve(__dirname, &#39;dist&#39;),<br>    filename: &#39;app.js&#39;<br>  }<br>  /*...*/<br>}</pre><h4>Loaders</h4><p>Using webpack allows you to use import or require statements in your JavaScript code to not just include other JavaScript, but any kind of file, for example CSS.</p><p>Webpack aims to handle all our dependencies, not just JavaScript, and loaders are one way to do that.</p><p>For example, in your code you can use:</p><pre>import &#39;style.css&#39;</pre><p>by using this loader configuration:</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      { test: /\.css$/, use: &#39;css-loader&#39; },<br>    }]<br>  }<br>  /*...*/<br>}</pre><p>The <a href="https://flaviocopes.com/javascript-regular-expressions/">regular expression</a> targets any CSS file.</p><p>A loader can have options:</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      {<br>        test: /\.css$/,<br>        use: [<br>          {<br>            loader: &#39;css-loader&#39;,<br>            options: {<br>              modules: true<br>            }<br>          }<br>        ]<br>      }<br>    ]<br>  }<br>  /*...*/<br>}</pre><p>You can require multiple loaders for each rule:</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      {<br>        test: /\.css$/,<br>        use:<br>          [<br>            &#39;style-loader&#39;,<br>            &#39;css-loader&#39;,<br>          ]<br>      }<br>    ]<br>  }<br>  /*...*/<br>}</pre><p>In this example, css-loader interprets the import &#39;style.css&#39; directive in the CSS. style-loader is then responsible for injecting that CSS in the DOM, using a &lt;style&gt; tag.</p><p>The order matters, and it’s reversed (the last is executed first).</p><p>What kind of loaders are there? Many! <a href="https://webpack.js.org/loaders/">You can find the full list here</a>.</p><p>A commonly used loader is Babel, which is used to transpile modern JavaScript to ES5 code:</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      {<br>        test: /\.js$/,<br>        exclude: /(node_modules|bower_components)/,<br>        use: {<br>          loader: &#39;babel-loader&#39;,<br>          options: {<br>            presets: [&#39;@babel/preset-env&#39;]<br>          }<br>        }<br>      }<br>    ]<br>  }<br>  /*...*/<br>}</pre><p>This example makes Babel preprocess all our React/JSX files:</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      {<br>        test: /\.(js|jsx)$/,<br>        exclude: /node_modules/,<br>        use: &#39;babel-loader&#39;<br>      }<br>    ]<br>  },<br>  resolve: {<br>    extensions: [<br>      &#39;.js&#39;,<br>      &#39;.jsx&#39;<br>    ]<br>  }<br>  /*...*/<br>}</pre><p><a href="https://webpack.js.org/loaders/babel-loader/">See the </a><a href="https://webpack.js.org/loaders/babel-loader/">babel-loader options here</a>.</p><h4>Plugins</h4><p>Plugins are like loaders, but on steroids. They can do things that loaders can’t do, and they are the main building block of webpack.</p><p>Take this example:</p><pre>module.exports = {<br>  /*...*/<br>  plugins: [<br>    new HTMLWebpackPlugin()<br>  ]<br>  /*...*/<br>}</pre><p>The HTMLWebpackPlugin plugin has the job of automatically creating an HTML file, adding the output JS bundle path, so the JavaScript is ready to be served.</p><p>There are <a href="https://webpack.js.org/plugins/">lots of plugins available</a>.</p><p>One useful plugin, CleanWebpackPlugin, can be used to clear the dist/ folder before creating any output, so you don&#39;t leave files around when you change the name of the output file:</p><pre>module.exports = {<br>  /*...*/<br>  plugins: [<br>    new CleanWebpackPlugin([&#39;dist&#39;]),<br>  ]<br>  /*...*/<br>}</pre><h4>The webpack mode</h4><p>This mode (introduced in webpack 4) sets the environment on which webpack works. It can be set to development or production (defaults to production, so you only set it when moving to development)</p><pre>module.exports = {<br>  entry: &#39;./index.js&#39;,<br>  mode: &#39;development&#39;,<br>  output: {<br>    path: path.resolve(__dirname, &#39;dist&#39;),<br>    filename: &#39;app.js&#39;<br>  }<br>}</pre><p>Development mode:</p><ul><li>builds very fast</li><li>is less optimized than production</li><li>does not remove comments</li><li>provides more detailed error messages and suggestions</li><li>provides a better debugging experience</li></ul><p>Production mode is slower to build, since it needs to generate a more optimized bundle. The resulting JavaScript file is smaller in size, as it removes many things that are not needed in production.</p><p>I made a sample app that just prints a console.log statement.</p><p>Here’s the production bundle:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JcR055dE_t--bItLNJ4Vsw.png" /></figure><p>Here’s the development bundle:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*akrQtM2aNG6BFin0nfXkpQ.png" /></figure><h4>Running webpack</h4><p>Webpack can be run from the command line manually if installed globally, but generally you write a script inside the package.json file, which is then run using npm or yarn.</p><p>For example this package.json scripts definition we used before:</p><pre>&quot;scripts&quot;: {<br>  &quot;build&quot;: &quot;webpack&quot;<br>}</pre><p>allows us to run webpack by running</p><pre>npm run build</pre><p>or</p><pre>yarn run build</pre><p>or simply</p><pre>yarn build</pre><h4>Watching changes</h4><p>Webpack can automatically rebuild the bundle when a change in your app happens, and keep listening for the next change.</p><p>Just add this script:</p><pre>&quot;scripts&quot;: {<br>  &quot;watch&quot;: &quot;webpack --watch&quot;<br>}</pre><p>and run</p><pre>npm run watch</pre><p>or</p><pre>yarn run watch</pre><p>or simply</p><pre>yarn watch</pre><p>One nice feature of the watch mode is that the bundle is only changed if the build has no errors. If there are errors, watch will keep listening for changes, and try to rebuild the bundle, but the current, working bundle is not affected by those problematic builds.</p><h4>Handling images</h4><p>Webpack allows us to use images in a very convenient way, using the <a href="https://webpack.js.org/loaders/file-loader/">file-loader</a> loader.</p><p>This simple configuration:</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      {<br>        test: /\.(png|svg|jpg|gif)$/,<br>        use: [<br>          &#39;file-loader&#39;<br>        ]<br>      }<br>    ]<br>  }<br>  /*...*/<br>}</pre><p>Allows you to import images in your JavaScript:</p><pre>import Icon from &#39;./icon.png&#39;</pre><pre>const img = new Image()<br>img.src = Icon<br>element.appendChild(img)</pre><p>(img is an HTMLImageElement. Check the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image">Image docs</a>)</p><p>file-loader can handle other asset types as well, like fonts, CSV files, xml, and more.</p><p>Another nice tool to work with images is the url-loader loader.</p><p>This example loads any PNG file smaller than 8KB as a <a href="https://flaviocopes.com/data-urls/">data URL</a>.</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      {<br>        test: /\.png$/,<br>        use: [<br>          {<br>            loader: &#39;url-loader&#39;,<br>            options: {<br>              limit: 8192<br>            }<br>          }<br>        ]<br>      }<br>    ]<br>  }<br>  /*...*/<br>}</pre><h4>Process your SASS code and transform it to CSS</h4><p>Using sass-loader, css-loader and style-loader:</p><pre>module.exports = {<br>  /*...*/<br>  module: {<br>    rules: [<br>      {<br>        test: /\.scss$/,<br>        use: [<br>          &#39;style-loader&#39;,<br>          &#39;css-loader&#39;,<br>          &#39;sass-loader&#39;<br>        ]<br>      }<br>    ]<br>  }<br>  /*...*/<br>}</pre><h4>Generate Source Maps</h4><p>Since webpack bundles the code, Source Maps are mandatory to get a reference to the original file that raised an error, for example.</p><p>You tell webpack to generate source maps using the devtool property of the configuration:</p><pre>module.exports = {<br>  /*...*/<br>  devtool: &#39;inline-source-map&#39;,<br>  /*...*/<br>}</pre><p>devtool has <a href="https://webpack.js.org/configuration/devtool/">many possible values</a>, the most used probably are:</p><ul><li>none: adds no source maps</li><li>source-map: ideal for production, provides a separate source map that can be minimized, and adds a reference into the bundle, so development tools know that the source map is available. Of course you should configure the server to avoid shipping this, and just use it for debugging purposes</li><li>inline-source-map: ideal for development, inlines the source map as a Data URL</li></ul><h3>SECTION 7: TESTING</h3><h3>Jest</h3><p>Jest is a library for testing JavaScript code.</p><p>It’s an open source project maintained by Facebook, and it’s especially well suited for React code testing, although not limited to that: it can test any JavaScript code. Its strengths are:</p><ul><li>it’s fast</li><li>it can perform <strong>snapshot testing</strong></li><li>it’s opinionated, and provides everything out of the box without requiring you to make choices</li></ul><p>Jest is a tool very similar to Mocha, although they have differences:</p><ul><li>Mocha is less opinionated, while Jest has a certain set of conventions</li><li>Mocha requires more configuration, while Jest works usually out of the box, thanks to being opinionated</li><li>Mocha is older and more established, with more tooling integrations</li></ul><p>In my opinion the biggest feature of Jest is it’s an out of the box solution that works without having to interact with other testing libraries to perform its job.</p><h4>Installation</h4><p>Jest is automatically installed in create-react-app, so if you use that, you don’t need to install Jest.</p><p>Jest can be installed in any other project using <a href="https://flaviocopes.com/yarn/">Yarn</a>:</p><pre>yarn add --dev jest</pre><p>or <a href="https://flaviocopes.com/npm/">npm</a>:</p><pre>npm install --save-dev jest</pre><p>notice how we instruct both to put Jest in the devDependencies part of the package.json file, so that it will only be installed in the development environment and not in production.</p><p>Add this line to the scripts part of your package.json file:</p><pre>{<br>  &quot;scripts&quot;: {<br>    &quot;test&quot;: &quot;jest&quot;<br>  }<br>}</pre><p>so that tests can be run using yarn test or npm run test.</p><p>Alternatively, you can install Jest globally:</p><pre>yarn global add jest</pre><p>and run all your tests using the jest command line tool.</p><h4>Create the first Jest test</h4><p>Projects created with create-react-app have Jest installed and preconfigured out of the box, but adding Jest to any project is as easy as typing</p><pre>yarn add --dev jest</pre><p>Add to your package.json this line:</p><pre>{<br>  &quot;scripts&quot;: {<br>    &quot;test&quot;: &quot;jest&quot;<br>  }<br>}</pre><p>and run your tests by executing yarn test in your shell.</p><p>Now, you don’t have any tests here, so nothing is going to be executed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/938/0*sxyJMy2T9cLnByPB.png" /></figure><p>Let’s create the first test. Open a math.js file and type a couple functions that we’ll later test:</p><pre>const sum = (a, b) =&gt; a + b<br>const mul = (a, b) =&gt; a * b<br>const sub = (a, b) =&gt; a - b<br>const div = (a, b) =&gt; a / b</pre><pre>export default { sum, mul, sub, div }</pre><p>Now create a math.test.js file, in the same folder, and there we’ll use Jest to test the functions defined in math.js:</p><pre>const { sum, mul, sub, div } = require(&#39;./math&#39;)</pre><pre>test(&#39;Adding 1 + 1 equals 2&#39;, () =&gt; {<br>  expect(sum(1, 1)).toBe(2)<br>})<br>test(&#39;Multiplying 1 * 1 equals 1&#39;, () =&gt; {<br>  expect(mul(1, 1)).toBe(1)<br>})<br>test(&#39;Subtracting 1 - 1 equals 0&#39;, () =&gt; {<br>  expect(sub(1, 1)).toBe(0)<br>})<br>test(&#39;Dividing 1 / 1 equals 1&#39;, () =&gt; {<br>  expect(div(1, 1)).toBe(1)<br>})</pre><p>Running yarn test results in Jest being run on all the test files it finds, and returning us the end result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/0*0MUKuOkEMX2c6MR_.png" /></figure><h4>Run Jest with VS Code</h4><p>Visual Studio Code is a great editor for JavaScript development. The <a href="https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest">Jest extension</a> offers a top notch integration for our tests.</p><p>Once you install it, it will automatically detect if you have installed Jest in your devDependencies and run the tests. You can also invoke the tests manually by selecting the <strong>Jest: Start Runner</strong> command. It will run the tests and stay in watch mode to re-run them whenever you change one of the files that have a test (or a test file):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/883/0*B15Cmsjiag4UFKuD.png" /></figure><h4>Matchers</h4><p>In the previous article I used toBe() as the only <strong>matcher</strong>:</p><pre>test(&#39;Adding 1 + 1 equals 2&#39;, () =&gt; {<br>  expect(sum(1, 1)).toBe(2)<br>})</pre><p>A matcher is a method that lets you test values.</p><p>Most commonly used matchers, comparing the value of the result of expect() with the value passed in as argument, are:</p><ul><li>toBe compares strict equality, using ===</li><li>toEqual compares the values of two variables. If it’s an object or array, it checks the equality of all the properties or elements</li><li>toBeNull is true when passing a null value</li><li>toBeDefined is true when passing a defined value (opposite to the above)</li><li>toBeUndefined is true when passing an undefined value</li><li>toBeCloseTo is used to compare floating values, avoiding rounding errors</li><li>toBeTruthy true if the value is considered true (like an if does)</li><li>toBeFalsy true if the value is considered false (like an if does)</li><li>toBeGreaterThan true if the result of expect() is higher than the argument</li><li>toBeGreaterThanOrEqual true if the result of expect() is equal to the argument, or higher than the argument</li><li>toBeLessThan true if the result of expect() is lower than the argument</li><li>toBeLessThanOrEqual true if the result of expect() is equal to the argument, or lower than the argument</li><li>toMatch is used to compare strings with <a href="https://flaviocopes.com/javascript-regular-expressions/">regular expression</a> pattern matching</li><li>toContain is used in arrays, true if the expected array contains the argument in its elements set</li><li>toHaveLength(number): checks the length of an array</li><li>toHaveProperty(key, value): checks if an object has a property, and optionally checks its value</li><li>toThrow checks if a function you pass throws an exception (in general) or a specific exception</li><li>toBeInstanceOf(): checks if an object is an instance of a class</li></ul><p>All those matchers can be negated using .not. inside the statement, for example:</p><pre>test(&#39;Adding 1 + 1 does not equal 3&#39;, () =&gt; {<br>  expect(sum(1, 1)).not.toBe(3)<br>})</pre><p>For use with promises, you can use .resolves and .rejects:</p><pre>expect(Promise.resolve(&#39;lemon&#39;)).resolves.toBe(&#39;lemon&#39;)</pre><pre>expect(Promise.reject(new Error(&#39;octopus&#39;))).rejects.toThrow(&#39;octopus&#39;)</pre><h4>Setup</h4><p>Before running your tests you will want to perform some initialization.</p><p>To do something once before all the tests run, use the beforeAll() function:</p><pre>beforeAll(() =&gt; {<br>  //do something<br>})</pre><p>To perform something before each test runs, use beforeEach():</p><pre>beforeEach(() =&gt; {<br>  //do something<br>})</pre><h4>Teardown</h4><p>Just as you can do with setup, you can also perform something after each test runs:</p><pre>afterEach(() =&gt; {<br>  //do something<br>})</pre><p>and after all tests end:</p><pre>afterAll(() =&gt; {<br>  //do something<br>})</pre><h4>Group tests using describe()</h4><p>You can create groups of tests, in a single file, that isolate the setup and teardown functions:</p><pre>describe(&#39;first set&#39;, () =&gt; {<br>  beforeEach(() =&gt; {<br>    //do something<br>  })<br>  afterAll(() =&gt; {<br>    //do something<br>  })<br>  test(/*...*/)<br>  test(/*...*/)<br>})</pre><pre>describe(&#39;second set&#39;, () =&gt; {<br>  beforeEach(() =&gt; {<br>    //do something<br>  })<br>  beforeAll(() =&gt; {<br>    //do something<br>  })<br>  test(/*...*/)<br>  test(/*...*/)<br>}) </pre><h4>Testing asynchronous code</h4><p>Asynchronous code in modern JavaScript can have basically 2 forms: callbacks and promises. On top of promises we can use async/await.</p><h4>Callbacks</h4><p>You can’t have a test in a callback, because Jest won’t execute it — the execution of the test file ends before the callback is called. To fix this, pass a parameter to the test function, which you can conveniently call done. Jest will wait until you call done() before ending that test:</p><pre>//uppercase.js<br>function uppercase(str, callback) {<br>  callback(str.toUpperCase())<br>}<br>module.exports = uppercase</pre><pre>//uppercase.test.js<br>const uppercase = require(&#39;./src/uppercase&#39;)</pre><pre>test(`uppercase &#39;test&#39; to equal &#39;TEST&#39;`, (done) =&gt; {<br>  uppercase(&#39;test&#39;, (str) =&gt; {<br>    expect(str).toBe(&#39;TEST&#39;)<br>    done()<br>  }<br>})</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/883/0*3aYRb_I7WLxrcyHx.png" /></figure><h4>Promises</h4><p>With functions that return promises, we simply <strong>return a promise</strong> from the test:</p><pre>//uppercase.js<br>const uppercase = str =&gt; {<br>  return new Promise((resolve, reject) =&gt; {<br>    if (!str) {<br>      reject(&#39;Empty string&#39;)<br>      return<br>    }<br>    resolve(str.toUpperCase())<br>  })<br>}<br>module.exports = uppercase</pre><pre>//uppercase.test.js<br>const uppercase = require(&#39;./uppercase&#39;)<br>test(`uppercase &#39;test&#39; to equal &#39;TEST&#39;`, () =&gt; {<br>  return uppercase(&#39;test&#39;).then(str =&gt; {<br>    expect(str).toBe(&#39;TEST&#39;)<br>  })<br>})</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/863/0*bp3ONuX3uiL_FQX8.png" /></figure><p>Promises that are rejected can be tested using .catch():</p><pre>//uppercase.js<br>const uppercase = str =&gt; {<br>  return new Promise((resolve, reject) =&gt; {<br>    if (!str) {<br>      reject(&#39;Empty string&#39;)<br>      return<br>    }<br>    resolve(str.toUpperCase())<br>  })<br>}</pre><pre>module.exports = uppercase</pre><pre>//uppercase.test.js<br>const uppercase = require(&#39;./uppercase&#39;)</pre><pre>test(`uppercase &#39;test&#39; to equal &#39;TEST&#39;`, () =&gt; {<br>  return uppercase(&#39;&#39;).catch(e =&gt; {<br>    expect(e).toMatch(&#39;Empty string&#39;)<br>  })<br>})</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/863/0*awdrSUfRpQEuPWUU.png" /></figure><h4>Async/await</h4><p>To test functions that return promises we can also use async/await, which makes the syntax very straightforward and simple:</p><pre>//uppercase.test.js<br>const uppercase = require(&#39;./uppercase&#39;)<br>test(`uppercase &#39;test&#39; to equal &#39;TEST&#39;`, async () =&gt; {<br>  const str = await uppercase(&#39;test&#39;)<br>  expect(str).toBe(&#39;TEST&#39;)<br>})</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/923/0*HSqBmtzZr-zRKv7z.png" /></figure><h4>Mocking</h4><p>In testing, <strong>mocking</strong> allows you to test functionality that depends on:</p><ul><li><strong>Database</strong></li><li><strong>Network</strong> requests</li><li>access to <strong>Files</strong></li><li>any <strong>External</strong> system</li></ul><p>so that:</p><ol><li>your tests run <strong>faster</strong>, giving a quick turnaround time during development</li><li>your tests are <strong>independent</strong> of network conditions, or the state of the database</li><li>your tests do not <strong>pollute</strong> any data storage because they do not touch the database</li><li>any change done in a test does not change the state for subsequent tests, and re-running the test suite should start from a known and reproducible starting point</li><li>you don’t have to worry about rate limiting on API calls and network requests</li></ol><p>Mocking is useful when you want to avoid side effects (e.g. writing to a database) or you want to skip slow portions of code (like network access), and also avoids implications with running your tests multiple times (e.g. imagine a function that sends an email or calls a rate-limited API).</p><p>Even more important, if you are writing a <strong>Unit Test</strong>, you should test the functionality of a function in isolation, not with all its baggage of things it touches.</p><p>Using mocks, you can inspect if a module function has been called and which parameters were used, with:</p><ul><li>expect().toHaveBeenCalled(): check if a spied function has been called</li><li>expect().toHaveBeenCalledTimes(): count how many times a spied function has been called</li><li>expect().toHaveBeenCalledWith(): check if the function has been called with a specific set of parameters</li><li>expect().toHaveBeenLastCalledWith(): check the parameters of the last time the function has been invoked</li></ul><h4>Spy packages without affecting the functions code</h4><p>When you import a package, you can tell Jest to “spy” on the execution of a particular function, using spyOn(), without affecting how that method works.</p><p>Example:</p><pre>const mathjs = require(&#39;mathjs&#39;)</pre><pre>test(`The mathjs log function`, () =&gt; {<br>  const spy = jest.spyOn(mathjs, &#39;log&#39;)<br>  const result = mathjs.log(10000, 10)</pre><pre>  expect(mathjs.log).toHaveBeenCalled()<br>  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)<br>})</pre><h4>Mock an entire package</h4><p>Jest provides a convenient way to mock an entire package. Create a __mocks__folder in the project root, and in this folder create one JavaScript file for each of your packages.</p><p>Say you import mathjs. Create a __mocks__/mathjs.js file in your project root, and add this content:</p><pre>module.exports = {<br>  log: jest.fn(() =&gt; &#39;test&#39;)<br>}</pre><p>This will mock the log() function of the package. Add as many functions as you want to mock:</p><pre>const mathjs = require(&#39;mathjs&#39;)</pre><pre>test(`The mathjs log function`, () =&gt; {<br>  const result = mathjs.log(10000, 10)<br>  expect(result).toBe(&#39;test&#39;)<br>  expect(mathjs.log).toHaveBeenCalled()<br>  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)<br>})</pre><h4>Mock a single function</h4><p>More simply, you can mock a single function using jest.fn():</p><pre>const mathjs = require(&#39;mathjs&#39;)</pre><pre>mathjs.log = jest.fn(() =&gt; &#39;test&#39;)<br>test(`The mathjs log function`, () =&gt; {<br>  const result = mathjs.log(10000, 10)<br>  expect(result).toBe(&#39;test&#39;)<br>  expect(mathjs.log).toHaveBeenCalled()<br>  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)<br>})</pre><p>You can also use jest.fn().mockReturnValue(&#39;test&#39;) to create a simple mock that does nothing except returning a value.</p><h4>Pre-built mocks</h4><p>You can find pre-made mocks for popular libraries. For example this package <a href="https://github.com/jefflau/jest-fetch-mock">https://github.com/jefflau/jest-fetch-mock</a> allows you to mock fetch() calls, and provide sample return values without interacting with the actual server in your tests.</p><h4>Snapshot testing</h4><p>Snapshot testing is a pretty cool feature offered by Jest. It can memorize how your UI components are rendered, and compare it to the current test, raising an error if there’s a mismatch.</p><p>This is a simple test on the App component of a simple create-react-app application (make sure you install react-test-renderer):</p><pre>import React from &#39;react&#39;<br>import App from &#39;./App&#39;<br>import renderer from &#39;react-test-renderer&#39;</pre><pre>it(&#39;renders correctly&#39;, () =&gt; {<br>  const tree = renderer.create(&lt;App /&gt;).toJSON()<br>  expect(tree).toMatchSnapshot()<br>})</pre><p>the first time you run this test, Jest saves the snapshot to the __snapshots__folder. Here’s what App.test.js.snap contains:</p><pre>// Jest Snapshot v1, https://goo.gl/fbAQLP</pre><pre>exports[`renders correctly 1`] = `<br>&lt;div<br>  className=&quot;App&quot;<br>&gt;<br>  &lt;header<br>    className=&quot;App-header&quot;<br>  &gt;<br>    &lt;img<br>      alt=&quot;logo&quot;<br>      className=&quot;App-logo&quot;<br>      src=&quot;logo.svg&quot;<br>    /&gt;<br>    &lt;h1<br>      className=&quot;App-title&quot;<br>    &gt;<br>      Welcome to React<br>    &lt;/h1&gt;<br>  &lt;/header&gt;<br>  &lt;p<br>    className=&quot;App-intro&quot;<br>  &gt;<br>    To get started, edit<br>    &lt;code&gt;<br>      src/App.js<br>    &lt;/code&gt;<br>     and save to reload.<br>  &lt;/p&gt;<br>&lt;/div&gt;<br>`</pre><p>As you see it’s the code that the App component renders, nothing more.</p><p>The next time the test compares the output of &lt;App /&gt; to this. If App changes, you get an error:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*FZRISPlUUTTQ3rp6.png" /></figure><p>When using yarn test in create-react-app you are in <strong>watch mode</strong>, and from there you can press w and show more options:</p><pre>Watch Usage<br> › Press u to update failing snapshots.<br> › Press p to filter by a filename regex pattern.<br> › Press t to filter by a test name regex pattern.<br> › Press q to quit watch mode.<br> › Press Enter to trigger a test run.</pre><p>If your change is intended, pressing u will update the failing snapshots, and make the test pass.</p><p>You can also update the snapshot by running jest -u (or jest --updateSnapshot) outside of watch mode.</p><h3>Testing React components</h3><p>The easiest way to start with testing React components is doing snapshot testing, a testing technique that lets you test components in isolation.</p><p>If you are familiar with testing software, it’s just like unit testing you do for classes: you test each component functionality.</p><p>I assume you created a React app with create-react-app, which already comes with <strong>Jest</strong> installed, the testing package we&#39;ll need.</p><p>Let’s start with a simple test. CodeSandbox is a great environment to try this out. Start with a React sandbox, and create an App.js component in a components folder, and add an App.test.js file.</p><pre>import React from &#39;react&#39;</pre><pre>export default function App() {<br>  return (<br>    &lt;div className=&quot;App&quot;&gt;<br>      &lt;h1&gt;Hello CodeSandbox&lt;/h1&gt;<br>      &lt;h2&gt;Start editing to see some magic happen!&lt;/h2&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>Our first test is dumb:</p><pre>test(&#39;First test&#39;, () =&gt; {<br>  expect(true).toBeTruthy()<br>})</pre><p>When CodeSandbox detects test files, it automatically runs them for you, and you can click the Tests button in the bottom of the view to show your test results:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/935/1*WSlNj-vxAaRtQo6pSi5UvA.png" /></figure><p>A test file can contain multiple tests:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/937/1*5wPycKiINSd7rq0rWtDNRQ.png" /></figure><p>Let’s do something a bit more useful now, to actually test a React component. We only have App now, which is not doing anything really useful, so let’s first set up the environment with a little application with more functionality: the counter app we built previously. If you skipped it, you can go back and read how we built it, but for easier reference I add it here again.</p><p>It’s just 2 components: App and Button. Create the App.js file:</p><pre>import React, { useState } from &#39;react&#39;<br>import Button from &#39;./Button&#39;</pre><pre>const App = () =&gt; {<br>  const [count, setCount] = useState(0)</pre><pre>  const incrementCount = increment =&gt; {<br>    setCount(count + increment)<br>  }</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;Button increment={1} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={10} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={100} onClickFunction={incrementCount} /&gt;<br>      &lt;Button increment={1000} onClickFunction={incrementCount} /&gt;<br>      &lt;span&gt;{count}&lt;/span&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><pre>export default App</pre><p>and the Button.js file:</p><pre>import React from &#39;react&#39;</pre><pre>const Button = ({ increment, onClickFunction }) =&gt; {<br>  const handleClick = () =&gt; {<br>    onClickFunction(increment)<br>  }<br>  return &lt;button onClick={handleClick}&gt;+{increment}&lt;/button&gt;<br>}</pre><pre>export default Button</pre><p>We are going to use the react-testing-library, which is a great help as it allows us to inspect the output of every component and to apply events on them. You can read more about it on <a href="https://github.com/kentcdodds/react-testing-library">https://github.com/kentcdodds/react-testing-library</a> or watch <a href="https://www.youtube.com/watch?v=JKOwJUM4_RM">this video</a>.</p><p>Let’s test the Button component first.</p><p>We start by importing render and fireEvent from react-testing-library, two helpers. The first lets us render JSX. The second lets us emit events on a component.</p><p>Create a Button.test.js and put it in the same folder as Button.js.</p><pre>import React from &#39;react&#39;<br>import { render, fireEvent } from &#39;react-testing-library&#39;<br>import Button from &#39;./Button&#39;</pre><p>Buttons are used in the app to accept a click event and then they call a function passed to the onClickFunction prop. We add a count variable and we create a function that increments it:</p><pre>let count</pre><pre>const incrementCount = increment =&gt; {<br>  count += increment<br>}</pre><p>Now off to the actual tests. We first initialize count to 0, and we render a +1 Button component passing a 1 to increment and our incrementCount function to onClickFunction.</p><p>Then we get the content of the first child of the component, and we check it outputs +1.</p><p>We then proceed to clicking the button, and we check that the count got from 0 to 1:</p><pre>test(&#39;+1 Button works&#39;, () =&gt; {<br>  count = 0<br>  const { container } = render(<br>    &lt;Button increment={1} onClickFunction={incrementCount} /&gt;<br>  )<br>  const button = container.firstChild<br>  expect(button.textContent).toBe(&#39;+1&#39;)<br>  expect(count).toBe(0)<br>  fireEvent.click(button)<br>  expect(count).toBe(1)<br>})</pre><p>Similarly we test a +100 button, this time checking the output is +100 and the button click increments the count of 100.</p><pre>test(&#39;+100 Button works&#39;, () =&gt; {<br>  count = 0<br>  const { container } = render(<br>    &lt;Button increment={100} onClickFunction={incrementCount} /&gt;<br>  )<br>  const button = container.firstChild<br>  expect(button.textContent).toBe(&#39;+100&#39;)<br>  expect(count).toBe(0)<br>  fireEvent.click(button)<br>  expect(count).toBe(100)<br>})</pre><p>Let’s test the App component now. It shows 4 buttons and the result in the page. We can inspect each button and see if the result increases when we click them, clicking multiple times as well:</p><pre>import React from &#39;react&#39;<br>import { render, fireEvent } from &#39;react-testing-library&#39;<br>import App from &#39;./App&#39;</pre><pre>test(&#39;App works&#39;, () =&gt; {<br>  const { container } = render(&lt;App /&gt;)<br>  console.log(container)<br>  const buttons = container.querySelectorAll(&#39;button&#39;)</pre><pre>  expect(buttons[0].textContent).toBe(&#39;+1&#39;)<br>  expect(buttons[1].textContent).toBe(&#39;+10&#39;)<br>  expect(buttons[2].textContent).toBe(&#39;+100&#39;)<br>  expect(buttons[3].textContent).toBe(&#39;+1000&#39;)</pre><pre>  const result = container.querySelector(&#39;span&#39;)<br>  expect(result.textContent).toBe(&#39;0&#39;)<br>  fireEvent.click(buttons[0])<br>  expect(result.textContent).toBe(&#39;1&#39;)<br>  fireEvent.click(buttons[1])<br>  expect(result.textContent).toBe(&#39;11&#39;)<br>  fireEvent.click(buttons[2])<br>  expect(result.textContent).toBe(&#39;111&#39;)<br>  fireEvent.click(buttons[3])<br>  expect(result.textContent).toBe(&#39;1111&#39;)<br>  fireEvent.click(buttons[2])<br>  expect(result.textContent).toBe(&#39;1211&#39;)<br>  fireEvent.click(buttons[1])<br>  expect(result.textContent).toBe(&#39;1221&#39;)<br>  fireEvent.click(buttons[0])<br>  expect(result.textContent).toBe(&#39;1222&#39;)<br>})</pre><p>Check the code working on this CodeSandbox: <a href="https://codesandbox.io/s/pprl4y0wq">https://codesandbox.io/s/pprl4y0wq</a></p><h3>SECTION 8: THE REACT ECOSYSTEM</h3><p>The ecosystem around React is huge. Here I introduce you to 4 of the most popular projects based upon React: React Router, Redux, Next.js, Gatsby.</p><h3>React Router</h3><p>React Router is the de-facto React routing library, and it’s one of the most popular projects built on top of React.</p><p>React at its core is a very simple library, and it does not dictate anything about routing.</p><p>Routing in a Single Page Application is the way to introduce some features to navigating the app through links, which are <strong>expected</strong> in normal web applications:</p><ol><li>The browser should <strong>change the URL</strong> when you navigate to a different screen</li><li><strong>Deep linking</strong> should work: if you point the browser to a URL, the application should reconstruct the same view that was presented when the URL was generated.</li><li>The <strong>browser back (and forward) button</strong> should work like expected.</li></ol><p><strong>Routing links together your application navigation with the navigation features offered by the browser</strong>: the <strong>address bar</strong> and the <strong>navigation buttons</strong>.</p><p>React Router offers a way to write your code so that <strong>it will show certain components of your app only if the route matches what you define</strong>.</p><h3>Installation</h3><p>With <a href="https://flaviocopes.com/npm/">npm</a>:</p><pre>npm install react-router-dom</pre><p>With <a href="https://flaviocopes.com/yarn/">Yarn</a>:</p><pre>yarn add react-router-dom</pre><h3>Types of routes</h3><p>React Router provides two different kind of routes:</p><ul><li>BrowserRouter</li><li>HashRouter</li></ul><p>One builds classic URLs, the other builds URLs with the hash:</p><pre>https://application.com/dashboard   /* BrowserRouter */<br>https://application.com/#/dashboard /* HashRouter    */</pre><p>Which one to use is mainly dictated by the browsers you need to support. BrowserRouter uses the <a href="https://flaviocopes.com/history-api/">History API</a>, which is relatively recent, and not supported in IE9 and below. If you don&#39;t have to worry about older browsers, it&#39;s the recommended choice.</p><h3>Components</h3><p>The 3 components you will interact the most when working with React Router are:</p><ul><li>BrowserRouter, usually aliased as Router</li><li>Link</li><li>Route</li></ul><p>BrowserRouter wraps all your Route components.</p><p>Link components are - as you can imagine - used to generate links to your routes</p><p>Route components are responsible for showing - or hiding - the components they contain.</p><h3>BrowserRouter</h3><p>Here’s a simple example of the BrowserRouter component. You import it from react-router-dom, and you use it to wrap all your app:</p><pre>import React from &#39;react&#39;<br>import ReactDOM from &#39;react-dom&#39;<br>import { BrowserRouter as Router } from &#39;react-router-dom&#39;</pre><pre>ReactDOM.render(<br>  &lt;Router&gt;<br>      &lt;div&gt;<br>        &lt;!-- --&gt;<br>      &lt;/div&gt;<br>  &lt;/Router&gt;,<br>  document.getElementById(&#39;app&#39;)<br>)</pre><p>A BrowserRouter component can only have one child element, so we wrap all we’re going to add in a div element.</p><h3>Link</h3><p>The Link component is used to trigger new routes. You import it from react-router-dom, and you can add the Link components to point at different routes, with the to attribute:</p><pre>import React from &#39;react&#39;<br>import ReactDOM from &#39;react-dom&#39;<br>import { BrowserRouter as Router, Link } from &#39;react-router-dom&#39;</pre><pre>ReactDOM.render(<br>  &lt;Router&gt;<br>      &lt;div&gt;<br>        &lt;aside&gt;<br>          &lt;Link to={`/dashboard`}&gt;Dashboard&lt;/Link&gt;<br>          &lt;Link to={`/about`}&gt;About&lt;/Link&gt;<br>        &lt;/aside&gt;<br>        &lt;!-- --&gt;<br>      &lt;/div&gt;<br>  &lt;/Router&gt;,<br>  document.getElementById(&#39;app&#39;)<br>)</pre><h3>Route</h3><p>Now let’s add the Route component in the above snippet to make things actually work as we want:</p><pre>import React from &#39;react&#39;<br>import ReactDOM from &#39;react-dom&#39;<br>import { BrowserRouter as Router, Link, Route } from &#39;react-router-dom&#39;</pre><pre>const Dashboard = () =&gt; (<br>  &lt;div&gt;<br>    &lt;h2&gt;Dashboard&lt;/h2&gt;<br>    ...<br>  &lt;/div&gt;<br>)</pre><pre>const About = () =&gt; (<br>  &lt;div&gt;<br>    &lt;h2&gt;About&lt;/h2&gt;<br>    ...<br>  &lt;/div&gt;<br>)</pre><pre>ReactDOM.render(<br>  &lt;Router&gt;<br>    &lt;div&gt;<br>      &lt;aside&gt;<br>        &lt;Link to={`/`}&gt;Dashboard&lt;/Link&gt;<br>        &lt;Link to={`/about`}&gt;About&lt;/Link&gt;<br>      &lt;/aside&gt;</pre><pre>      &lt;main&gt;<br>        &lt;Route exact path=&quot;/&quot; component={Dashboard} /&gt;<br>        &lt;Route path=&quot;/about&quot; component={About} /&gt;<br>      &lt;/main&gt;<br>    &lt;/div&gt;<br>  &lt;/Router&gt;,<br>  document.getElementById(&#39;app&#39;)<br>)</pre><p>Check this example on Glitch: <a href="https://flaviocopes-react-router-v4.glitch.me/">https://flaviocopes-react-router-v4.glitch.me/</a></p><p>When the route matches /, the application shows the <strong>Dashboard</strong> component.</p><p>When the route is changed by clicking the “About” link to /about, the Dashboard component is removed and the <strong>About</strong> component is inserted in the DOM.</p><p>Notice the exact attribute. Without this, path=&quot;/&quot; would also match /about, since / is contained in the route.</p><h3>Match multiple paths</h3><p>You can have a route respond to multiple paths simply using a regex, because path can be a regular expressions string:</p><pre>&lt;Route path=&quot;/(about|who)/&quot; component={Dashboard} /&gt;</pre><h3>Inline rendering</h3><p>Instead of specifying a component property on Route, you can set a render prop:</p><pre>&lt;Route<br>  path=&quot;/(about|who)/&quot;<br>  render={() =&gt; (<br>    &lt;div&gt;<br>      &lt;h2&gt;About&lt;/h2&gt;<br>      ...<br>    &lt;/div&gt;<br>  )}<br>/&gt;</pre><h3>Match dynamic route parameter</h3><p>You already saw how to use static routes like</p><pre>const Posts = () =&gt; (<br>  &lt;div&gt;<br>    &lt;h2&gt;Posts&lt;/h2&gt;<br>    ...<br>  &lt;/div&gt;<br>)</pre><pre>//...</pre><pre>&lt;Route exact path=&quot;/posts&quot; component={Posts} /&gt;</pre><p>Here’s how to handle dynamic routes:</p><pre>const Post = ({match}) =&gt; (<br>  &lt;div&gt;<br>    &lt;h2&gt;Post #{match.params.id}&lt;/h2&gt;<br>    ...<br>  &lt;/div&gt;<br>)</pre><pre>//...</pre><pre>&lt;Route exact path=&quot;/post/:id&quot; component={Post} /&gt;</pre><p>In your Route component you can lookup the dynamic parameters in match.params.</p><p>match is also available in inline rendered routes, and this is especially useful in this case, because we can use the id parameter to lookup the post data in our data source before rendering Post:</p><pre>const posts = [<br>  { id: 1, title: &#39;First&#39;, content: &#39;Hello world!&#39; },<br>  { id: 2, title: &#39;Second&#39;, content: &#39;Hello again!&#39; }<br>]</pre><pre>const Post = ({post}) =&gt; (<br>  &lt;div&gt;<br>    &lt;h2&gt;{post.title}&lt;/h2&gt;<br>    {post.content}<br>  &lt;/div&gt;<br>)</pre><pre>//...</pre><pre>&lt;Route exact path=&quot;/post/:id&quot; render={({match}) =&gt; (<br>  &lt;Post post={posts.find(p =&gt; p.id === match.params.id)} /&gt;<br>)} /&gt;</pre><h3>Redux</h3><p>Redux is a state manager that’s usually used along with React, but it’s not tied to that library — it can be used with other technologies as well, but we’ll stick to React for the sake of the explanation..</p><p>Redux is a way to manage an application state, and move it to an <strong>external global store</strong>.</p><p>There are a few concepts to grasp, but once you do, Redux is a very simple approach to the problem.</p><p>Redux is very popular with React applications, but it’s in no way unique to React: there are bindings for nearly any popular framework. That said, I’ll make some examples using React as it is its primary use case.</p><h4>When should you use Redux?</h4><p>Redux is ideal for medium to big apps, and you should only use it when you have trouble managing the state with the default state management of React, or the other library you use.</p><p>Simple apps should not need it at all (and there’s nothing wrong with simple apps).</p><h4>Immutable State Tree</h4><p>In Redux, the whole state of the application is represented by <strong>one</strong> <a href="https://flaviocopes.com/javascript/">JavaScript</a> object, called <strong>State</strong> or <strong>State Tree</strong>.</p><p>We call it <strong>Immutable State Tree</strong> because it is read only: it can’t be changed directly.</p><p>It can only be changed by dispatching an <strong>Action</strong>.</p><h4>Actions</h4><p>An <strong>Action</strong> is <strong>a JavaScript object that describes a change in a minimal way</strong> (with just the information needed):</p><pre>{<br>  type: &#39;CLICKED_SIDEBAR&#39;<br>}</pre><pre>// e.g. with more data<br>{<br>  type: &#39;SELECTED_USER&#39;,<br>  userId: 232<br>}</pre><p>The only requirement of an action object is having a type property, whose value is usually a string.</p><h4>Actions types should be constants</h4><p>In a simple app an action type can be defined as a string, as I did in the example in the previous lesson.</p><p>When the app grows is best to use constants:</p><pre>const ADD_ITEM = &#39;ADD_ITEM&#39;<br>const action = { type: ADD_ITEM, title: &#39;Third item&#39; }</pre><p>and to separate actions in their own files, and import them</p><pre>import { ADD_ITEM, REMOVE_ITEM } from &#39;./actions&#39;</pre><h4>Action creators</h4><p><strong>Actions Creators</strong> are functions that create actions.</p><pre>function addItem(t) {<br>  return {<br>    type: ADD_ITEM,<br>    title: t<br>  }<br>}</pre><p>You usually run action creators in combination with triggering the dispatcher:</p><pre>dispatch(addItem(&#39;Milk&#39;))</pre><p>or by defining an action dispatcher function:</p><pre>const dispatchAddItem = i =&gt; dispatch(addItem(i))<br>dispatchAddItem(&#39;Milk&#39;)</pre><h4>Reducers</h4><p>When an action is fired, something must happen, the state of the application must change.</p><p>This is the job of <strong>reducers</strong>.</p><p>A <strong>reducer</strong> is a <strong>pure function</strong> that calculates the next State Tree based on the previous State Tree, and the action dispatched.</p><pre>;(currentState, action) =&gt; newState</pre><p>A pure function takes an input and returns an output without changing the input or anything else. Thus, a reducer returns a completely new state tree object that substitutes the previous one.</p><h4>What a reducer should not do</h4><p>A reducer should be a pure function, so it should:</p><ul><li>never mutate its arguments</li><li>never mutate the state, but instead create a new one with Object.assign({}, ...)</li><li>never generate side-effects (no API calls changing anything)</li><li>never call non-pure functions, functions that change their output based on factors other than their input (e.g. Date.now() or Math.random())</li></ul><p>There is no reinforcement, but you should stick to the rules.</p><h4>Multiple reducers</h4><p>Since the state of a complex app could be really wide, there is not a single reducer, but many reducers for any kind of action.</p><h4>A simulation of a reducer</h4><p>At its core, Redux can be simplified with this simple model:</p><h4>The state</h4><pre>{<br>  list: [<br>    { title: &quot;First item&quot; },<br>    { title: &quot;Second item&quot; },<br>  ],<br>  title: &#39;Groceries list&#39;<br>}</pre><h4>A list of actions</h4><pre>{ type: &#39;ADD_ITEM&#39;, title: &#39;Third item&#39; }<br>{ type: &#39;REMOVE_ITEM&#39;, index: 1 }<br>{ type: &#39;CHANGE_LIST_TITLE&#39;, title: &#39;Road trip list&#39; }</pre><h4>A reducer for every part of the state</h4><pre>const title = (state = &#39;&#39;, action) =&gt; {<br>    if (action.type === &#39;CHANGE_LIST_TITLE&#39;) {<br>      return action.title<br>    } else {<br>      return state<br>    }<br>}</pre><pre>const list = (state = [], action) =&gt; {<br>  switch (action.type) {<br>    case &#39;ADD_ITEM&#39;:<br>      return state.concat([{ title: action.title }])<br>    case &#39;REMOVE_ITEM&#39;:<br>      return state.map((item, index) =&gt;<br>        action.index === index<br>          ? { title: item.title }<br>          : item<br>    default:<br>      return state<br>  }<br>}</pre><h4>A reducer for the whole state</h4><pre>const listManager = (state = {}, action) =&gt; {<br>  return {<br>    title: title(state.title, action),<br>    list: list(state.list, action)<br>  }<br>}</pre><h4>The Store</h4><p>The <strong>Store</strong> is an object that:</p><ul><li><strong>holds the state</strong> of the app</li><li><strong>exposes the state</strong> via getState()</li><li>allows us to <strong>update the state</strong> via dispatch()</li><li>allows us to (un)register a <strong>state change listener</strong> using subscribe()</li></ul><p>A store is <strong>unique</strong> in the app.</p><p>Here is how a store for the listManager app is created:</p><pre>import { createStore } from &#39;redux&#39;<br>import listManager from &#39;./reducers&#39;<br>let store = createStore(listManager)</pre><h4>Can I initialize the store with server-side data?</h4><p>Sure, <strong>just pass a starting state</strong>:</p><pre>let store = createStore(listManager, preexistingState)</pre><h4>Getting the state</h4><pre>store.getState()</pre><h4>Update the state</h4><pre>store.dispatch(addItem(&#39;Something&#39;))</pre><h4>Listen to state changes</h4><pre>const unsubscribe = store.subscribe(() =&gt;<br>  const newState = store.getState()<br>)</pre><pre>unsubscribe()</pre><h4>Data Flow</h4><p>Data flow in Redux is always <strong>unidirectional</strong>.</p><p>You call dispatch() on the Store, passing an Action.</p><p>The Store takes care of passing the Action to the Reducer, generating the next State.</p><p>The Store updates the State and alerts all the Listeners.</p><h3>Next.js</h3><p>Working on a modern <a href="https://flaviocopes.com/javascript/">JavaScript</a> application powered by <a href="https://flaviocopes.com/react/">React</a> is awesome until you realize that there are a couple problems related to rendering all the content on the client-side.</p><p>First, the page takes longer to the become visible to the user, because before the content loads, all the JavaScript must load, and your application needs to run to determine what to show on the page.</p><p>Second, if you are building a publicly available website, you have a content SEO issue. Search engines are getting better at running and indexing JavaScript apps, but it’s much better if we can send them content instead of letting them figure it out.</p><p>The solution to both of those problems is <strong>server rendering</strong>, also called <strong>static pre-rendering</strong>.</p><p>Next.js is one React framework to do all of this in a very simple way, but it’s not limited to this. It’s advertised by its creators as a <strong>zero-configuration, single-command toolchain for React apps</strong>.</p><p>It provides a common structure that allows you to easily build a frontend React application, and transparently handle server-side rendering for you.</p><p>Here is a non-exhaustive list of the main Next.js features:</p><ul><li><strong>Hot Code Reloading</strong>: Next.js reloads the page when it detects any change saved to disk.</li><li><strong>Automatic Routing</strong>: any URL is mapped to the filesystem, to files put in the pages folder, and you don’t need any configuration (you have customization options of course).</li><li><strong>Single File Components</strong>: using <a href="https://github.com/zeit/styled-jsx">styled-jsx</a>, completely integrated as built by the same team, it’s trivial to add styles scoped to the component.</li><li><strong>Server Rendering</strong>: you can (optionally) render React components on the server side, before sending the HTML to the client.</li><li><strong>Ecosystem Compatibility</strong>: Next.js plays well with the rest of the JavaScript, Node and React ecosystem.</li><li><strong>Automatic Code Splitting</strong>: pages are rendered with just the libraries and JavaScript that they need, no more.</li><li><strong>Prefetching</strong>: the Link component, used to link together different pages, supports a prefetch prop which automatically prefetches page resources (including code missing due to code splitting) in the background.</li><li><strong>Dynamic Components</strong>: you can import JavaScript modules and React Components dynamically (<a href="https://github.com/zeit/next.js#dynamic-import">https://github.com/zeit/next.js#dynamic-import</a>).</li><li><strong>Static Exports</strong>: using the next export command, Next.js allows you to export a fully static site from your app.</li></ul><h4>Installation</h4><p>Next.js supports all the major platforms: Linux, macOS, Windows.</p><p>A Next.js project is started easily with npm:</p><pre>npm install next react react-dom</pre><p>or with <a href="https://flaviocopes.com/yarn/">Yarn</a>:</p><pre>yarn add next react react-dom</pre><h4>Getting started</h4><p>Create a package.json file with this content:</p><pre>{<br>  &quot;scripts&quot;: {<br>    &quot;dev&quot;: &quot;next&quot;<br>  }<br>}</pre><p>If you run this command now:</p><pre>npm run dev</pre><p>the script will raise an error complaining about not finding the pages folder. This is the only thing that Next.js requires to run.</p><p>Create an empty pages folder, and run the command again, and Next.js will start up a server on localhost:3000.</p><p>If you go to that URL now, you’ll be greeted by a friendly 404 page, with a nice clean design.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*A0gvXE6QxkPBTXi1.png" /></figure><p>Next.js handles other error types as well, like 500 errors for example.</p><h4>Create a page</h4><p>In the pages folder create an index.js file with a simple React functional component:</p><pre>export default () =&gt; (<br>  &lt;div&gt;<br>    &lt;p&gt;Hello World!&lt;/p&gt;<br>  &lt;/div&gt;<br>)</pre><p>If you visit localhost:3000, this component will automatically be rendered.</p><p>Why is this so simple?</p><p>Next.js uses a declarative pages structure, which is based on the filesystem structure.</p><p>Simply put, pages are inside a pages folder, and the page URL is determined by the page file name. The filesystem is the pages API.</p><h4>Server-side rendering</h4><p>Open the page source, View -&gt; Developer -&gt; View Source with Chrome.</p><p>As you can see, the HTML generated by the component is sent directly in the page source. It’s not rendered client-side, but instead it’s rendered on the server.</p><p>The Next.js team wanted to create a developer experience for server rendered pages similar to the one you get when creating a basic PHP project, where you simply drop PHP files and you call them, and they show up as pages. Internally of course it’s all very different, but the apparent ease of use is clear.</p><h4>Add a second page</h4><p>Let’s create another page, in pages/contact.js</p><pre>export default () =&gt; (<br>  &lt;div&gt;<br>    &lt;p&gt;<br>      &lt;a href=&quot;mailto:my@email.com&quot;&gt;Contact us!&lt;/a&gt;<br>    &lt;/p&gt;<br>  &lt;/div&gt;<br>)</pre><p>If you point your browser to localhost:3000/contact this page will be rendered. As you can see, also this page is server rendered.</p><h4>Hot reloading</h4><p>Note how you did not have to restart the npm process to load the second page. Next.js does this for you under the hood.</p><h4>Client rendering</h4><p>Server rendering is very convenient in your first page load, for all the reasons we saw above, but when it comes to navigating inside the website, client-side rendering is key to speeding up the page load and improving the user experience.</p><p>Next.js provides a Link component you can use to build links. Try linking the two pages above.</p><p>Change index.js to this code:</p><pre>import Link from &#39;next/link&#39;</pre><pre>export default () =&gt; (<br>  &lt;div&gt;<br>    &lt;p&gt;Hello World!&lt;/p&gt;<br>    &lt;Link href=&quot;/contact&quot;&gt;<br>      &lt;a&gt;Contact me!&lt;/a&gt;<br>    &lt;/Link&gt;<br>  &lt;/div&gt;<br>)</pre><p>Now go back to the browser and try this link. As you can see, the Contact page loads immediately, without a page refresh.</p><p>This is client-side navigation working correctly, with complete support for the <a href="https://flaviocopes.com/history-api/"><strong>History API</strong></a>, which means your users back button won’t break.</p><p>If you now cmd-click the link, the same Contact page will open in a new tab, now server rendered.</p><h4>Dynamic pages</h4><p>A good use case for Next.js is a blog, as it’s something that all developers know how it works, and it’s a good fit for a simple example of how to handle dynamic pages.</p><p>A dynamic page is a page that has no fixed content, but instead display some data based on some parameters.</p><p>Change index.js to</p><pre>import Link from &#39;next/link&#39;</pre><pre>const Post = props =&gt; (<br>  &lt;li&gt;<br>    &lt;Link href={`/post?title=${props.title}`}&gt;<br>      &lt;a&gt;{props.title}&lt;/a&gt;<br>    &lt;/Link&gt;<br>  &lt;/li&gt;<br>)</pre><pre>export default () =&gt; (<br>  &lt;div&gt;<br>    &lt;h2&gt;My blog&lt;/h2&gt;<br>    &lt;ul&gt;<br>      &lt;li&gt;<br>        &lt;Post title=&quot;Yet another post&quot; /&gt;<br>        &lt;Post title=&quot;Second post&quot; /&gt;<br>        &lt;Post title=&quot;Hello, world!&quot; /&gt;<br>      &lt;/li&gt;<br>    &lt;/ul&gt;<br>  &lt;/div&gt;<br>)</pre><p>This will create a series of posts and will fill the title query parameter with the post title:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/829/0*34dzRgmfgzc1Soqb.png" /></figure><p>Now create a post.js file in the pages folder, and add:</p><pre>export default props =&gt; &lt;h1&gt;{props.url.query.title}&lt;/h1&gt;</pre><p>Now clicking a single post will render the post title in a h1 tag:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/520/0*3JgCKMq29HSrEj8f.png" /></figure><p>You can use clean URLs without query parameters. The Next.js Link component helps us by accepting an as attribute, which you can use to pass a slug:</p><pre>import Link from &#39;next/link&#39;</pre><pre>const Post = props =&gt; (<br>  &lt;li&gt;<br>    &lt;Link as={`/${props.slug}`} href={`/post?title=${props.title}`}&gt;<br>      &lt;a&gt;{props.title}&lt;/a&gt;<br>    &lt;/Link&gt;<br>  &lt;/li&gt;<br>)</pre><pre>export default () =&gt; (<br>  &lt;div&gt;<br>    &lt;h2&gt;My blog&lt;/h2&gt;<br>    &lt;ul&gt;<br>      &lt;li&gt;<br>        &lt;Post slug=&quot;yet-another-post&quot; title=&quot;Yet another post&quot; /&gt;<br>        &lt;Post slug=&quot;second-post&quot; title=&quot;Second post&quot; /&gt;<br>        &lt;Post slug=&quot;hello-world&quot; title=&quot;Hello, world!&quot; /&gt;<br>      &lt;/li&gt;<br>    &lt;/ul&gt;<br>  &lt;/div&gt;<br>)</pre><h4>CSS-in-JS</h4><p>Next.js by default provides support for <a href="https://github.com/zeit/styled-jsx">styled-jsx</a>, which is a CSS-in-JS solution provided by the same development team, but you can use whatever library you prefer, like Styled Components.</p><p>Example:</p><pre>export default () =&gt; (<br>  &lt;div&gt;<br>    &lt;p&gt;<br>      &lt;a href=&quot;mailto:my@email.com&quot;&gt;Contact us!&lt;/a&gt;<br>    &lt;/p&gt;<br>    &lt;style jsx&gt;{`<br>      p {<br>        font-family: &#39;Courier New&#39;;<br>      }<br>      a {<br>        text-decoration: none;<br>        color: black;<br>      }<br>      a:hover {<br>        opacity: 0.8;<br>      }<br>    `}&lt;/style&gt;<br>  &lt;/div&gt;<br>)</pre><p>Styles are scoped to the component, but you can also edit global styles adding global to the style element:</p><pre>export default () =&gt; (<br>  &lt;div&gt;<br>    &lt;p&gt;<br>      &lt;a href=&quot;mailto:my@email.com&quot;&gt;Contact us!&lt;/a&gt;<br>    &lt;/p&gt;<br>    &lt;style jsx global&gt;{`<br>      body {<br>        font-family: &#39;Benton Sans&#39;, &#39;Helvetica Neue&#39;;<br>        margin: 2em;<br>      }<br>      h2 {<br>        font-style: italic;<br>        color: #373fff;<br>      }<br>    `}&lt;/style&gt;<br>  &lt;/div&gt;<br>)</pre><h4>Exporting a static site</h4><p>A Next.js application can be easily exported as a static site, which can be deployed on one of the super fast static site hosts, like <a href="https://flaviocopes.com/netlify/">Netlify</a> or <a href="https://flaviocopes.com/firebase-hosting/">Firebase Hosting</a>, without the need to set up a Node environment.</p><p>The process requires you to declare the URLs that compose the site, but it’s <a href="https://github.com/zeit/next.js/#static-html-export">a straightforward process</a>.</p><h4>Deploying</h4><p>Creating a production-ready copy of the application, without source maps or other development tooling that aren’t needed in the final build, is easy.</p><p>At the beginning of this tutorial you created a package.json file with this content:</p><pre>{<br>  &quot;scripts&quot;: {<br>    &quot;dev&quot;: &quot;next&quot;<br>  }<br>}</pre><p>which was the way to start up a development server using npm run dev.</p><p>Now just add the following content to package.json instead:</p><pre>{<br>  &quot;scripts&quot;: {<br>    &quot;dev&quot;: &quot;next&quot;,<br>    &quot;build&quot;: &quot;next build&quot;,<br>    &quot;start&quot;: &quot;next start&quot;<br>  }<br>}</pre><p>and prepare your app by running npm run build and npm run start.</p><h4>Now</h4><p>The company behind Next.js provides an awesome hosting service for Node.js applications, called <a href="https://zeit.co/now"><strong>Now</strong></a>.</p><p>Of course they integrate both their products so you can deploy Next.js apps seamlessly, <a href="https://zeit.co/download">once you have Now installed</a>, by running the now command in the application folder.</p><p>Behind the scenes Now sets up a server for you, and you don’t need to worry about anything, just wait for your application URL to be ready.</p><h4>Zones</h4><p>You can set up multiple Next.js instances to listen to different URLs, yet the application to an outside user will simply look like it’s being powered by a single server: <a href="https://github.com/zeit/next.js/#multi-zones">https://github.com/zeit/next.js/#multi-zones</a></p><h4>Plugins</h4><p>Next.js has a list of plugins at <a href="https://github.com/zeit/next-plugins">https://github.com/zeit/next-plugins</a></p><h4>Starter kit on Glitch</h4><p>If you’re looking to experiment, I recommend Glitch. Check out my <a href="https://glitch.com/edit/#!/flavio-starter-nextjs">Next.js Glitch Starter Kit</a>.</p><h3>Gatsby</h3><p>Gatsby is a platform for building apps and websites using React.</p><p>It is one of the tools that allow you to build on a set of technologies and practices collectively known as <a href="https://flaviocopes.com/jamstack/">JAMstack</a>.</p><p>Gatsby is one of the cool kids in the Frontend Development space right now. Why? I think the reasons are:</p><ul><li>the explosion of the JAMstack approach to building Web Apps and Web Sites</li><li>the rapid adoption of the <a href="https://flaviocopes.com/progressive-web-apps/">Progressive Web Apps</a> technology in the industry, which is one of the key features of Gatsby</li><li>it’s built in React and <a href="https://flaviocopes.com/graphql/">GraphQL</a>, which are two very popular and rising technologies</li><li>it’s really powerful</li><li>it’s fast</li><li>the documentation is great</li><li>the network effect (people use it, create sites, make tutorials, people know more about it, creating a cycle)</li><li>everything is JavaScript (no need to learn a new templating language)</li><li>it hides the complexity, in the beginning, but allows us access into every step to customize</li></ul><p>All those are great points, and Gatsby is definitely worth a look.</p><h4>How does it work?</h4><p>With Gatsby, your applications are built using React components.</p><p>The content you’ll render in a site is generally written using Markdown, but you can use any kind of data source, like a headless CMS or a web service like Contentful.</p><p>Gatsby builds the site, and it’s compiled to static HTML which can be deployed on any Web Server you want, like Netlify, AWS S3, GitHub Pages, regular hosting providers, PAAS and more. All you need is a place that serves plain HTTP pages and your assets to the client.</p><p>I mentioned Progressive Web Apps in the list. Gatsby automatically generates your site as a PWA, with a service worker that speeds up page loading and resource caching.</p><p>You can enhance the functionality of Gatsby via plugins.</p><h4>Installation</h4><p>You can install Gatsby by simply running this in your terminal:</p><pre>npm install -g gatsby-cli</pre><p>This installs the gatsby CLI utility.</p><p>(when a new version is out, update it by calling this command again)</p><p>You create a new “Hello World” site by running</p><pre>gatsby new mysite <a href="https://github.com/gatsbyjs/gatsby-starter-hello-world">https://github.com/gatsbyjs/gatsby-starter-hello-world</a></pre><p>This command creates a brand new Gatsby site in the mysite folder, using the <em>starter</em> available at <a href="https://github.com/gatsbyjs/gatsby-starter-hello-world">https://github.com/gatsbyjs/gatsby-starter-hello-world</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Yengi0GTrfiSq6sH.png" /></figure><p>A <em>starter</em> is a sample site that you can build upon. Another common starter is default, available at <a href="https://github.com/gatsbyjs/gatsby-starter-default">https://github.com/gatsbyjs/gatsby-starter-default</a>.</p><blockquote><a href="https://www.gatsbyjs.org/docs/gatsby-starters/"><em>Here you can find a list of all the starters you can use</em></a><em>.</em></blockquote><h4>Running the Gatsby site</h4><p>After the terminal has finished installing the starter, you can run the website by calling</p><pre>cd mysite<br>gatsby develop</pre><p>which will start up a new Web Server and serve the site on port 8000 on localhost.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*kDa8yhqQ1w8_nj3M.png" /></figure><p>And here is our Hello World starter in action:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/859/0*BQyl2EQnnGPld60c.png" /></figure><h3>Inspecting the site</h3><p>If you open the site you created with your favorite code editor (I use <a href="https://flaviocopes.com/vscode/">VS Code</a>), you’ll find there are 3 folders:</p><ul><li>.cache, a hidden folder that contains the Gatsby internals, nothing you should change right now</li><li>public, which contains the resulting website once you build it</li><li>src contains the React components, in this case just the index component</li><li>static which will contain the static resources like CSS and images</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*J9c4FViRqh0xpMiC.png" /></figure><p>Now, making a simple change to the default page is easy, just open src/pages/index.js and change “Hello world!” to something else, and save. The browser should instantly <strong>hot reload</strong> the component (which means the page does not actually refresh, but the content changes - a trick made possible by the underlying technology).</p><p>To add a second page, just create another .js file in this folder, with the same content of index.js (tweak the content) and save it.</p><p>For example I created a second.js file with this content:</p><pre>import React from &#39;react&#39;</pre><pre>export default () =&gt; &lt;div&gt;Second page!&lt;/div&gt;</pre><p>and I opened the browser to <a href="http://localhost:8000/second">http://localhost:8000/second</a>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/0*n_WDLlpI8VQOR7Xq.png" /></figure><h4>Linking pages</h4><p>You can link those pages by importing a Gatsby-provided React component called Link:</p><pre>import { Link } from &quot;gatsby&quot;</pre><p>and using it in your component <a href="https://flaviocopes.com/jsx/">JSX</a>:</p><pre>&lt;Link to=&quot;/second/&quot;&gt;Second&lt;/Link&gt;</pre><h4>Adding CSS</h4><p>You can import any CSS file using a JavaScript import:</p><pre>import &#39;./index.css&#39;</pre><p>You can use React styling:</p><pre>&lt;p style={{<br>    margin: &#39;0 auto&#39;,<br>    padding: &#39;20px&#39;<br>  }}&gt;Hello world&lt;/p&gt;</pre><h4>Using plugins</h4><p>Gatsby provides lots of things out of the box, but many other functionalities are provided by <a href="https://www.gatsbyjs.org/plugins/">plugins</a>.</p><p>There are 3 kind of plugins:</p><ul><li><strong>source plugins</strong> fetch data from a source. Create nodes that can be then filtered by transformer plugins</li><li><strong>transformer plugins</strong> transform the data provided by source plugins into something Gatsby can use</li><li><strong>functional plugins</strong> implement some kind of functionality, like adding sitemap support or more</li></ul><p>Some commonly used plugins are:</p><ul><li><a href="https://www.gatsbyjs.org/packages/gatsby-plugin-react-helmet/">gatsby-plugin-react-helmet</a> which allows to edit the head tag content</li><li><a href="https://www.gatsbyjs.org/packages/gatsby-plugin-catch-links/">gatsby-plugin-catch-links</a> which uses the <a href="https://flaviocopes.com/history-api/">History API</a> to prevent the browser reloading the page when a link is clicked, loading the new content using AJAX instead</li></ul><p>A Gatsby plugin is installed in 2 steps. First you install it using npm, then you add it to the Gatsby configuration in gatsby-config.js.</p><p>For example you can install the Catch Links plugin:</p><pre>npm install gatsby-plugin-catch-links</pre><p>In gatsby-config.js (create it if you don’t have it, in the website root folder), add the plugin to the plugins exported array:</p><pre>module.exports = {<br>  plugins: [&#39;gatsby-plugin-catch-links&#39;]<br>}</pre><p>That’s it, the plugin will now do its job.</p><h4>Building the static website</h4><p>Once you are done tweaking the site and you want to generate the production static site, you will call</p><pre>gatsby build</pre><p>At this point you can check that it all works as you expect by starting a local Web Server using</p><pre>gatsby serve</pre><p>which will render the site as close as possible to how you will see it in production.</p><h4>Deployment</h4><p>Once you build the site using gatsby build, all you need to do is to deploy the result contained in the public folder.</p><p>Depending on the solution you choose, you’ll need different steps here, but generally you’ll push to a Git repository and let the Git post-commit hooks do the job of deploying. <a href="https://www.gatsbyjs.org/docs/deploying-and-hosting/">Here are some great guides for some popular hosting platforms</a> where you can deploy Gatsby.</p><h3>Wrapping up</h3><p>I hope this book has helped you get started with React, and maybe it gave you a head start in exploring some of the most advanced aspects of React programming. That’s my hope, at least.</p><blockquote>You can get this ebook in PDF, ePub and Mobi format at <a href="https://reacthandbook.com">reacthandbook.com</a></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b71c27b0a795" width="1" height="1" alt=""><hr><p><a href="https://medium.com/free-code-camp/the-react-handbook-b71c27b0a795">The React Handbook</a> was originally published in <a href="https://medium.com/free-code-camp">We’ve moved to freeCodeCamp.org/news</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>