<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tom Ray</title>
    <description>The latest articles on DEV Community by Tom Ray (@bytomray).</description>
    <link>https://dev.to/bytomray</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F256975%2F847459cd-e23d-4e04-8eac-a9f0ed40980b.jpeg</url>
      <title>DEV Community: Tom Ray</title>
      <link>https://dev.to/bytomray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bytomray"/>
    <language>en</language>
    <item>
      <title>How to build a NestJS Docker image for production</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Sun, 15 May 2022 10:16:33 +0000</pubDate>
      <link>https://dev.to/bytomray/how-to-build-a-nestjs-docker-image-for-production-3cmm</link>
      <guid>https://dev.to/bytomray/how-to-build-a-nestjs-docker-image-for-production-3cmm</guid>
      <description>&lt;p&gt;When deploying my NestJS project, I found there wasn't loads online on how to write the Dockerfile to build the Docker image needed for containerized deployment.&lt;/p&gt;

&lt;p&gt;So I wrote this guide which takes you through step-by-step how to setup a Docker image for your NestJs project!&lt;/p&gt;

&lt;p&gt;Ready? Let's dive in.&lt;/p&gt;

&lt;p&gt;P.S. if you want to just copy and paste the production ready Dockerfile, just skip to this section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing the Dockerfile
&lt;/h2&gt;

&lt;p&gt;A container image is an isolated package of software that includes everything you need to run the code. You can define container images by writing a &lt;code&gt;Dockerfile&lt;/code&gt; which provides the instructions on how to build the image.&lt;/p&gt;

&lt;p&gt;Let's add the Dockerfile now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then let's add the instructions to the Dockerfile. See the comments which explain each step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Base image
FROM node:18

# Create app directory
WORKDIR /usr/src/app

# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./

# Install app dependencies
RUN npm install

# Bundle app source
COPY . .

# Creates a "dist" folder with the production build
RUN npm run build

# Start the server using the production build
CMD [ "node", "dist/main.js" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to a &lt;code&gt;.gitignore&lt;/code&gt; file, we can add a &lt;code&gt;.dockerignore&lt;/code&gt; file which will prevent certain files from being included in the image build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .dockerignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then exclude the following files from the image build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dockerfile
.dockerignore
node_modules
npm-debug.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test the container locally
&lt;/h2&gt;

&lt;p&gt;Let's now do some testing locally to check if the Dockerfile behaves as we expect. &lt;/p&gt;

&lt;p&gt;Let's first build the image using the command in your terminal at the root of your project (you can swap out &lt;code&gt;nest-cloud-run&lt;/code&gt; with your project name). Don't forget the &lt;code&gt;.&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; nest-cloud-run &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify the image has been created by running &lt;code&gt;docker images&lt;/code&gt; which will output a list of Docker images you have on your local machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker images
REPOSITORY                   TAG       IMAGE ID       CREATED          SIZE
nest-cloud-run               latest    004f7f222139   31 seconds ago   1.24GB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's now start the container and run the image with this command (be sure to same image name used above):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p80&lt;/span&gt;:3000 nest-cloud-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now access the NestJS app by visiting &lt;code&gt;https://localhost&lt;/code&gt; in your browser (just &lt;code&gt;https://localhost&lt;/code&gt; without any port numbers).&lt;/p&gt;

&lt;p&gt;I ran into a couple of issues on my machine when running the container, mainly due to with conflicts with ports from other containers I had running.&lt;/p&gt;

&lt;p&gt;If you run into similar trouble, you can try running the command &lt;code&gt;docker rm -f $(docker ps -aq)&lt;/code&gt; which stops and removes all running containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize Dockerfile for production
&lt;/h2&gt;

&lt;p&gt;Now that we've confirmed the image is working locally, let's try to reduce the size of the image. &lt;/p&gt;

&lt;p&gt;Deployment tools like Cloud Run factor in the size of the image when calculating how much to charge you, so it's a good idea to keep the image size as small as possible.&lt;/p&gt;

&lt;p&gt;Running the command &lt;code&gt;docker images&lt;/code&gt; gives us our image size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker images
REPOSITORY                   TAG       IMAGE ID       CREATED          SIZE
nest-cloud-run               latest    004f7f222139   31 seconds ago   1.24GB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.24GB is pretty big! Let's dive back into our &lt;code&gt;Dockerfile&lt;/code&gt; and make some optimizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Alpine node images
&lt;/h3&gt;

&lt;p&gt;It's &lt;a href="https://hub.docker.com/_/node"&gt;recommended&lt;/a&gt; to use the Alpine node images when trying to optimize for image size. Using &lt;code&gt;node:18-alpine&lt;/code&gt; instead of &lt;code&gt;node:18&lt;/code&gt; by itself reduces the image size from 1.24GB to 466MB!&lt;/p&gt;

&lt;h3&gt;
  
  
  Use multistage builds
&lt;/h3&gt;

&lt;p&gt;In your Dockerfile you can define &lt;a href="https://earthly.dev/blog/docker-multistage/"&gt;multistage builds&lt;/a&gt; which is a way to sequentially build the most optimized image by building multiple images.&lt;/p&gt;

&lt;p&gt;In practice, here's how we can use multistage builds in our Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Base image
FROM node:18-alpine As development

# Create app directory
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./

# Install app dependencies
RUN npm install

# Bundle app source
COPY . .

# Creates a "dist" folder with the production build
RUN npm run build

# Base image for production
FROM node:18-alpine As production

# Create app directory
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
# If you have a package-lock.json, speedier builds with 'npm ci', otherwise use 'npm install --only=production'
RUN npm ci --only=production

# Bundle app source
COPY . .

# Copy the bundled code
COPY --from=development /usr/src/app/dist ./dist

# Start the server using the production build
CMD [ "node", "dist/main.js" ]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've updated your &lt;code&gt;Dockerfile&lt;/code&gt;, you'll need to re-run the commands to build your image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; nest-cloud-run &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then the command to spin up your container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p80&lt;/span&gt;:3000 nest-cloud-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run &lt;code&gt;docker images&lt;/code&gt; again to check our image size, you'll see it's now signifantly smaller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker images
REPOSITORY                   TAG       IMAGE ID       CREATED          SIZE
nest-cloud-run               latest    004f7f222139   31 seconds ago   189MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;You might come into the following errors:&lt;/p&gt;

&lt;h3&gt;
  
  
  Error: Cannot find module 'webpack'
&lt;/h3&gt;

&lt;p&gt;It's likely you're using the wrong node version in your base image if you're getting errors like the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Error: Cannot find module 'webpack'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ERROR [development 6/6] RUN npm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;npm ERR! nest-cloud-run@0.0.1 build: nest build&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of using &lt;code&gt;FROM node:14-alpine&lt;/code&gt;, use &lt;code&gt;FROM node:18-alpine&lt;/code&gt; to solve this issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In summary, here is our production optimized Docker image for a NestJS project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Base image
FROM node:18-alpine As development

# Create app directory
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./

# Install app dependencies
RUN npm install

# Bundle app source
COPY . .

# Creates a "dist" folder with the production build
RUN npm run build

# Base image for production
FROM node:18-alpine As production

# Create app directory
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
# If you have a package-lock.json, speedier builds with 'npm ci', otherwise use 'npm install --only=production'
RUN npm ci --only=production

# Bundle app source
COPY . .

# Copy the bundled code
COPY --from=development /usr/src/app/dist ./dist

# Start the server using the production build
CMD [ "node", "dist/main.js" ]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you have any further optimizations you can make to the above image? Drop them in the comments below!&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>docker</category>
    </item>
    <item>
      <title>How to setup &amp; deploy an Express GraphQL server</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Fri, 20 Aug 2021 13:01:24 +0000</pubDate>
      <link>https://dev.to/bytomray/how-to-setup-deploy-an-express-graphql-server-4ni8</link>
      <guid>https://dev.to/bytomray/how-to-setup-deploy-an-express-graphql-server-4ni8</guid>
      <description>&lt;p&gt;This is a quick start guide to setting up a GraphQL API using Express, Apollo Server, Prisma, Heroku, Postgres, Docker and TypeScript.&lt;/p&gt;

&lt;p&gt;When we're done, we'll have a GraphQL server that can be used by a front end to query and persist data from a Postres database.&lt;/p&gt;

&lt;p&gt;I've noticed this tech stack rise in popularity in recent times.&lt;/p&gt;

&lt;p&gt;Why? Probably because Heroku offers a free plan and the developer experience for Prisma and Apollo is 🔥.&lt;/p&gt;

&lt;p&gt;Ready? Let's dive in 🤿.&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href="https://github.com/tomwray13/graphql-typescript-api-starter" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt; if you'd like to review the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Creating the project&lt;/li&gt;
&lt;li&gt;Configuring Typescript&lt;/li&gt;
&lt;li&gt;Hot reloading and scripts&lt;/li&gt;
&lt;li&gt;Setting up the server with Apollo&lt;/li&gt;
&lt;li&gt;Deploy to Heroku&lt;/li&gt;
&lt;li&gt;Set up Postgres locally with Docker&lt;/li&gt;
&lt;li&gt;Build your database schema with Prisma&lt;/li&gt;
&lt;li&gt;Connect database to Graphql API&lt;/li&gt;
&lt;li&gt;Adding Postgres to Heroku&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;You'll need to ensure you have the following setup in order to complete this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;Git&lt;/a&gt; and &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed on your machine&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.docker.com/products/docker-desktop" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; installed on your machine. This is not required if you use something else for serving postgres locally&lt;/li&gt;
&lt;li&gt;A free &lt;a href="https://signup.heroku.com/" rel="noopener noreferrer"&gt;Heroku&lt;/a&gt; account for deploying the API&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the project
&lt;/h2&gt;

&lt;p&gt;Jump into your terminal, create the directory and push the code up to a new repository in Github. You can skip this section if you're familiar with this process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;graphql-typescript-api-starter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's setup Node.js in the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;graphql-typescript-api-starter
npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will walk you through a few questions to answer. These are optional - hit enter in your keyboard to skip through them.&lt;/p&gt;

&lt;p&gt;Next, still in your terminal, add a &lt;code&gt;.gitignore&lt;/code&gt; file which tells git which files to ignore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open up the project in your favourite editor and add the following to your .gitignore file for now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, &lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;create a Github repository&lt;/a&gt; and in the terminal, push your code up to the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git add &lt;span class="nt"&gt;-A&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"first commit"&lt;/span&gt;
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git remote add origin &amp;lt;your remote Github repository url&amp;gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring TypeScript
&lt;/h2&gt;

&lt;p&gt;We're going to be using &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; in this tutorial.&lt;/p&gt;

&lt;p&gt;If you're not too familiar with TypeScript - don't fret. &lt;/p&gt;

&lt;p&gt;This tutorial doesn't focus on how to use TypeScript, just how to set it up for a Node JS server side project.&lt;/p&gt;

&lt;p&gt;First of all, add TypeScript as a dependency to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;typescript &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This give us access to the &lt;code&gt;tsc&lt;/code&gt; command locally which will compile our code from TypeScript to Javascript.&lt;/p&gt;

&lt;p&gt;Let's now add type safety and auto-completion for core Node APIs (like &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;http&lt;/code&gt; and &lt;code&gt;fs&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @types/node &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to add a &lt;code&gt;tsconfig.json&lt;/code&gt; file which sets our TypeScript compiler options. First, add the file to the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;tsconfig.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then paste in these compiler options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                          
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                    
    &lt;/span&gt;&lt;span class="nl"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"es6"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;                     
    &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                          
    &lt;/span&gt;&lt;span class="nl"&gt;"rootDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;         
    &lt;/span&gt;&lt;span class="nl"&gt;"noImplicitAny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolveJsonModule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a look at the &lt;a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html" rel="noopener noreferrer"&gt;docs&lt;/a&gt; if you'd like to learn what each configuration means and if you'd like to add more configuration options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hot reloading and scripts
&lt;/h2&gt;

&lt;p&gt;Hot reloading in your local set up is fundamental to a decent developer experience. Otherwise you'll need to quit and restart the server everytime you make changes to your code.&lt;/p&gt;

&lt;p&gt;We're going to use the packages &lt;code&gt;nodemon&lt;/code&gt; and &lt;code&gt;ts-node&lt;/code&gt; to set up hot reloading:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;ts-node nodemon &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;nodemon&lt;/code&gt; watches for any changes in your code and restarts the server automatically, while &lt;code&gt;ts-node&lt;/code&gt; enables the server to understand TypeScript directly (removing the requirement for compiling).&lt;/p&gt;

&lt;p&gt;Next add a &lt;code&gt;nodemon.json&lt;/code&gt; config file to the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;nodemon.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then add the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ext"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".ts,.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ignore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ts-node ./src/index.ts"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever you use &lt;code&gt;nodemon&lt;/code&gt; in the command line, it will use these configurations.&lt;/p&gt;

&lt;p&gt;A typical script to run your local dev environment is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's set that up now. Open up your &lt;code&gt;package.json&lt;/code&gt; file and add this script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  ...

  "scripts": {
    ...
    // for running the server on your local machine, using nodemon
    "dev": "nodemon"
  },

  ...
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run &lt;code&gt;npm run dev&lt;/code&gt; in the root of your project to start up your server (which we'll do in the next step when we add a &lt;code&gt;index.ts&lt;/code&gt; file).&lt;/p&gt;

&lt;p&gt;We'll set up the &lt;code&gt;build&lt;/code&gt; and &lt;code&gt;start&lt;/code&gt; scripts (for production) in a later step when we deploy to heroku.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the server with Apollo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo.png%26w%3D3840%26q%3D75" alt="Apollo GraphQL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With some of the admin out of the way, let's set up our server!&lt;/p&gt;

&lt;p&gt;We're going to use 3 packages to get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;express&lt;/code&gt;: The Javascript server side framework&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apollo-server-express&lt;/code&gt;: Allows us to setup a GraphQL API on top of Express&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;graphql&lt;/code&gt;: Allows us to write GraphQL in Javascript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's add them to our project now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express apollo-server-express graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of using &lt;code&gt;express&lt;/code&gt; and &lt;code&gt;apollo-server-express&lt;/code&gt;, we could've just gone with &lt;code&gt;apollo-server&lt;/code&gt; which is easier and simpler to get going.&lt;/p&gt;

&lt;p&gt;However, I've opted with the Express option because it means we can add Node.js middleware like authentication and rate-limiting - things you'll very likely need if you're building out an API for use in production 👌.&lt;/p&gt;

&lt;p&gt;With the packages installed, we can now whip up a server.&lt;/p&gt;

&lt;p&gt;Create an &lt;code&gt;index.ts&lt;/code&gt; file inside a directory called &lt;code&gt;src&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;src
&lt;span class="nb"&gt;touch &lt;/span&gt;src/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the following code to the new file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createServer } from "http";
import express from "express";
import { ApolloServer, gql } from "apollo-server-express";

// 1
const startServer = async () =&amp;gt; { 

  // 2
  const app = express()
  const httpServer = createServer(app)

  // 3
  const typeDefs = gql`
    type Query {
      hello: String
    }
  `;

  // 4
  const resolvers = {
    Query: {
      hello: () =&amp;gt; 'Hello world!',
    },
  };

  // 5
  const apolloServer = new ApolloServer({
    typeDefs,
    resolvers,
  })

  // 6
  await apolloServer.start()

  // 7
  apolloServer.applyMiddleware({
      app,
      path: '/api'
  })

  // 8
  httpServer.listen({ port: process.env.PORT || 4000 }, () =&amp;gt;
    console.log(`Server listening on localhost:4000${apolloServer.graphqlPath}`)
  )
}

startServer()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code starts a server and listens on port 4000.&lt;/p&gt;

&lt;p&gt;I've added numbered comments to the code - Let's dive into each part to understand what's going on here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an asynchronous function to start the server. At the end of the code, you can see the function is called &lt;code&gt;startServer()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Here we are creating an instance of express with &lt;code&gt;const app = express()&lt;/code&gt; and then creating an HTTP server with &lt;code&gt;const httpServer = createServer(app)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;typeDefs&lt;/code&gt; define your API schema. Here you describe what data can be read and mutated by the frontend. For example:

&lt;ul&gt;
&lt;li&gt;Fetch a list of items&lt;/li&gt;
&lt;li&gt;Fetch details about a profile&lt;/li&gt;
&lt;li&gt;Login a user&lt;/li&gt;
&lt;li&gt;Sign up a user&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resolvers&lt;/code&gt; are responsible for handling the logic and response for each &lt;code&gt;typeDef&lt;/code&gt; you defined. It's where the business logic is executed. Each &lt;code&gt;typeDef&lt;/code&gt; will have a matching &lt;code&gt;resolver&lt;/code&gt;. For example, in the &lt;code&gt;typeDefs&lt;/code&gt; you might have defined a &lt;code&gt;query&lt;/code&gt; to fetch a list of items. You'll need a matching &lt;code&gt;resolver&lt;/code&gt; to handle the query (e.g. find the items in the database and return them)&lt;/li&gt;
&lt;li&gt;Here you initialize an instance of ApolloServer, passing in the &lt;code&gt;typeDefs&lt;/code&gt; and &lt;code&gt;resolvers&lt;/code&gt;. This creates your GraphQL server, but as we're using Express, we'll need to apply it as middleware in the next step.&lt;/li&gt;
&lt;li&gt;You must &lt;code&gt;await apolloServer.start()&lt;/code&gt; before applying the ApolloServer instance as middleware&lt;/li&gt;
&lt;li&gt;The ApolloServer instance is applied as middleware to the Express instance, enabling the GraphQL server. GraphQL is served over a single endpoint in contrast to REST APIs which expose a range of endpoints. By default, Apollo sets this endpoint to &lt;code&gt;/graphql&lt;/code&gt;, but I've updated it to &lt;code&gt;/api&lt;/code&gt; - this is optional.&lt;/li&gt;
&lt;li&gt;If you've built any Express applicatons before, this step will be familiar to you. Here, we are telling the server to listen on a specific port, and log something to the server. We first look in a env file for the PORT key, and if it doesn't exist, then we'll use 4000 by default. The reason for the env lookup is for when we deploy with Heroku - using the env key allows the port to be defined by Heroku (otherwise there may be errors, such as a request timeout)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nice work if you've made it this far!&lt;/p&gt;

&lt;p&gt;Let's now start our server using the script we set up earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In response, the terminal should output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Server listening on localhost:4000/api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ss&lt;br&gt;&lt;br&gt;
Open &lt;code&gt;localhost:4000/api&lt;/code&gt; in your browser and you'll be prompted to enter Apollo Studio. Press the "Query your server" button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo-studio.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo-studio.png%26w%3D3840%26q%3D75" alt="Apollo Studio"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a testing environment for you to run your GraphQL queries and mutations.&lt;/p&gt;

&lt;p&gt;For example, write the following query on the left side and hit the &lt;strong&gt;Run&lt;/strong&gt; button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see on the right hand side the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello world!"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo-studio-query.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo-studio-query.png%26w%3D3840%26q%3D75" alt="Apollo Studio Query"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You've just set up the foundations for a GraphQL API! Great work.&lt;/p&gt;

&lt;p&gt;Everything you'll do from here will build on top of this foundational mental model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;typeDefs&lt;/code&gt; describe the queries and mutations available in the API&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resolvers&lt;/code&gt; handle the logic and send the data back in the response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up, we'll be adding some more scripts and configuring our deployment to our production environment, Heroku.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy to Heroku
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku.png%26w%3D3840%26q%3D75" alt="Heroku"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might be thinking:&lt;/p&gt;

&lt;p&gt;"Isn't it too soon in the project to worry about deployment?"&lt;/p&gt;

&lt;p&gt;Possibly. It's down to personal preference.&lt;/p&gt;

&lt;p&gt;I prefer to &lt;a href="https://en.wikipedia.org/wiki/Release_early,_release_often" rel="noopener noreferrer"&gt;release early and often&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just like running the command &lt;code&gt;npm run dev&lt;/code&gt; to run your server on your local machine, Heroku needs to know about a command so it can execute the script to start the server. &lt;/p&gt;

&lt;p&gt;We'll create 2 scripts: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt; - This will clean and compile our TypeScript code so it's ready for production&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;start&lt;/code&gt; - This will first run the &lt;code&gt;build&lt;/code&gt; command and then it will execute the compiled code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to run the &lt;code&gt;build&lt;/code&gt; script, we need to install a package called &lt;code&gt;rimraf&lt;/code&gt; which takes care of the cleaning for us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;rimraf &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can add both the &lt;code&gt;build&lt;/code&gt; and &lt;code&gt;start&lt;/code&gt; scripts to your &lt;code&gt;package.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  ...

  "scripts": {
    ...
    "dev": "nodemon",
    "build": "rimraf ./build &amp;amp;&amp;amp; tsc",
    "start": "npm run build &amp;amp;&amp;amp; node build/index.js",
  },

  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay nice work! Your scripts are all now set up, so let's configure Heroku for deployment.&lt;/p&gt;

&lt;p&gt;Firstly, You need to add a &lt;a href="https://devcenter.heroku.com/articles/procfile" rel="noopener noreferrer"&gt;Procfile&lt;/a&gt; (this is a special Heroku file that tells the server what command to run when the application launches) to the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Procfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go into this new Procfile and add the following (this leverages the script we defined in the &lt;code&gt;package.json&lt;/code&gt; file we added earlier on).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay! Make sure you've pushed up all the changes up to Github, then log in to your Heroku account.&lt;/p&gt;

&lt;p&gt;First, &lt;a href="https://dashboard.heroku.com/new-app" rel="noopener noreferrer"&gt;create a new app&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fcreate-heroku-app.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fcreate-heroku-app.png%26w%3D3840%26q%3D75" alt="Create Heroku App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, connect the project to the Github repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fconnect-github.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fconnect-github.png%26w%3D3840%26q%3D75" alt="Connect to Github"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then enable automatic deploys. This will mean every time you push a commit to the master branch, it will deploy a new version of the app:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fautomatic-heroku-deploys.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fautomatic-heroku-deploys.png%26w%3D3840%26q%3D75" alt="Enable automatic deploys"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default, Heroku prunes the &lt;code&gt;devDependencies&lt;/code&gt; when the server is launched. This is problematic as the server needs to use the &lt;code&gt;rimraf&lt;/code&gt; script for the &lt;code&gt;build&lt;/code&gt; script.&lt;/p&gt;

&lt;p&gt;Therefore, you need to add an ENV variable in the Heroku app called &lt;code&gt;NPM_CONFIG_PRODUCTION=false&lt;/code&gt;. Go to the &lt;strong&gt;Settings&lt;/strong&gt; tab and add a Config Vars:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-config-vars.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-config-vars.png%26w%3D3840%26q%3D75" alt="Heroku Config Vars"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, go back to the &lt;strong&gt;Deploy&lt;/strong&gt; tab and press the Deploy Branch button to deploy the app:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-deploy.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-deploy.png%26w%3D3840%26q%3D75" alt="Heroku deploy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once it's finished, press the "Open app" in the top right, and edit the url to end in &lt;code&gt;/api&lt;/code&gt; which is the path you defined in an earlier step.&lt;/p&gt;

&lt;p&gt;And there you have it, you should see Apollo's default screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo-production.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fapollo-production.png%26w%3D3840%26q%3D75" alt="GraphQL playground"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you'd like to enable the GraphQL playground on the production environment, take a look at the &lt;a href="https://www.apollographql.com/docs/apollo-server/api/plugin/landing-pages/" rel="noopener noreferrer"&gt;Apollo docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nice work! You've just set up a very basic GraphQL API and deployed it to production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up Postgres locally with Docker
&lt;/h2&gt;

&lt;p&gt;There's a little more admin work we need to do before we get into the fun stuff.&lt;/p&gt;

&lt;p&gt;The goal for this tutorial is build a GraphQL API that can query and mutate directly to a database.&lt;/p&gt;

&lt;p&gt;That means we'll need access to a database in our local and deployed environments.&lt;/p&gt;

&lt;p&gt;We will set up the Postgres server for our deployed application in Heroku in &lt;a href="https://dev.to/graphql-api-setup#adding-postgres-to-heroku"&gt;the final step&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We'll use &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; for our local database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fdocker.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fdocker.png%26w%3D3840%26q%3D75" alt="Docker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're comfortable configuring your database server locally (e.g. you might use the &lt;a href="https://postgresapp.com" rel="noopener noreferrer"&gt;Postgres app&lt;/a&gt; instead of Docker), you can skip this section.&lt;/p&gt;

&lt;p&gt;That being said, Docker is pretty simple to setup, so as long as you have Docker installed on your machine, I'll walk you through it.&lt;/p&gt;

&lt;p&gt;First of all, add a new file to the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then navigate to this file and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'
services:
  postgres:
    image: postgres:10.3
    restart: always
    environment:
      - POSTGRES_USER=test-user
      - POSTGRES_PASSWORD=test-password
    volumes:
      - postgres:/var/lib/postgresql/data
    ports:
      - '5432:5432'
volumes:
  postgres:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file is responsible for running the Postgres server on your local machine.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;environment&lt;/code&gt; variables set the credentials for the database which we'll use when connecting Prisma to the database.&lt;/p&gt;

&lt;p&gt;Now go ahead and launch this server by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using VSCode, I recommend installing the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker" rel="noopener noreferrer"&gt;official Docker extension&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once installed, it will apear in your left menu and show you which containers (i.e. local servers) you have running:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fdocker-vscode-extension.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fdocker-vscode-extension.png%26w%3D3840%26q%3D75" alt="Cocker VSCode extension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice work, your local Postgres server is now up and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build your database schema with Prisma
&lt;/h2&gt;

&lt;p&gt;In order for our GraphQL API to query and mutate data to a database, we first need to define how the database is structured.&lt;/p&gt;

&lt;p&gt;We're going to use &lt;a href="https://prisma.io/" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt; to define this structure. We'll also use Prisma in the next section to connect our GraphQL API to the database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fprisma.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fprisma.png%26w%3D3840%26q%3D75" alt="Prisma.io"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can think of Prisma as a bridge between your database and your API - they provide a set of tools that make working with databases much easier.&lt;/p&gt;

&lt;p&gt;First of all, add the Prisma CLI as a development dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;prisma &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to use the Prisma CLI moving forward (the Prisma CLI is always prefixed with &lt;code&gt;npx&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Next you need to set up Prisma in your project by running this command in the root of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates a directory called &lt;code&gt;prisma&lt;/code&gt; with a file inside called &lt;code&gt;schema.prisma&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Adds an &lt;code&gt;.env&lt;/code&gt; file to the root of the project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's first move the &lt;code&gt;prisma&lt;/code&gt; directory into the &lt;code&gt;src&lt;/code&gt; directory to keep things clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mv &lt;/span&gt;prisma/ src/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because we've moved the prisma directory, we just need to add this to our &lt;code&gt;package.json file&lt;/code&gt; so Prisma knows where to find it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  ...

  "prisma": {
    "schema": "src/prisma/schema.prisma"
  }

  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;schema.prisma&lt;/code&gt; file is the main configuration file for Prisma. If you open up the file, you'll see the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;datasource&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;db&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;provider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgresql"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;url&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;env(&lt;/span&gt;&lt;span class="s2"&gt;"DATABASE_URL"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;generator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;provider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prisma-client-js"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;datasource&lt;/code&gt; provides the connection to your Postgres database by looking up a url in the ENV file.&lt;/p&gt;

&lt;p&gt;This is important - by using the env file, it allows us to have a different Postgres database for our various environments.&lt;/p&gt;

&lt;p&gt;Right now, we have a local environment and a production environment in Heroku. We'll configure the Heroku Postgres database in &lt;a href="https://dev.to/graphql-api-setup#adding-postgres-to-heroku"&gt;the final step&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your local Postgres server already exists (as we set this up in the previous step) - so we just need to grab these credentials and update our env file.&lt;/p&gt;

&lt;p&gt;Open your &lt;code&gt;docker-compose.yml&lt;/code&gt; file and grab the environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
  postgres:
    ...
    environment:
      - POSTGRES_USER=test-user
      - POSTGRES_PASSWORD=test-password
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, the user is &lt;code&gt;test-user&lt;/code&gt; and the password is &lt;code&gt;test-password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can update these to your liking, but just make sure you restart your local Postgres server and then add the values to your env file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;DATABASE_URL=&lt;/span&gt;&lt;span class="s2"&gt;"postgresql://test-user:test-password@localhost:5432/mydb?schema=public"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your Prisma configuration is using your local Postgres server as the data source.&lt;/p&gt;

&lt;p&gt;It's now time to get to the fun stuff - creating tables in your database.&lt;/p&gt;

&lt;p&gt;This is done inside the Prisma configuration file (&lt;code&gt;schema.prisma&lt;/code&gt;) by adding models and then running a special Prisma command.&lt;/p&gt;

&lt;p&gt;This tutorial won't get in to much detail on how to use Prisma - we'll stick to a simple example that you can expand on - &lt;a href="https://www.prisma.io/docs/" rel="noopener noreferrer"&gt;their docs&lt;/a&gt; are very good.&lt;/p&gt;

&lt;p&gt;Let's say we are building a Trello clone.&lt;/p&gt;

&lt;p&gt;We could start with a model for the "Board". Add the following to your &lt;code&gt;prisma.schema&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;datasource&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;db&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;generator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;prisma&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;model&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Board&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="k"&gt;@id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;@default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;autoincrement&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;@default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;updatedAt&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;@updatedAt&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;@unique&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is fairly self-explanatory (which is a testament to the Prisma team in itself!). Either way, here's a quick explainer of what's happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new model (i.e. table in the database) has been defined as "Board"&lt;/li&gt;
&lt;li&gt;The table is defined with a field name, a field type and optional attributes

&lt;ul&gt;
&lt;li&gt;The field name maps to the column in that table. Typically is camelCase.&lt;/li&gt;
&lt;li&gt;The field type defines the native database type&lt;/li&gt;
&lt;li&gt;Attributes are handy modifiers Prisma provide you. E.g. the &lt;code&gt;@unique&lt;/code&gt; attribute on the &lt;code&gt;path&lt;/code&gt; field means that each record in the "Board" table must have a unique string stored as a path.&lt;/li&gt;
&lt;li&gt;You may have noticed the &lt;code&gt;?&lt;/code&gt; appended to the &lt;code&gt;String&lt;/code&gt; field type for the description. This is a type modifier. &lt;code&gt;?&lt;/code&gt; makes a field optional.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If you open a GUI tool like TablePlus and open up your local Postrgres server to view the tables, you'll see nothing.&lt;/p&gt;

&lt;p&gt;That's because we need to run a Prisma command to map the model you've defined into your database (i.e. run "migrations").&lt;/p&gt;

&lt;p&gt;Here's the command to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma migrate dev &lt;span class="nt"&gt;--name&lt;/span&gt; init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everytime you add a new model (or tweak any existing model structure), you'll need to run this command. So I find it helpful to add a new script for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  ...

  "scripts": {
    "dev": "nodemon",
    "build": "rimraf ./build &amp;amp;&amp;amp; tsc",
    "start": "npm run build &amp;amp;&amp;amp; node build/index.js",
    // for running database migrations
    "migrate": "npx prisma migrate dev",
  },

  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now anytime you need to run migrations you can run &lt;code&gt;npm run migrate&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Great work, you just created your first table in a database with Prisma Migrate 🎉.&lt;/p&gt;

&lt;p&gt;Now open up your GUI again and your table will be there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Ftableplus.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Ftableplus.png%26w%3D3840%26q%3D75" alt="TablePlus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can take this example further by adding other models to your &lt;code&gt;prisma.schema&lt;/code&gt; file, for example by adding some &lt;a href="https://www.prisma.io/docs/concepts/components/prisma-schema/relations/" rel="noopener noreferrer"&gt;relations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just remember everytime you make changes to your models, you'll need to run your new script &lt;code&gt;npm run migrate&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Whenever you run &lt;code&gt;npm run migrate&lt;/code&gt;, you'll be prompted to add a name for the migration. This is optional, but a good idea to give the migration a name so you can easily look at your migration history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect database to Graphql API
&lt;/h2&gt;

&lt;p&gt;So we've defined the structure of our database with Prisma Models.&lt;/p&gt;

&lt;p&gt;Now let's move into how we can access and manipulate that data.&lt;/p&gt;

&lt;p&gt;We'll use Prisma Client to help make queries to our database. For that, we'll need to install an additional Prisma package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @prisma/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One this package is installed, create a new file inside the &lt;code&gt;prisma&lt;/code&gt; directory called &lt;code&gt;client.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;prisma/client.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then inside this new file, you need to instantiate the Prisma Client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@prisma/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PrismaClient&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now inside your &lt;code&gt;src/index.ts&lt;/code&gt; file, you can import Prisma client so it's available to use for your queries and mutations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApolloServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-server-express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../prisma/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, with that set up, let's build on our Trello clone example and use Prisma Client to fetch a list of "Boards" from the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fetch a list of boards
&lt;/h3&gt;

&lt;p&gt;Before we dive in to adding this a query for fetching a list of boards, it's worth adding some data to our database.&lt;/p&gt;

&lt;p&gt;Otherwise, we'll build our query and get back empty results. Adding some records to the database will help us to validate our queries are working properly.&lt;/p&gt;

&lt;p&gt;Thankfully, Prisma have made this super easy.&lt;/p&gt;

&lt;p&gt;Run this command to open up &lt;a href="https://www.prisma.io/studio" rel="noopener noreferrer"&gt;Prisma Studio&lt;/a&gt;, a simple way to explore and manipulate the data in the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma studio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will open Prisma Studio in a new tab in your browser, looking something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fprisma-studio.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fprisma-studio.png%26w%3D3840%26q%3D75" alt="Prisma Studio"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate into the &lt;code&gt;Board&lt;/code&gt; model and press the "Add record" button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fprisma-studio-add-record.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fprisma-studio-add-record.png%26w%3D3840%26q%3D75" alt="Prisma Studio - Add record"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, back to writing some GraphQL.&lt;/p&gt;

&lt;p&gt;We want to write a query that looks up all &lt;code&gt;Boards&lt;/code&gt; in the database, and returns them in an array.&lt;/p&gt;

&lt;p&gt;Let's hop back into our &lt;code&gt;src/index.ts&lt;/code&gt; file and add a new &lt;code&gt;typeDef&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...

const typeDefs = gql`
  type Query {
    boards: [Board]
  }

  type Board {
    id: ID!
    title: String!
    description: String
    path: String!
  }
`;

...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The purpose of &lt;code&gt;typeDefs&lt;/code&gt; is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define the name of the query / mutation&lt;/li&gt;
&lt;li&gt;Define the structure of the response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So here, we are creating a query called &lt;code&gt;boards&lt;/code&gt;. This is the name of the query.&lt;/p&gt;

&lt;p&gt;And you can see that this query returns &lt;code&gt;[Board]&lt;/code&gt;. This defines the structure of the response. We're basically saying here:&lt;/p&gt;

&lt;p&gt;When a &lt;code&gt;boards&lt;/code&gt; query is called to the server, return an array (that's what the square brackets are for) of items, and each item should have the structure defined by the &lt;code&gt;Board&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;But we've still not hooked up that array to retrieve data from the database - that's where resolvers come in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...

const resolvers = {
  Query: {
    boards: () =&amp;gt; {
      return prisma.board.findMany()
    }
  },
};

...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we're using a Prisma Client query called &lt;code&gt;findMany&lt;/code&gt;, which pulls in all of the records.&lt;/p&gt;

&lt;p&gt;If you now start up your server with &lt;code&gt;npm run dev&lt;/code&gt; and run the query in the left section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;boards&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming you added some records with Prisma studio, your API will return a response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fgraph-query-boards.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fgraph-query-boards.png%26w%3D3840%26q%3D75" alt="Querying boards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great work! You now have an GraphQL API that fetches data from a database.&lt;/p&gt;

&lt;p&gt;If you're following this tutorial, review the Prisma docs and try to build out some CRUD functionality for "Boards":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new board&lt;/li&gt;
&lt;li&gt;View a board&lt;/li&gt;
&lt;li&gt;Edit a board&lt;/li&gt;
&lt;li&gt;Delete a board&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding Postgres to Heroku
&lt;/h2&gt;

&lt;p&gt;Our API is working locally.&lt;/p&gt;

&lt;p&gt;With our local Postgres server and running &lt;code&gt;npm run dev&lt;/code&gt;, we can run queries and mutations on our GraphQL API to view and manipulate data in our local database.&lt;/p&gt;

&lt;p&gt;However, this is currently limited to our local machine.&lt;/p&gt;

&lt;p&gt;The final step in this tutorial is to add to our Heroku set up we &lt;a href="https://dev.to/graphql-api-setup#deploy-to-heroku"&gt;started earlier on&lt;/a&gt; by adding a hosted Postrges server.&lt;/p&gt;

&lt;p&gt;Inside your Heroku project, navigate to the Resources tab, search for "Heroku Postgres" and enable the "Hobby Dev" plan:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-postgres-addon.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-postgres-addon.png%26w%3D3840%26q%3D75" alt="Adding Postgres"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a free plan so you won't be charged for it.&lt;/p&gt;

&lt;p&gt;Once you've added this, if you navigate to the Settings tab and look at the Config Vars, you'll see that the &lt;code&gt;DATABASE_URL&lt;/code&gt; has been added automatically for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-config-vars.png%26w%3D3840%26q%3D75" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftomray.dev%2F_next%2Fimage%3Furl%3D%252Fimages%252Fgraphql-api-setup%252Fheroku-config-vars.png%26w%3D3840%26q%3D75" alt="Check Heroku Config Vars"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Config Vars in Heroku is the env file equivalent.&lt;/p&gt;

&lt;p&gt;If you navigate to your &lt;code&gt;prisma.schema&lt;/code&gt; file, you'll see that the datasource is pointing towards the &lt;code&gt;DATABASE_URL&lt;/code&gt; in the env file.&lt;/p&gt;

&lt;p&gt;This means that in the deployed Heroku environment, it will use the &lt;code&gt;DATABASE_URL&lt;/code&gt; defined in the Config Vars.&lt;/p&gt;

&lt;p&gt;The final step is the considerations for the database changes.&lt;/p&gt;

&lt;p&gt;If you make some changes to the Prisma Models in your local machine and then run the &lt;code&gt;npm run migrate&lt;/code&gt; command, this will make the database changes to your local database server.&lt;/p&gt;

&lt;p&gt;However, the hosted database in Heroku will not know about these changes.&lt;/p&gt;

&lt;p&gt;Therefore, you need to add a command that tells Heroku to run a migration command whenever there is a new deployment.&lt;/p&gt;

&lt;p&gt;You can achieve this by adding to your Procfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: npm start
release: npx prisma migrate deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you're done!&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href="https://github.com/tomwray13/graphql-typescript-api-starter/issues" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt; again if you'd like to review the code. The repository is available as a Template Repository, which means you can use it as a starter repo for your next project!&lt;/p&gt;

&lt;p&gt;If you have any questions about this tutorial, drop a comment below, open up an issue in the &lt;a href="https://github.com/tomwray13/graphql-typescript-api-starter/issues" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt; or send me a DM on &lt;a href="https://twitter.com/bytomray" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>heroku</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Styled Components: A Quick Start Guide</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Sun, 09 Aug 2020 17:27:48 +0000</pubDate>
      <link>https://dev.to/bytomray/styled-components-a-quick-start-guide-jm9</link>
      <guid>https://dev.to/bytomray/styled-components-a-quick-start-guide-jm9</guid>
      <description>&lt;p&gt;This is a quick start guide to learning &lt;a href="https://styled-components.com/"&gt;Styled Components&lt;/a&gt;, the component-driven CSS methodology. &lt;/p&gt;

&lt;p&gt;If you want to start practicing and applying Styled Components to your projects, this guide will help you get started.&lt;/p&gt;

&lt;p&gt;Ready? Let's dive in:&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; &lt;a href="https://scalablecss.com/styled-components-cheat-sheet/"&gt;Download a free cheat sheet&lt;/a&gt; that will show you how to quickly get started with styled-components.&lt;/p&gt;




&lt;h2&gt;
  
  
  Contents:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Styled Components Overview&lt;/li&gt;
&lt;li&gt;Installing styled-components&lt;/li&gt;
&lt;li&gt;Building your first Styled Component&lt;/li&gt;
&lt;li&gt;Using props to customise Styled Components&lt;/li&gt;
&lt;li&gt;How to make your styled-components responsive&lt;/li&gt;
&lt;li&gt;How to handle pseudo-selectors with Styled Components&lt;/li&gt;
&lt;li&gt;Creating global styles&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Styled Components Overview
&lt;/h2&gt;

&lt;p&gt;Styled Components is a library for React &amp;amp; React Native to write and manage your CSS.&lt;/p&gt;

&lt;p&gt;It's a "CSS-in-JS" solution, meaning you write your CSS in Javascript files (specifically within your components, which are Javascript files).&lt;/p&gt;

&lt;p&gt;It's an extremely popular solution for managing CSS in React, with around 8 million &lt;a href="https://www.npmjs.com/package/styled-components"&gt;npm downloads/month&lt;/a&gt; and 30k stars in &lt;a href="https://github.com/styled-components/styled-components"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A familiarity and understanding of React is recommended before diving into Styled Components.&lt;/p&gt;

&lt;p&gt;A few benefits of the styled-components library are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's plain CSS. Yes, you're writing the CSS in a JS file, but the CSS syntax is unchanged.&lt;/li&gt;
&lt;li&gt;Vendor prefixes are automatically added when using Styled Components, improving performance across browsers.&lt;/li&gt;
&lt;li&gt;All unused CSS and styling gets removed automatically&lt;/li&gt;
&lt;li&gt;You don't write any class names, whatsoever. Class names are generated automatically, so there's no need to manage a CSS class naming methodology like BEM. (This'll make more sense as you go through the article)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing styled-components
&lt;/h2&gt;

&lt;p&gt;To get started with styled-components, you first need to install it into your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;styled-components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And on every file that you use styled-components, you'll need to add this import:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! You're ready to start working with styled-components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building your first styled component
&lt;/h2&gt;

&lt;p&gt;Open up an existing React project you're working on (or quickly whip up a new project with &lt;a href="https://create-react-app.dev/"&gt;create-react-app&lt;/a&gt;), and open up one of your existing components.&lt;/p&gt;

&lt;p&gt;Here, you can add your first Styled Component. &lt;/p&gt;

&lt;p&gt;Now that you have &lt;code&gt;styled&lt;/code&gt; imported, here's how you get started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Button component that'll render an &amp;lt;a&amp;gt; tag with some styles&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  background-colour: teal;
  color: white;
  padding: 1rem 2rem;
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I am a button&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break this code down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Just like writing a React functional component, declare the name of the component with &lt;code&gt;const Button&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;styled&lt;/code&gt; is what we imported above, and gives us the Styled Components functionality&lt;/li&gt;
&lt;li&gt;Notice the &lt;code&gt;a&lt;/code&gt; after &lt;code&gt;styled&lt;/code&gt;? This represents the anchor HTML element: &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;. When declaring a Styled Component, you can use any HTML element here (e.g. &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sense?&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;Button&amp;gt;&lt;/code&gt; returned inside the App component looks like a normal React component. And that's because it is a React component! &lt;/p&gt;

&lt;p&gt;In our previous example, we created a Styled Component inside an existing component.&lt;/p&gt;

&lt;p&gt;But you can also create a Styled Component in its own file.&lt;/p&gt;

&lt;p&gt;For example, create a new component file called Button.js, and add a Styled Component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  background-colour: teal;
  color: white;
  padding: 1rem 2rem;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Button&lt;/code&gt; now works like any other React component. For example, we can now import this component into other components files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// import the styled component:&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I am a button&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it! &lt;/p&gt;

&lt;p&gt;Congratulations, you just built your first Styled Component!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using props to customize Styled Components
&lt;/h2&gt;

&lt;p&gt;Imagine you have a &lt;code&gt;&amp;lt;Button /&amp;gt;&lt;/code&gt; component, and you need to style different variants of that button (primary, secondary, danger, etc).&lt;/p&gt;

&lt;p&gt;Styled Components have an elegant solution for this, where you leverage props to make your component styles dynamic.&lt;/p&gt;

&lt;p&gt;Let's dive right into an example to show you what I mean.&lt;/p&gt;

&lt;p&gt;Here we are rendering two Button components, one with a &lt;code&gt;primary&lt;/code&gt; prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I am a button&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I am a primary button&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, inside our &lt;code&gt;&amp;lt;Button /&amp;gt;&lt;/code&gt; component, we can add the dynamic styles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  border: 2px solid white;
  background: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;palevioletred&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
  color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;palevioletred&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's happening here is you're interpolating a function that is returning a CSS value (using a ternary operator) based on the props.&lt;/p&gt;

&lt;p&gt;That was quite a mouthful. &lt;/p&gt;

&lt;p&gt;To put it more simply, &lt;code&gt;background: ${props =&amp;gt; props.primary ? 'white' : 'palevioletred' }&lt;/code&gt; essentially means: &lt;/p&gt;

&lt;p&gt;If the prop &lt;code&gt;primary&lt;/code&gt; is true, then the background should be &lt;code&gt;white&lt;/code&gt;, else the background should be &lt;code&gt;palevioletred&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Handling props like this works in some use-cases, but it can get messy if you have multiple props (e.g. primary, secondary, danger, etc.) as well as multiple lines of CSS.&lt;/p&gt;

&lt;p&gt;Often, it makes more sense to import &lt;code&gt;{ css }&lt;/code&gt; from &lt;code&gt;styled-components&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="s2"&gt;`
    background: white;
    color: palevioletred;
  `&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps your dynamic styles separate for different props. &lt;/p&gt;

&lt;p&gt;For example, adding styles for a &lt;code&gt;danger&lt;/code&gt; prop would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="s2"&gt;`
    background: white;
    color: palevioletred;
  `&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;danger&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="s2"&gt;`
    background: red;
    color: white;
  `&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice! We're making some good progress.&lt;/p&gt;

&lt;p&gt;How about making this &lt;code&gt;&amp;lt;Button /&amp;gt;&lt;/code&gt; a little more responsive, eh?&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; &lt;a href="https://scalablecss.com/styled-components-cheat-sheet/"&gt;Download a free cheat sheet&lt;/a&gt; that will show you how to quickly get started with BEM.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using media-queries to make your styled-components responsive
&lt;/h2&gt;

&lt;p&gt;Thankfully, making your Styled Components responsive is super simple.&lt;/p&gt;

&lt;p&gt;Add media queries inside your template literal, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 9rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  @media (min-width: 768px) { 
    padding: 1rem 2rem;
    width: 11rem;
  }

  @media (min-width: 1024px) { 
    padding: 1.5rem 2.5rem;
    width: 13rem;
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're looking for a more involved example with multiple different device sizes, I recommend checking out this &lt;a href="https://jsramblings.com/how-to-use-media-queries-with-styled-components/"&gt;Javascript Ramblings article&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling hover states and other pseudo-selectors with Styled Components
&lt;/h2&gt;

&lt;p&gt;Similarly to adding media queries to your Styled Components, adding pseudo selectors is pretty straightforward.&lt;/p&gt;

&lt;p&gt;For example, adding a hover state to our &lt;code&gt;&amp;lt;Button /&amp;gt;&lt;/code&gt; component would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 9rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  :hover {
    border-color: green;
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating global styles
&lt;/h2&gt;

&lt;p&gt;One of the main mental models of React is how you treat everything as components.&lt;/p&gt;

&lt;p&gt;You essentially break an interface down into tiny chunks and piece it all together in a scalable way.&lt;/p&gt;

&lt;p&gt;This approach comes with many advantages, but does however surface a challenge:&lt;/p&gt;

&lt;p&gt;How to style parts of your design that are consistent across multiple components?&lt;/p&gt;

&lt;p&gt;Or put another way:&lt;/p&gt;

&lt;p&gt;How can you set &lt;a href="https://dev.to/styled-components-global-styles"&gt;global styles&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;For example, you might want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set a font-family for all your typography&lt;/li&gt;
&lt;li&gt;Set the background color on every page&lt;/li&gt;
&lt;li&gt;Override some browser default styling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Styled Components has a solution for global styles using the &lt;code&gt;createGlobalStyle&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;First, navigate to the component which is at the top of your React tree.&lt;/p&gt;

&lt;p&gt;For example, if you're working in a create-react-app project, that'll be your &lt;code&gt;App.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Here, you'll need to import &lt;code&gt;createGlobalStyle&lt;/code&gt; into your project, and set some styles to a &lt;code&gt;GlobalStyle&lt;/code&gt; component (you can name this component how you like):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Nav&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`
  body {
    margin: 0;
    padding: 0;
    background: teal;
    font-family: Open-Sans, Helvetica, Sans-Serif;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nav&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't going to apply the styles to the project &lt;strong&gt;yet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we need to &lt;strong&gt;use&lt;/strong&gt; the &lt;code&gt;GlobalStyle&lt;/code&gt; component to apply the global styles to the application.&lt;/p&gt;

&lt;p&gt;You do this by placing the &lt;code&gt;GlobalStyle&lt;/code&gt; component at the top of your React tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Nav&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`
  body {
    margin: 0;
    padding: 0;
    background: teal;
    font-family: Open-Sans, Helvetica, Sans-Serif;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GlobalStyle&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nav&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the use of &lt;a href="https://reactjs.org/docs/fragments.html#short-syntax"&gt;fragments short syntax&lt;/a&gt;? &lt;/p&gt;

&lt;p&gt;This is required as you're placing the &lt;code&gt;&amp;lt;GlobalStyle /&amp;gt;&lt;/code&gt; component as a sibling at the top of the tree.&lt;/p&gt;

&lt;p&gt;And that's it! &lt;/p&gt;

&lt;p&gt;Global styling is now all set up with Styled Components. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Nice job if you've made it all the way to the end.&lt;/p&gt;

&lt;p&gt;We covered a lot! Specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Styled Components are and why you should consider using them&lt;/li&gt;
&lt;li&gt;How to install styled-components&lt;/li&gt;
&lt;li&gt;Building your first styled component&lt;/li&gt;
&lt;li&gt;Making your Styled Components dynamic with props&lt;/li&gt;
&lt;li&gt;Using media queries to make your Styled Components responsive&lt;/li&gt;
&lt;li&gt;How to handle pseudo selectors with Styled Components&lt;/li&gt;
&lt;li&gt;Setting global styles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are the fundamentals to get you off and running with Styled Components.&lt;/p&gt;

&lt;p&gt;Like learning anything new, practicing is key. Give Styled Components a shot in your next project and see where it takes you!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Download Free Styled Components Cheat Sheet&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Want to start practicing styled-components and looking for a no-nonsense, quick start action guide?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scalablecss.com/styled-components-cheat-sheet"&gt;Download a free cheat sheet&lt;/a&gt; covering styled-components basics so you can dive in and start practicing today.&lt;/p&gt;




</description>
      <category>css</category>
      <category>styledcomponents</category>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>How to Create Global Styles with Styled Components</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Tue, 02 Jun 2020 14:46:13 +0000</pubDate>
      <link>https://dev.to/bytomray/how-to-create-global-styles-with-styled-components-5gec</link>
      <guid>https://dev.to/bytomray/how-to-create-global-styles-with-styled-components-5gec</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--03HNdGrO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/isqh71s897aqljm2k7bk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--03HNdGrO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/isqh71s897aqljm2k7bk.png" alt="Global styles in styled-components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've opted to use &lt;a href="https://styled-components.com/"&gt;styled-components&lt;/a&gt; as a solution for managing your CSS, you'll quickly ask yourself:&lt;/p&gt;

&lt;p&gt;The Styled Components library is all about styling individual components. So how can you apply styles globally to an application? &lt;/p&gt;

&lt;p&gt;For example, you might want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set a font-family for all your typography&lt;/li&gt;
&lt;li&gt;Set the background color on every page&lt;/li&gt;
&lt;li&gt;Override some browser default styling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, I'll dive into exactly how you can achieve this with the &lt;a href="https://styled-components.com/docs/api#createglobalstyle"&gt;createGlobalStyle&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; This solution is only applicable to web, so this &lt;strong&gt;won't&lt;/strong&gt; work for react-native!&lt;/p&gt;

&lt;p&gt;Ready? Let's do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a global styles file
&lt;/h2&gt;

&lt;p&gt;The first step is to create a file that contains all your global styles. &lt;/p&gt;

&lt;p&gt;Inside your &lt;code&gt;src/&lt;/code&gt; folder, add a file called &lt;code&gt;globalStyles.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here, we'll use the &lt;code&gt;createGlobalStyle&lt;/code&gt; function from styled-components and add some global styles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// globalStyles.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`
  body {
    margin: 0;
    padding: 0;
    background: teal;
    font-family: Open-Sans, Helvetica, Sans-Serif;
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the GlobalStyle variable is where you define all your global styles.&lt;/p&gt;

&lt;p&gt;This isn't going to apply the styles to the project &lt;strong&gt;yet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we need to &lt;strong&gt;use&lt;/strong&gt; that file to apply the global styles to the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Place GlobalStyle at the top of your React tree
&lt;/h2&gt;

&lt;p&gt;Find your component which is at the top of your React tree. &lt;/p&gt;

&lt;p&gt;In many react applications, that's typically the &lt;code&gt;App.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Here, import your GlobalStyle component and place it inside the the top of your React tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Fragment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./theme/globalStyle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GlobalStyle&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code example, &lt;code&gt;&amp;lt;Content /&amp;gt;&lt;/code&gt; is a component that contains all the other components for the application.&lt;/p&gt;

&lt;p&gt;This is just an example, and you might structure the top of your React tree differently, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Fragment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./theme/globalStyle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Wrapper&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Wrapper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Nav&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Nav&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GlobalStyle&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Wrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nav&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Wrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing to remember is to place the &lt;code&gt;GlobalStyle&lt;/code&gt; component as a sibling component to your main application component(s).&lt;/p&gt;

&lt;p&gt;And that's it! &lt;/p&gt;

&lt;p&gt;Global styling is now all set up with Styled Components. &lt;/p&gt;

&lt;h2&gt;
  
  
  Download The Free Styled Components Cheat Sheet
&lt;/h2&gt;

&lt;p&gt;I'm currently working on a styled components 1-pager. &lt;a href="https://scalablecss.com/styled-components-cheat-sheet/"&gt;Grab it here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>css</category>
      <category>react</category>
      <category>styledcomponents</category>
    </item>
    <item>
      <title>Quick Start Guide to Attrs in Styled Components</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Mon, 25 May 2020 13:27:31 +0000</pubDate>
      <link>https://dev.to/bytomray/quick-start-guide-to-attrs-in-styled-components-cp3</link>
      <guid>https://dev.to/bytomray/quick-start-guide-to-attrs-in-styled-components-cp3</guid>
      <description>&lt;p&gt;When learning styled components, you may have noticed the use of &lt;code&gt;attrs&lt;/code&gt; and be thinking:&lt;/p&gt;

&lt;p&gt;Huh. What does this do? When would I need to use &lt;code&gt;attrs&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;The best way to explain the use case of &lt;code&gt;attrs()&lt;/code&gt; in styled components is to dive right into some examples.&lt;/p&gt;

&lt;p&gt;Ready? Let's do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Use Case 1: Defining Default Attributes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here I've put together a simple button styled component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
  display: block;
  font-size: 1rem;
  font-weight: bold;
  color: white;
  border-radius: 4px;
  transition: 0.2s;
  cursor: pointer;
  border: none;
  padding: 1rem;

  &amp;amp;:hover {
    opacity: 0.7;
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I'm going to use a couple of these styled button components in my app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;components/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Buttons&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello there&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Wassuuuupppp&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;   
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;   
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case you didn't know, the default type for HTML buttons is &lt;code&gt;type="submit"&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;So in my above design, when a button is clicked it will result in a page reload (becuase of the default behaviour). &lt;/p&gt;

&lt;p&gt;But what if you wanted to change the default type to &lt;code&gt;type="button"&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;Or set any HTML attribute as default for that matter?&lt;/p&gt;

&lt;p&gt;Well, you could add this as a prop directly to the component like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;components/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Buttons&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello there&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Wassuuuupppp&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;      
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;      
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if the attribute can be considered a default across your application, it's better to use the &lt;code&gt;attrs()&lt;/code&gt; function instead and define the default there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Every &amp;lt;Button /&amp;gt; will now have type="button" as default&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;`
  display: block;
  font-size: 1rem;
  font-weight: bold;
  color: white;
  border-radius: 4px;
  transition: 0.2s;
  cursor: pointer;
  border: none;
  padding: 1rem;

  &amp;amp;:hover {
    opacity: 0.7;
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much more efficient than adding a prop to every component if you find yourself turning to the same atrribute over and over.&lt;/p&gt;

&lt;p&gt;Or put another way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The rule of thumb is to use &lt;code&gt;attrs&lt;/code&gt; when you want every instance of a styled component to have that prop, and pass props directly when every instance needs a different one&lt;br&gt;
-&lt;a href="https://styled-components.com/docs/faqs#when-to-use-attrs"&gt;Styled Components Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means that we can ommit the default attribute, and only pass props when we want to change the default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;components/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Buttons&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello there&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Wassuuuupppp&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;      
      // Add a prop to override the default defined in attr
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;      
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the simplest way to get started with &lt;code&gt;attrs&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;If you're looking to get more dynamic continue on to the next use case...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Use Case 2: Defining Dynamic Props&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Building from the previous use case, using &lt;code&gt;attrs&lt;/code&gt; also allows you to attach dynamic props to a component.&lt;/p&gt;

&lt;p&gt;Sticking with our button example from use case 1, let's add a default size of our button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;`
  display: block;
  font-size: 1rem;
  font-weight: bold;
  color: white;
  border-radius: 4px;
  transition: 0.2s;
  cursor: pointer;
  border: none;
  /* define default margin and padding: */
  margin: 1rem;
  padding: 1rem;

  &amp;amp;:hover {
    opacity: 0.7;
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code will make the margin and padding for all buttons &lt;code&gt;1rem&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;We can, however, make this more dynamic. &lt;/p&gt;

&lt;p&gt;Let's say we want to make a larger version of the button, we could pass a size prop like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Buttons&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"2rem"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello there&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"3rem"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Wassuuuupppp&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;      
      // Add a prop to override the default defined in attr
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;      
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then in our styled component, we can make the margin and padding dynamic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;`
  display: block;
  font-size: 1rem;
  font-weight: bold;
  color: white;
  border-radius: 4px;
  transition: 0.2s;
  cursor: pointer;
  border: none;
  /* pass the dynamic props: */
  margin: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
  padding: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;  

  &amp;amp;:hover {
    opacity: 0.7;
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This leverages what we learned in use case 1:&lt;/p&gt;

&lt;p&gt;We set the default size as &lt;code&gt;1rem&lt;/code&gt;, but if a specific prop is passed, it overwrites the default.&lt;/p&gt;

&lt;p&gt;With this override, we can now dynamically set the margin and padding using the passed prop.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In short, the use case of &lt;code&gt;attrs()&lt;/code&gt; in styled components is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To define default HTML attributes in your styled components to save you passing the prop&lt;/li&gt;
&lt;li&gt;When you want to override the default HTML attribute, pass props to a component that dynamically styles the component &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Download The Free Styled Components Cheat Sheet&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I'm currently working on a styled components 1-pager. &lt;a href="https://scalablecss.com/styled-components-cheat-sheet/"&gt;Join the waiting list&lt;/a&gt; and be notified when it launches.&lt;/p&gt;

</description>
      <category>styledcomponents</category>
      <category>css</category>
      <category>react</category>
    </item>
    <item>
      <title>Launching BEM Basics: A Free Email Course on BEM</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Tue, 03 Mar 2020 11:58:27 +0000</pubDate>
      <link>https://dev.to/bytomray/launching-bem-basics-a-free-email-course-on-bem-5aoj</link>
      <guid>https://dev.to/bytomray/launching-bem-basics-a-free-email-course-on-bem-5aoj</guid>
      <description>&lt;p&gt;Learning BEM is tricky.&lt;/p&gt;

&lt;p&gt;Perhaps that's because BEM is a concept; a way of thinking. &lt;/p&gt;

&lt;p&gt;Applying BEM in practice was always difficult for me as I struggled to find real, practical examples.&lt;/p&gt;

&lt;p&gt;So I made a free course covering BEM fundamentals, with a focus on code snippets and examples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scalablecss.com/resource/bem-basics/"&gt;&lt;strong&gt;Get access to the free course now.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This course is a sequence of emails that you’ll receive over the next 5 days.&lt;/p&gt;

&lt;p&gt;Specifically, we’ll go over:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;BEM Overview&lt;/li&gt;
&lt;li&gt;BEM Ground Rules&lt;/li&gt;
&lt;li&gt;B - Blocks&lt;/li&gt;
&lt;li&gt;E - Elements&lt;/li&gt;
&lt;li&gt;M - Modifiers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

</description>
      <category>css</category>
      <category>bem</category>
    </item>
    <item>
      <title>How To Name Containers And Wrappers In BEM</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Tue, 18 Feb 2020 07:20:56 +0000</pubDate>
      <link>https://dev.to/bytomray/how-to-name-containers-and-wrappers-in-bem-4ebk</link>
      <guid>https://dev.to/bytomray/how-to-name-containers-and-wrappers-in-bem-4ebk</guid>
      <description>&lt;p&gt;Are you unclear on &lt;a href="https://scalablecss.com/bem-quickstart-guide/"&gt;BEM&lt;/a&gt; best practices for the naming conventions of wrapper and container CSS classes?&lt;/p&gt;

&lt;p&gt;For example, you might have multiple blocks and you need to add a wrapper class to style the positioning of those blocks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dE233ETE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/rwyzHcz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dE233ETE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/rwyzHcz.png" alt="What is BEM best practice for naming wrapper classes?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It becomes difficult to know how to name wrapper and container classes as they fall out of the 'block, element &amp;amp; modifier' mental model.&lt;/p&gt;

&lt;p&gt;Let's dive right in and look at ways to solve this.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; &lt;a href="https://scalablecss.com/resource/bem-cheat-sheet/"&gt;Download a free cheat sheet&lt;/a&gt; that will show you how to quickly get started with BEM.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Repeated Wrappers: Airbnb Example&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's a screenshot from &lt;a href="https://airbnb.com"&gt;Airbnb's&lt;/a&gt; home page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DAG5CanX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Jyy4Pl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DAG5CanX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Jyy4Pl8.png" alt="Airbnb Experiences"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thinking with your BEM hat on, you'll notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each card can be considered a BEM block (e.g. &lt;code&gt;.card&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A wrapper is required to position the 5 blocks horizontally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's how the HTML would be structured following the BEM convention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Wrapper class goes here --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__img"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h4&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__subtitle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__rating"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nc"&gt;.card__img&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nc"&gt;.card__subtitle&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nc"&gt;.card__description&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nc"&gt;.card__rating&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact, other sections of the Airbnb home page follow a similar structure. For example, the 'Airbnb Plus' section uses 3 columns instead of 5:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wlkYI52M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JapYaYO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wlkYI52M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JapYaYO.png" alt="Airbnb Plus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the question is:&lt;/p&gt;

&lt;p&gt;What is the BEM best practice naming convention for the wrappers? &lt;/p&gt;

&lt;p&gt;In this case, as there are &lt;strong&gt;repeated&lt;/strong&gt; patterns of how the wrappers work, the best approach would be to use a generic wrapper name like &lt;code&gt;.grid&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This allows you to use the wrapper in multiple places as it's not constrained with semantic meaning. &lt;/p&gt;

&lt;p&gt;For example, here's how the HTML could look for the Airbnb Experiences section:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DAG5CanX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Jyy4Pl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DAG5CanX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Jyy4Pl8.png" alt="Airbnb Experiences"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"grid grid--experiences"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.grid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-column-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.grid--experiences&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's the Airbnb Plus section:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wlkYI52M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JapYaYO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wlkYI52M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JapYaYO.png" alt="Airbnb Plus"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"grid grid--plus"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.grid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-column-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.grid--plus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using modifiers to tweak the layout, like &lt;code&gt;.grid--experiences&lt;/code&gt; and &lt;code&gt;.grid--plus&lt;/code&gt; allows you to use a generic wrapper that can be applied at scale across the design.&lt;/p&gt;

&lt;p&gt;Pretty cool, eh?&lt;/p&gt;

&lt;p&gt;But you might be thinking...&lt;/p&gt;

&lt;p&gt;How about in the example where the wrapper isn't a repeated pattern? &lt;/p&gt;

&lt;p&gt;Like a 1-off design that requires a wrapper to style a collection of BEM blocks?&lt;/p&gt;

&lt;p&gt;This will require a slightly different approach...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Unique Wrappers: Notion Example&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Take a look at this design from the &lt;a href="https://notion.so"&gt;Notion.so&lt;/a&gt; home page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---CCRaJHM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/1so7MDd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---CCRaJHM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/1so7MDd.png" alt="Notion.so features"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, thinking with your BEM hat on, you'll notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each quarter can be considered a BEM block (e.g. &lt;code&gt;.feature&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A wrapper is required to position the 4 blocks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's how the HTML could be structured following the BEM convention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Wrapper class goes here --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature__img"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature__title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature__description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.feature&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nc"&gt;.feature__img&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nc"&gt;.feature__title&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="nc"&gt;.feature__description&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's an important difference between this example and the previous Airbnb example:&lt;/p&gt;

&lt;p&gt;Looking at the design of the entire Airbnb page, it's clear that the layout of each section uses a consistent format, with slight variations (like the number of columns). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3nMAW6Uu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/CEztW7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3nMAW6Uu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/CEztW7f.png" alt="Airbnb home page layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Notion feature section, however, is contextually unique. I.e. there are no other similar sections across the website.&lt;/p&gt;

&lt;p&gt;Therefore, instead of using a generic naming convention for the wrapper as we did for Airbnb, &lt;strong&gt;a different&lt;/strong&gt; naming convention approach is required for the wrapper in the Notion example.&lt;/p&gt;

&lt;p&gt;The naming convention best approach would be to use a wrapper specific to the blocks, like &lt;code&gt;features-wrapper&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;For example, here's how the HTML could look for the Notion features section:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---CCRaJHM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/1so7MDd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---CCRaJHM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/1so7MDd.png" alt="Notion.so features"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"features-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"feature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.features-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-column-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.feature&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;So the key to naming wrapper and container classes within the BEM mental model is considering the context:&lt;/p&gt;

&lt;p&gt;Is this layout a repeated pattern that can be leveraged in many areas? &lt;/p&gt;

&lt;p&gt;If so, use a generic class name like &lt;code&gt;.grid&lt;/code&gt; or &lt;code&gt;.container&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Or is this layout unique to a collection of blocks?&lt;/p&gt;

&lt;p&gt;In this case, use a class name related to the blocks you're positioning. So if you need a wrapper class for a bunch of &lt;code&gt;.card&lt;/code&gt; blocks, then &lt;code&gt;cards-wrapper&lt;/code&gt; would work well.&lt;/p&gt;

&lt;p&gt;What do you think?&lt;/p&gt;

&lt;p&gt;How do you handle containers and wrappers when following the BEM methodology?&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Download Free BEM Cheat Sheet&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Want to start practicing BEM and looking for a no-nonsense, quick start action guide?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scalablecss.com/resource/bem-cheat-sheet"&gt;Download a free cheat sheet&lt;/a&gt; covering BEM basics so you can dive in and start practicing today.&lt;/p&gt;

</description>
      <category>css</category>
      <category>bem</category>
    </item>
    <item>
      <title>BEM Grandchildren: How To Handle Deeply Nested Elements</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Tue, 21 Jan 2020 09:07:23 +0000</pubDate>
      <link>https://dev.to/bytomray/bem-grandchildren-how-to-handle-deeply-nested-elements-2i3c</link>
      <guid>https://dev.to/bytomray/bem-grandchildren-how-to-handle-deeply-nested-elements-2i3c</guid>
      <description>&lt;p&gt;Understanding the &lt;a href="https://scalablecss.com/bem-quickstart-guide/"&gt;basic concept of BEM&lt;/a&gt; (block, element, and modifier) is a fairly simple concept to grasp.&lt;/p&gt;

&lt;p&gt;However, things can start to easily go out of control when elements start to get 3 or 4 layers nested deep within a block.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; &lt;a href="https://scalablecss.com/resource/bem-cheat-sheet/"&gt;Download a free cheat sheet&lt;/a&gt; that will show you how to quickly get started with BEM.&lt;/p&gt;




&lt;p&gt;These nested elements are typically known as 'grandchild' elements (as they're nested 2 levels deep).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P8a00YHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1579530596742/0KN9kpt0R.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P8a00YHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1579530596742/0KN9kpt0R.png" alt="bem-granchild-image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I'll tackle how to solve these common issues and follow BEM best practices.&lt;/p&gt;

&lt;p&gt;Ready? Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Chaining Elements Together - The Typical Grandchild Mistake&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s how many people solve for nesting elements within elements with BEM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__menu”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__menu__item”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__menu__item__link”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following this method of chaining elements (like this: &lt;code&gt;.nav__menu__item__link&lt;/code&gt;) gets out of control pretty quickly.&lt;/p&gt;

&lt;p&gt;It makes your class names difficult to read, not to mention it'll unnecessarily bloat your HTML and CSS files.&lt;/p&gt;

&lt;p&gt;This approach also follows the structure of the DOM, which limits your flexibility if the structure of your HTML changes.&lt;/p&gt;

&lt;p&gt;Don't just take my word for it. Vladimir Grinenko is on the Yandex team (the creators of the BEM methodology) and said this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"BEM methodology doesn't recommend to use elements within elements in class names. You don't need to resemble DOM structure in naming. Having one level structure makes refactoring much easier."&lt;br&gt;
— Vladimir Grinenko, Yandex&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, imagine that you realised that you needed to add a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; inside the &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav__wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Here is my new div--&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- Now I need to refactor all the classes below
        because of the new div --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__wrapper__menu”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__wrapper__menu__item”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__wrapper____menu__item__link”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the classes within the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; would need to be updated, as well as updating the class names in your CSS file.&lt;/p&gt;

&lt;p&gt;So as you can see, taking the &lt;code&gt;Block__Element__Element__Element&lt;/code&gt; is not a long term, sustainable choice.&lt;/p&gt;

&lt;p&gt;Here's how to better solve it:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Grandchild Solution&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Instead of chaining elements like &lt;code&gt;nav__menu__item__link&lt;/code&gt;, simply focus on the block name itself and use that as the main anchor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__menu”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__item”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__link”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Taking this approach also makes your code much more readable for other developers, as they can easily see all the elements that have a relationship with the block (in this case: &lt;code&gt;.nav&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;And if you need to add or remove HTML elements in the future, no refactoring is required:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- New div added without the need to refactor --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav__wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__menu”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__item”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“nav__link”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you find yourself entering territory where your elements are more than 3 levels deep, you might need to reconsider the structure of the block, potentially even breaking the block into smaller chunks.&lt;/p&gt;

&lt;p&gt;And that's it!&lt;/p&gt;

&lt;p&gt;I hope this article has helped you solve the 'Grandchild' scenario moving forward.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Download Free BEM Cheat Sheet&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Want to start practicing BEM and looking for a no-nonsense, quick start action guide?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scalablecss.com/resource/bem-cheat-sheet"&gt;Download a free cheat sheet&lt;/a&gt; covering BEM basics so you can dive in and start practicing today.&lt;/p&gt;

</description>
      <category>bem</category>
      <category>css</category>
    </item>
    <item>
      <title>BEM Methodology In CSS: A Quick Start Guide</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Tue, 14 Jan 2020 09:23:13 +0000</pubDate>
      <link>https://dev.to/bytomray/bem-methodology-in-css-a-quick-start-guide-2bd1</link>
      <guid>https://dev.to/bytomray/bem-methodology-in-css-a-quick-start-guide-2bd1</guid>
      <description>&lt;p&gt;This is a quick start guide to learning &lt;a href="https://en.bem.info/methodology/"&gt;BEM&lt;/a&gt;, the component-driven CSS methodology. &lt;/p&gt;

&lt;p&gt;If you want to start practicing and applying BEM to your projects, this guide will help you get started.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; &lt;a href="https://scalablecss.com/resource/bem-cheat-sheet/"&gt;Download a free cheat sheet&lt;/a&gt; that will show you how to quickly get started with BEM.&lt;/p&gt;




&lt;p&gt;Ready? Let's dive in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BEM overview&lt;/li&gt;
&lt;li&gt;B - Blocks&lt;/li&gt;
&lt;li&gt;E - Elements&lt;/li&gt;
&lt;li&gt;M - Modifiers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;BEM Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;BEM (Block-Element-Modifier) is a CSS naming convention developed by the team at &lt;a href="https://tech.yandex.com/bem/"&gt;Yandex&lt;/a&gt; to improve scalability and maintainability in web development.&lt;/p&gt;

&lt;p&gt;Put simply, the idea of BEM is to "divide the user interface into independent blocks" by naming CSS classes in the following methodology:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Block component */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="cm"&gt;/* Elements are dependent on their parent block */&lt;/span&gt; 
&lt;span class="nc"&gt;.card__img&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="cm"&gt;/* Modifiers are for incremental style changes */&lt;/span&gt;
&lt;span class="nc"&gt;.card--dark&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 
&lt;span class="nc"&gt;.card__img--large&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Block:&lt;/strong&gt; an independent component that can be reused (e.g. with class name &lt;code&gt;.nav&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Element:&lt;/strong&gt; a child within a block that cannot be used separately from that block (e.g. with class name &lt;code&gt;.nav__item&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modifier:&lt;/strong&gt; a variation in the style of either a block or modifier (e.g. with class name &lt;code&gt;.nav--dark&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's dive into some real CSS examples to get a hang of this thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Blocks&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Blocks are reusable components. Like buttons, cards or form fields.&lt;/p&gt;

&lt;p&gt;When naming your blocks, focus on describing its purpose (i.e. what it is) rather than its state (i.e. what it looks like).&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;.btn&lt;/code&gt; or &lt;code&gt;.nav&lt;/code&gt; follows the correct naming convention for a block.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.big&lt;/code&gt; or &lt;code&gt;.bright-pink&lt;/code&gt; describes how it looks, so doesn't scale well when you want to change the design later on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- INCORRECT --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"large-red-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
 &lt;span class="nc"&gt;.large-red-box&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- CORRECT --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're wondering how to place blocks within blocks (for example, a button inside a nav), &lt;a href="https://scalablecss.com/bem-blocks-within-blocks/"&gt;here's a short article&lt;/a&gt; to help you with that.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Elements&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Inside blocks are where elements live. Elements are dependent on their parent block, and so cannot be used without them.&lt;/p&gt;

&lt;p&gt;Elements also have a unique CSS class naming convention which works like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.block__element&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For example, using the &lt;code&gt;.card&lt;/code&gt; component, an element inside the card component (like an image) would have a class name like &lt;code&gt;.card__img&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The element name always appends the block name, separated by a double underscore &lt;code&gt;__&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- INCORRECT --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- CORRECT --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__img"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__title"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__description"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card__img&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card__title&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card__description&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's important to note that the second code snippet avoids using more than 1 selector to target the styles (e.g. like &lt;code&gt;.card img {}&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;It's considered best practice to use a BEM element class and use that directly instead (like &lt;code&gt;.card__img {}&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Following this approach reduces the chance of &lt;a href="https://www.smashingmagazine.com/2016/06/battling-bem-extended-edition-common-problems-and-how-to-avoid-them/"&gt;cascade issues&lt;/a&gt; down the line.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Modifiers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When you have varying styles in blocks (or elements), that's where modifiers come in. &lt;/p&gt;

&lt;p&gt;For example, your 'card' block might have a light and dark version. Or you might have primary and secondary buttons.&lt;/p&gt;

&lt;p&gt;Modifiers have a unique CSS naming convention which works like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;block--modifier&lt;/code&gt; or &lt;code&gt;block__element--modifier&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's right- BEM modifiers can be applied to both blocks and elements.&lt;/p&gt;

&lt;p&gt;Let's dive into some bad and good practices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- INCORRECT --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card--dark"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__title--large"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
 &lt;span class="nc"&gt;.card--dark&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card__title--large&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's considered bad practice to use a modifier class in isolation (i.e. without the block or element class).&lt;/p&gt;

&lt;p&gt;That's because the modifier is meant to add incremental style changes to the block.&lt;/p&gt;

&lt;p&gt;Therefore, whenever using a modifier, ensure it's used with the base class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- CORRECT --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card card--dark"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__title card__title--large"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
 &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card--dark&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card__title&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="nc"&gt;.card__title--large&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it!&lt;/p&gt;

&lt;p&gt;Those are the fundamentals to get you off and running with BEM.&lt;/p&gt;

&lt;p&gt;If you're interested to learn more about the 'why' behind BEM, I recommend checking out &lt;a href="https://css-tricks.com/bem-101/"&gt;this CSS Tricks article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Like learning anything new, practicing is key. Give BEM a shot in your next project and see where it takes you!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Download Free BEM Cheat Sheet&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Want to start practicing BEM and looking for a no-nonsense, quick start action guide?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scalablecss.com/resource/bem-cheat-sheet"&gt;Download a free cheat sheet&lt;/a&gt; covering BEM basics so you can dive in and start practicing today.&lt;/p&gt;




</description>
      <category>css</category>
      <category>bem</category>
      <category>methodologies</category>
    </item>
    <item>
      <title>Is Sass worth learning in 2020?</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Tue, 31 Dec 2019 11:24:38 +0000</pubDate>
      <link>https://dev.to/bytomray/is-sass-worth-learning-in-2020-4dcj</link>
      <guid>https://dev.to/bytomray/is-sass-worth-learning-in-2020-4dcj</guid>
      <description>&lt;p&gt;Sass has been around for over 10 years now. It's worth asking:&lt;/p&gt;

&lt;p&gt;Is Sass worth learning going into 2020? &lt;/p&gt;

&lt;p&gt;Is it still a relevant way to &lt;a href="https://scalablecss.com/stop-writing-messy-css/"&gt;keep your CSS organized&lt;/a&gt; and write efficient stylesheets?&lt;/p&gt;

&lt;p&gt;Let's go through some valid objections to learning Sass to answer these questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Isn't CSS catching up with Sass functionality?"&lt;/li&gt;
&lt;li&gt;"Isn't PostCSS taking over Sass?"&lt;/li&gt;
&lt;li&gt;"I only work on small websites. Do I need Sass?"&lt;/li&gt;
&lt;li&gt;"I've avoided Sass because of the compiler"&lt;/li&gt;
&lt;li&gt;"I'm not sure I know enough CSS to get started with Sass"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready? Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;"Isn't CSS catching up with Sass functionality?"&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It's true, CSS is evolving. &lt;/p&gt;

&lt;p&gt;In fact, some developers are opting to leave preprocessors all together and get back to writing vanilla CSS.&lt;/p&gt;

&lt;blockquote&gt;
"CSS has evolved over recent years and the problems that lead me to Sass in the first place seem to be less of an issue today"
— Cathy Dutton in her blog post on &lt;a href="https://cathydutton.co.uk/posts/why-i-stopped-using-sass/"&gt;Stepping away from Sass&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;An example of CSS catching up with Sass is the introduction of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties"&gt;CSS Variables&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's quite similar to the variables functionality in Sass, and is widely adopted across browsers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Me4_gw3y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/FxrlKmO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Me4_gw3y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/FxrlKmO.png" alt="Browser support for CSS Variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other functionality from Sass is also &lt;a href="http://preset-env.cssdb.org/"&gt;planned to move across to CSS&lt;/a&gt; in the coming months/years.&lt;/p&gt;

&lt;p&gt;But the reality is that right now, many developers and plenty of organizations still rely on preprocessors like Sass.&lt;/p&gt;

&lt;p&gt;Sass functionality like nesting (when used carefully), mixins &amp;amp; partials still provide value to frontend developers and are not (yet) supported in vanilla CSS.&lt;/p&gt;

&lt;p&gt;That being said, can't PostCSS help with those things?...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;"Isn't PostCSS taking over Sass?"&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Over the past few years, PostCSS has grown quite a bit in popularity:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iQ-9cSGS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/4WQ00ke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iQ-9cSGS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/4WQ00ke.png" alt="Graph showing the growth of PostCSS over 2017 vs other CSS processing tools"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some frontend developers have adopted PostCSS as a complete replacement to Sass (or other preprocessors).&lt;/p&gt;

&lt;p&gt;So, what is PostCSS and how does it differ to Sass?&lt;/p&gt;

&lt;p&gt;PostCSS is a tool that gives you access to a bunch of CSS related plugins to help improve your workflow and how you write CSS.&lt;/p&gt;

&lt;p&gt;This means you start with a blank slate, and you can pick and choose the additional plugins you need.&lt;/p&gt;

&lt;p&gt;That's the biggest difference between Sass and PostCSS:&lt;/p&gt;

&lt;p&gt;Sass comes with a whole bunch of functionality out of the box, even if you don't need some of that functionality. PostCSS allows you to choose which functionality you'd like to add (and they have a &lt;a href="https://github.com/postcss/postcss/blob/master/docs/plugins.md"&gt;pretty amazing choice of independently created plugins&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;For example, let's say you enjoy using the nesting functionality from Sass, but you're not bothered about the other Sass functionality.&lt;/p&gt;

&lt;p&gt;Well, once you've got PostCSS setup, you'd simply need to add the &lt;a href="https://github.com/postcss/postcss-nested"&gt;postcss-nested&lt;/a&gt; plugin and you're off!&lt;/p&gt;

&lt;p&gt;Pretty cool, right?&lt;/p&gt;

&lt;p&gt;The data from &lt;a href="https://ashleynolan.co.uk/blog/frontend-tooling-survey-2019-results#css-processors"&gt;Ashley Nolan's recent CSS tooling survey&lt;/a&gt; paint an interesting picture on the usage of Sass vs PostCSS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tL42DnmX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/gi8qqQs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tL42DnmX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/gi8qqQs.png" alt="Comparitive bar chart of the usage of various CSS processing tools in 2019. Sass &amp;amp; PostCSS are both growing in usage compared to 2018&amp;lt;br&amp;gt;
"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So clearly, Sass and PostCSS are both winners here.&lt;/p&gt;

&lt;p&gt;That being said, their usage is not mutually exclusive. &lt;/p&gt;

&lt;p&gt;In fact, many use both &lt;a href="https://webdesign.tutsplus.com/tutorials/using-postcss-together-with-sass-stylus-or-less--cms-24591"&gt;Sass and PostCSS in tandem&lt;/a&gt;, allowing them to keep using Sass and take advantage of PostCSS plugins to improve their workflow.&lt;/p&gt;

&lt;p&gt;The barrier to entry for getting started and using Sass is lower than PostCSS, which is one of the reasons I imagine PostCSS hasn't skyrocketed in usage over Sass.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;"I only work on small websites. Do I need Sass?"&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For small websites, it can be hard to rationalize using Sass. &lt;/p&gt;

&lt;p&gt;For example, one of the features of Sass is using variables to define repeating values, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Declare the variable&lt;/span&gt;
&lt;span class="nv"&gt;$danger-red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#fc4103&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;.error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$danger-red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Use the variable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure, it's easy to see how this can save you time.&lt;/p&gt;

&lt;p&gt;But in reality, for a sub-20 page website, updating colors on a website would only take you a couple of minutes in CSS.&lt;/p&gt;

&lt;p&gt;I.e. Sass seems a bit overkill. &lt;/p&gt;

&lt;p&gt;That being said, don't forget that Sass (SCSS) uses the same syntax as CSS. &lt;/p&gt;

&lt;p&gt;Meaning that you can write CSS in a .scss (Sass) file and it will work the same as CSS (once it's compiled. See more on the compilation setup below).&lt;/p&gt;

&lt;p&gt;So think of Sass like a bolt-on to your CSS, giving you extra functionality.&lt;/p&gt;

&lt;p&gt;That being said, you might STILL think this is overkill for a small website. &lt;/p&gt;

&lt;p&gt;And you might be right. &lt;/p&gt;

&lt;p&gt;But the barrier to &lt;em&gt;trying&lt;/em&gt; Sass is much lower than you think. And once you've tried it, then you can make a judgment call.&lt;/p&gt;

&lt;p&gt;To try Sass, you just need to know how to set up the compiler...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;"I've avoided Sass because of the compiler"&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ahh, the compiler. &lt;/p&gt;

&lt;p&gt;If you've not used &lt;code&gt;npm&lt;/code&gt; before or a task runner like &lt;code&gt;gulp&lt;/code&gt; or &lt;code&gt;grunt&lt;/code&gt;, the compiler can be a reason to shy away from getting started with Sass.&lt;/p&gt;

&lt;p&gt;The reality is that if you want to use Sass in a professional workflow, you will need to address that fear and learn how to use package managers.&lt;/p&gt;

&lt;p&gt;But what if I told you about a simpler way? If you wanted to just start writing some Sass and dive in?&lt;/p&gt;

&lt;p&gt;Well, my friend, you're in for a treat. Here's what you can do (assuming you're using &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;Search for 'sass' inside the extensions tab of VS code and install the &lt;strong&gt;Live Sass Compiler&lt;/strong&gt; extension:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y6PHkRnX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/r5qWB1D.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y6PHkRnX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/r5qWB1D.png" alt="Search for 'Live Sass Compiler' within Visual Studio Code extensions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a .scss file and, with your .scss file open, press the 'Watch Sass' button at the bottom of your screen inside the horizontal blue bar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GwVkxS_6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/BrO98ZU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GwVkxS_6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/BrO98ZU.png" alt="Press the 'Watch Sass' button to start the compiler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The compiler is now setup! Easy as that. You should see the compiled .css file within your files:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1UqcxLir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Qas1Fnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1UqcxLir--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Qas1Fnz.png" alt="The compiled CSS file will now be within your directory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step is to link the compiled CSS file. So remember to link the .css file, not the .scss file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9_66wbxF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/WKHmnV3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9_66wbxF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/WKHmnV3.png" alt="Ensure you link to the CSS file in your HTML, not the SCSS file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;"I'm not sure I know enough CSS to get started with Sass"&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;How do you know when your foundational CSS skills are strong enough to start learning Sass?&lt;/p&gt;

&lt;p&gt;It's an interesting question.&lt;/p&gt;

&lt;p&gt;Because if you can write CSS, then you can write Sassy Sass (SCSS) as we mentioned above.&lt;/p&gt;

&lt;p&gt;For example, declaring a style like this in CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* CSS (.css) file */&lt;/span&gt;

&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is the same as declaring the style in SCSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Sassy Sass (.scss) file */&lt;/span&gt;

&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference between Sassy Sass and CSS is that Sassy Sass requires a compiler and has additional syntax and functionality, like mixins and nesting.&lt;/p&gt;

&lt;p&gt;So the question should be:&lt;/p&gt;

&lt;p&gt;At what point should I learn Sass functionality like mixins &amp;amp; nesting?&lt;/p&gt;

&lt;p&gt;Well, have you spent some time learning (and importantly &lt;strong&gt;practicing&lt;/strong&gt;) fundamental concepts CSS like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How the cascade &amp;amp; specificity works&lt;/li&gt;
&lt;li&gt;The box model&lt;/li&gt;
&lt;li&gt;Practiced different layout methods like flexbox &amp;amp; grid&lt;/li&gt;
&lt;li&gt;Practiced using different selector types, properties &amp;amp; values&lt;/li&gt;
&lt;li&gt;Using media queries for responsiveness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've got these topics covered, I think you should be brave and dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The reality is that Sass is still being used commercially (and recreationally) by developers and organizations around the world.&lt;/p&gt;

&lt;p&gt;How do I know this?&lt;/p&gt;

&lt;p&gt;Well, the &lt;a href="https://2019.stateofcss.com/"&gt;State of CSS 2019&lt;/a&gt; survey results speak for itself:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kFGAZgaV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/OujI7q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kFGAZgaV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/OujI7q7.png" alt="State of CSS 2019 rankings for pre &amp;amp; post processors"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, if you're pondering whether or not to start learning Sass, I would encourage you to be brave and dive in.&lt;/p&gt;

&lt;p&gt;I know. At first glance, Sass can look fairly overwhelming and complex.&lt;/p&gt;

&lt;p&gt;But the barrier to entry is much lower than it seems. &lt;/p&gt;

&lt;p&gt;Give it a go!&lt;/p&gt;

</description>
      <category>sass</category>
      <category>css</category>
      <category>postcss</category>
      <category>scss</category>
    </item>
    <item>
      <title>Is Sass worth learning in 2020?</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Mon, 30 Dec 2019 14:33:30 +0000</pubDate>
      <link>https://dev.to/bytomray/is-sass-worth-learning-in-2020-5gn</link>
      <guid>https://dev.to/bytomray/is-sass-worth-learning-in-2020-5gn</guid>
      <description>&lt;p&gt;What do you think? Is learning Sass still a worthy investment going into 2020?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>How To Stop Writing Messy &amp; Unscalable CSS</title>
      <dc:creator>Tom Ray</dc:creator>
      <pubDate>Tue, 24 Dec 2019 10:04:31 +0000</pubDate>
      <link>https://dev.to/bytomray/how-to-stop-writing-messy-unscalable-css-2ngj</link>
      <guid>https://dev.to/bytomray/how-to-stop-writing-messy-unscalable-css-2ngj</guid>
      <description>&lt;p&gt;“I have 4 .css files and in total, they’re over 10,000 lines of code. How did things get so big?”&lt;/p&gt;

&lt;p&gt;CSS files can get out of control, pretty quickly. &lt;/p&gt;

&lt;p&gt;But it doesn't have to be this way.&lt;/p&gt;

&lt;p&gt;Let's dive into some actionable CSS techniques to help you write more modular &amp;amp; flexible code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Technique 1: Leverage inheritance in CSS&lt;/li&gt;
&lt;li&gt;Technique 2: The power of the elements&lt;/li&gt;
&lt;li&gt;Technique 3: Use a CSS methodology &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Technique 1: Leverage inheritance in CSS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Do you ever find yourself in CSS repeating a declaration, even though you know that you've used that declaration before?&lt;/p&gt;

&lt;p&gt;Understanding inheritance in CSS might help.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vqSZC-bK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/s3zD8XD.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vqSZC-bK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/s3zD8XD.png" alt="Understanding and using CSS inheritance is the foundation of writing scalable CSS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance"&gt;Inheritance in CSS&lt;/a&gt; allows us to define styles at a high level so that these styles can be trickled downstream and style descendant elements.&lt;/p&gt;

&lt;p&gt;This is simple, entry-level CSS skills.&lt;/p&gt;

&lt;p&gt;However, despite its well-understood nature, I believe the inheritance rule is often being underutilised.&lt;/p&gt;

&lt;p&gt;When leveraged correctly, it can save you hundreds of lines of code in the long run.&lt;/p&gt;

&lt;p&gt;Starting at the highest level, for the majority of websites, there will be styles that will be consistent across all of your HTML elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fafafa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#424242&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Helvetica'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Don't forget about &lt;code&gt;inherit&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Adding styles to the root as shown above is a great place to start. &lt;/p&gt;

&lt;p&gt;There are, however, some HTML elements (like &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;) that by default will &lt;strong&gt;not&lt;/strong&gt; inherit styles that you've defined.&lt;/p&gt;

&lt;p&gt;This means if you set the &lt;code&gt;font-family: Helvetica&lt;/code&gt; in the root as shown in the example above, the font in the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; will &lt;strong&gt;not&lt;/strong&gt; inherit this style, they will take the browser default font family.&lt;/p&gt;

&lt;p&gt;You can override this by adding the following declaration: &lt;code&gt;font-family: inherit&lt;/code&gt; to these elements that do not inherit properties by default.&lt;/p&gt;

&lt;p&gt;A common technique to ensure all elements inherit the styles you've defined on the root element is to use the universal selector &lt;code&gt;* {}&lt;/code&gt; and apply the &lt;code&gt;inherit&lt;/code&gt; value to specific properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
 &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important to note:&lt;/strong&gt; Properties like &lt;code&gt;font-size&lt;/code&gt; and &lt;code&gt;font-style&lt;/code&gt; are not included in the universal selector snippet above, as applying these syles will override the user-agent styles.&lt;/p&gt;

&lt;p&gt;For example, if you styled &lt;code&gt;font-size: 20px&lt;/code&gt; within the universal selector, this will override the user-agent &lt;code&gt;font-size&lt;/code&gt; for all the heading tags (h1, h2, h3...)&lt;/p&gt;

&lt;p&gt;Putting it all together, here's an example of of some common declarations used to leverage the inheritance rule and save you some lines of CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fafafa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#424242&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Georgia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
 &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's dive a little deeper and discuss styling elements.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Technique 2: The power of the elements&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Getting more granular than styling the root, adding styles directly to element selectors is a great way to keep your CSS file lean and efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pLlXnykm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/qrhRHpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pLlXnykm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/qrhRHpb.png" alt="Step 2 of the pyramid to writing more scalable CSS is to style elements"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, a content-heavy website like a blog, you can style the typographic selectors like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c"&gt;/* paragraph styles are not required 
 as they are inherited from the root */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h6&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;32rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h4&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has 2 benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your HTML will be much cleaner, as the styles are applied natively to the HTML element selectors (i.e. no need to add classes to your HTML tags)&lt;/li&gt;
&lt;li&gt;In some cases, it can remove the need to add custom classes, simplifying your CSS stylesheet and making it more scalable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I like to view this as setting up the core foundation of the styling in a project to give yourself a good base to begin styling components and building out more complex parts of your website.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Technique 3: Use a CSS methodology&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Leveraging CSS inheritance rules and styling element selectors will only get you so far.&lt;/p&gt;

&lt;p&gt;Using classes to design various components and layouts on your website is inevitable (and where you'll spend most of your time).&lt;/p&gt;

&lt;p&gt;Therefore, what we need is a "system" to write CSS in a modular, flexible way to keep our CSS efficient and organised.&lt;/p&gt;

&lt;p&gt;That's where a &lt;a href="https://www.creativebloq.com/features/a-web-designers-guide-to-css-methodologies"&gt;CSS methodology&lt;/a&gt; comes in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z-r-gWHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/wDxUzTx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z-r-gWHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/wDxUzTx.png" alt="Step 3 of the pyramid is using a CSS methodology to provide naming convention consistent at scale"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A CSS methodology is a consistent set of naming conventions that a team of developers will follow to ensure they write consistent, reusable CSS that is scalable over time.&lt;/p&gt;

&lt;p&gt;Some of the most popular methodologies include &lt;a href="http://getbem.com/"&gt;BEM&lt;/a&gt;, &lt;a href="http://smacss.com/"&gt;SMACSS&lt;/a&gt;, &lt;a href="https://github.com/stubbornella/oocss/wiki"&gt;OOCSS&lt;/a&gt; and &lt;a href="https://acss.io/"&gt;Atomic CSS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Out of these, it appears BEM has taken the pole position as the most adopted of the methodologies &lt;a href="https://2019.stateofcss.com/technologies/methodologies/"&gt;as noted from the State of CSS 2019&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, let's zero in on BEM: what it is and how you can start to implement it in your projects. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5KzM3am--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/e1uJdyB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5KzM3am--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/e1uJdyB.png" alt="A visual example of BEM showing a block, element and modifier"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BEM stands for Block-Element-Modifier, which are the 3 core pillars. &lt;/p&gt;

&lt;p&gt;Each pillar has a different naming convention to use when creating components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Block is the component itself, for example, a card component (e.g. &lt;code&gt;.card&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Element is a child that lives within the Block and uses the naming convention &lt;code&gt;[Block]__[Element]&lt;/code&gt; (e.g. &lt;code&gt;.card__title&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Modifier is a variation in the design of a Block or Element and uses the naming convention &lt;code&gt;[Block]--[Modifier]&lt;/code&gt;(e.g. &lt;code&gt;.card--dark&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive into a real example, sticking with a card component:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/scalablecss/embed/dyyQQvm?height=600&amp;amp;default-tab=html,result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In this example, the &lt;code&gt;.card&lt;/code&gt; is the Block.&lt;/p&gt;

&lt;p&gt;You can see the children elements within the &lt;code&gt;.card&lt;/code&gt; Block uses the naming convention &lt;code&gt;[Block]__[Element]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, the class used for the image of the card is &lt;code&gt;.card__image&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, let's dive into an example with 'Modifier':&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/scalablecss/embed/QWWJzwG?height=600&amp;amp;default-tab=html,result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can see the naming convention &lt;code&gt;[Block]--[Modifier]&lt;/code&gt; is being used for the Modifier (&lt;code&gt;.card--dark&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;It's important to note here that when you used a Modifier, you use it with the Block (not instead of the Block).&lt;/p&gt;

&lt;p&gt;You can see in the CodePen above that the Modifier class &lt;code&gt;.card--dark&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; replace the Block class &lt;code&gt;.card&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;For more code examples and a deeper dive into BEM, I recommend checking out &lt;a href="https://seesparkbox.com/foundry/bem_by_example"&gt;Sparkbox's&lt;/a&gt; article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Perhaps you've been authoring CSS stylesheets for a long time but often look back and say: "Damn. My CSS is an absolute mess!"&lt;/p&gt;

&lt;p&gt;If implemented, the techniques covered in this article will help remedy that feeling and you will be well on your way to becoming a modular &amp;amp; scalable CSS master. &lt;/p&gt;

&lt;p&gt;To summarise up, here are the 3 CSS techniques you can start using today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand how inheritance works in CSS and use it to your advantage&lt;/li&gt;
&lt;li&gt;Style element selectors directly to give your design a solid foundation&lt;/li&gt;
&lt;li&gt;Use a CSS Methodology like &lt;a href="https://scalablecss.com/bem-quickstart-guide/"&gt;BEM&lt;/a&gt; to design your components in a modular and flexible way.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;What do you think? Any tips/strategies to write less messy CSS?&lt;/p&gt;

</description>
      <category>css</category>
      <category>bem</category>
    </item>
  </channel>
</rss>
