<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ PostCSS - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ PostCSS - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 27 Jul 2026 04:22:37 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/postcss/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What is PostCSS? How to Use Plugins to Automate CSS Tasks ]]>
                </title>
                <description>
                    <![CDATA[ PostCSS is a Node.js tool that transforms your styles using JavaScript plugins.   It generates more downloads per week on NPM than other CSS preprocessors like Sass, Less, and Stylus combined. PostCSS download trends comparing to other CSS preproces... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-postcss/</link>
                <guid isPermaLink="false">66bb52ff3c5ab240beb8cd73</guid>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PostCSS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Yasir Tobbileh ]]>
                </dc:creator>
                <pubDate>Mon, 31 Jan 2022 17:29:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/postcss-1.PNG" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>PostCSS is a Node.js tool that transforms your styles using JavaScript plugins.  </p>
<p>It generates more downloads per week on <a target="_blank" href="https://www.npmtrends.com/less-vs-postcss-vs-sass-vs-stylus">NPM</a> than other CSS preprocessors like Sass, Less, and Stylus combined.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/trend.PNG" alt="Image" width="600" height="400" loading="lazy">
<em>PostCSS download trends comparing to other CSS preprocessors</em></p>
<h2 id="heading-in-this-article-we-will-discuss">In this article we will discuss:</h2>
<ul>
<li>What is PostCSS?</li>
<li>PostCSS features and advantages</li>
<li>Some popular PostCSS plugins</li>
<li>How to setup PostCSS configurations</li>
</ul>
<h1 id="heading-what-is-postcss">What is PostCSS?</h1>
<p>PostCSS is a JavaScript tool that transforms your CSS code into an abstract syntax tree (AST) and then provides an API (application programming interface) for analyzing and modifying it using JavaScript plugins.</p>
<p>PostCSS provides a large ecosystem of plugins to perform different functionalities like linting, minifying, inserting vendor prefixes, and many other things.</p>
<p>Despite its name, it is neither a post-processor nor a pre-processor, it is just a <strong>transpiler</strong> that turns a special PostCSS plugin syntax into a Vanilla CSS. You can think of it as the <a target="_blank" href="https://babeljs.io/docs/en/"><strong>Babel</strong></a> tool for CSS.</p>
<p>You can use PostCSS in conjunction with existing preprocessors like Sass, Less, and Stylus. Or you can use it as an alternative to all of them since it has all the required functionalities to be used alone.</p>
<p>You may have already been using PostCSS without knowing it. It's used in the popular Autoprefixer plugin which is used to automatically prepend vendor prefixes to CSS properties that require them.</p>
<p>PostCSS is also used by other technologies like Vite and Next.js, as well as the CSS framework <a target="_blank" href="https://tailwindcss.com/docs/using-with-preprocessors#using-post-css-as-your-preprocessor">TailwindCSS</a> which is a PostCSS plugin.</p>
<h1 id="heading-postcss-features-and-benefits">PostCSS Features and Benefits</h1>
<ul>
<li>PostCSS is fully customizable so you can use only the plugins and features you need for your application.</li>
<li>It also produces fast build times compared with other preprocessors.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/1_WVCihSMXXK0xkCw2a3g8iQ.png" alt="Image" width="600" height="400" loading="lazy">
<em>Different build times for different CSS preprocessors comparing to PostCSS</em></p>
<ul>
<li>If you want, you can write your own custom plugins. And you can use it with regular CSS as well as alongside other preprocessors like Sass.</li>
</ul>
<p>PostCSS is all about plugins (on its own, it is simply an API). It has an ecosystem of 356 plugins (as of writing this article). Each plugin was created for a specific task.</p>
<p>You can navigate through the plugins using the <a target="_blank" href="https://github.com/postcss/postcss/blob/main/docs/plugins.md">plugin directory</a> on the official PostCSS GitHub page, or using this <a target="_blank" href="https://www.postcss.parts/">searchable catalog of PostCSS plugins</a>.</p>
<p>Before starting with the code, I highly recommend that you follow these steps:</p>
<ol>
<li>Download or fork the following <a target="_blank" href="https://github.com/adamA113/postcss-tutorial"><strong>postcss-tutorial</strong></a> repository to your machine and try to follow along. (Make sure to read the README.md file.)</li>
<li>Install the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=csstools.postcss"><strong>PostCSS Language Support</strong></a> <strong>plugin</strong> if you are using the Visual Studio Code editor, so your editor can recognize any new syntax and stop giving you errors (skip this step if you are using other code editors).</li>
</ol>
<h1 id="heading-popular-postcss-plugins">Popular PostCSS Plugins</h1>
<h3 id="heading-postcss-import">PostCSS Import</h3>
<p>One of the basic and most important plugins to use is <a target="_blank" href="https://github.com/postcss/postcss-import">postcss-import</a>. It lets us import CSS files into other files.</p>
<p>To check how to use this plugin go to <code>src/style.css</code> in the postcss-tutorial repository.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> <span class="hljs-string">'./components/comp1.css'</span>;
<span class="hljs-keyword">@import</span> <span class="hljs-string">'./components/comp2.css'</span>;
</code></pre>
<p>You can see that it is very similar to the way that we use the @import method in Sass. </p>
<p><strong>Note:</strong> <code>postcss-import</code> is different than the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/@import">import rule</a> in native CSS. You should avoid the import rule in native CSS, since it can prevent stylesheets from being downloaded concurrently which affects the loading speed and performance.</p>
<p>The browser has to wait for every imported file to be loaded instead of being able to load all the CSS files at once.</p>
<h2 id="heading-autoprefixerhttpsgithubcompostcssautoprefixer"><a target="_blank" href="https://github.com/postcss/autoprefixer">Autoprefixer</a></h2>
<p>This is one of the most popular PostCSS plugins. You use it to parse and add vendor prefixes like <code>-webkit</code>, <code>-moz</code>, and <code>-ms</code> to CSS rules using values from the <a target="_blank" href="https://caniuse.com/">Can I Use</a> website.</p>
<p>We use the Can I Use website to see which browsers support a CSS feature with their versions. This helps us determine whether we need to add a prefix or not.</p>
<p>Autoprefixer uses <a target="_blank" href="https://github.com/browserslist/browserslist">Browserslist</a>, so you can specify the browsers you want to target in your project with queries.</p>
<p>We can configure our Browserslist in the package.json file using a “browserslist” key:</p>
<pre><code class="lang-json"> <span class="hljs-string">"browserslist"</span>: [ 
     <span class="hljs-string">"defaults"</span>  
 ]
</code></pre>
<p>The <code>defaults</code> query above is a short version of:</p>
<ul>
<li><code>&gt; 0.5%</code> browsers that have at least 0.5% global usage.</li>
<li><code>last 2 versions</code> the last 2 versions for <em>each</em> browser,</li>
<li><code>Firefox ESR</code> the latest <a target="_blank" href="https://support.mozilla.org/en-US/kb/choosing-firefox-update-channel">Firefox Extended Support Release</a>., </li>
<li><code>not dead</code> browsers that received official support or updates for the last 24 months.</li>
</ul>
<p>Or we can use a <code>.browserslistrc</code> file in the root directory, and inside it we type our configurations.</p>
<pre><code>defaults
</code></pre><p>To test this plugin, we have added some CSS rules that need some prefixes in the <code>src/components/comp2.css</code> file:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">label</span> {
  <span class="hljs-attribute">user-select</span>: none;
}

<span class="hljs-selector-pseudo">::selection</span> {
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">background</span>: blue;
}

<span class="hljs-selector-pseudo">::placeholder</span> {
  <span class="hljs-attribute">color</span>: gray;
}
</code></pre>
<p>Based on our previous "browserslist" settings, the final output will be:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">label</span> {
  <span class="hljs-attribute">-webkit-user-select</span>: none;
     <span class="hljs-attribute">-moz-user-select</span>: none;
      <span class="hljs-attribute">-ms-user-select</span>: none;
          <span class="hljs-attribute">user-select</span>: none;
}

<span class="hljs-selector-pseudo">::-moz-selection</span> {
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">background</span>: blue;
}

<span class="hljs-selector-pseudo">::selection</span> {
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">background</span>: blue;
}

<span class="hljs-selector-pseudo">::-moz-placeholder</span> {
  <span class="hljs-attribute">color</span>: gray;
}

<span class="hljs-selector-pseudo">:-ms-input-placeholder</span> {
  <span class="hljs-attribute">color</span>: gray;
}

<span class="hljs-selector-pseudo">::placeholder</span> {
  <span class="hljs-attribute">color</span>: gray;
}
</code></pre>
<h2 id="heading-postcss-preset-envhttpsgithubcomcsstoolspostcss-pluginstreemainplugin-packspostcss-preset-env"><a target="_blank" href="https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-preset-env">PostCSS Preset Env</a></h2>
<p>This plugin enables us to use modern CSS (like nesting and custom media queries) in our code, by converting it to Vanilla CSS which can be understood by browsers.</p>
<p>It has a <code>stage</code> option which determines which CSS features to polyfill based upon their stability in the process of becoming implemented as a web standard.</p>
<p>The <code>stage</code> can be 0 (experimental) to 4 (stable), or false. Stage 2 is the default.</p>
<p>For nesting, we need to use stage 1.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">plugins</span>: [
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-preset-env'</span>)({ <span class="hljs-attr">stage</span>: <span class="hljs-number">1</span> })
    ],
}
</code></pre>
<p>Also, the preset-env plugin includes by default the <a target="_blank" href="https://github.com/postcss/autoprefixer">Autoprefixer</a> plugin and the <code>[browsers](https://github.com/csstools/postcss-preset-env#browsers)</code> option will be passed to it automatically.</p>
<p>In the <code>src/components/comp1.css</code> we have used the nesting feature pretty similarly to what we have in the Sass preprocessor:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">article</span> {
    <span class="hljs-attribute">background</span>: purple;

    &amp; .title {
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">6rem</span>;
    }

    &amp; <span class="hljs-selector-tag">li</span> {
        <span class="hljs-attribute">list-style-type</span>: none;
    }
}
</code></pre>
<p>Since nesting is not supported in today's CSS, we need to convert the code above so that web browsers can understand it.</p>
<p>The following code is the final result:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">article</span> {
    <span class="hljs-attribute">background</span>: purple
}

<span class="hljs-selector-tag">article</span> <span class="hljs-selector-class">.title</span> {
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">6rem</span>;
    }

<span class="hljs-selector-tag">article</span> <span class="hljs-selector-tag">li</span> {
        <span class="hljs-attribute">list-style-type</span>: none;
    }
</code></pre>
<h2 id="heading-postcss-nestedhttpsgithubcompostcsspostcss-nested"><a target="_blank" href="https://github.com/postcss/postcss-nested">PostCSS Nested</a></h2>
<p>If we want <strong>only</strong> to use the nesting feature, then this plugin is the perfect choice as it produce the same result as the previous plugin.</p>
<h2 id="heading-postcss-mixinshttpsgithubcompostcsspostcss-mixins"><a target="_blank" href="https://github.com/postcss/postcss-mixins">PostCSS Mixins</a></h2>
<p>Mixins allow you to define styles that can be re-used throughout your code.</p>
<p>In our code we used some mixins in the <code>src/components/comp1.css</code> file.</p>
<p>We first define the mixin using the keyword <code>@defin-mixin</code> followed by the mixin name. Then we use it by writing the name after the <code>@mixin</code> keyword. </p>
<pre><code class="lang-css"><span class="hljs-keyword">@define-mixin</span> reset-list {
  <span class="hljs-selector-tag">margin</span>: 0;
  <span class="hljs-selector-tag">padding</span>: 0;
  <span class="hljs-selector-tag">list-style</span>: <span class="hljs-selector-tag">none</span>;
}

<span class="hljs-selector-tag">nav</span> <span class="hljs-selector-tag">ul</span> {
  @mixin reset-list;
}
</code></pre>
<p>Mixins are not supported in today's CSS, so they need to be compiled to Vanilla CSS.</p>
<p>The final code will be:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">nav</span> <span class="hljs-selector-tag">ul</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">list-style</span>: none;
}
</code></pre>
<h2 id="heading-stylelinthttpsstylelintio"><a target="_blank" href="https://stylelint.io/">Stylelint</a></h2>
<p>This is a CSS linter that helps us avoid errors in our code before they break our User Interface (UI).</p>
<p>It can be configured in <a target="_blank" href="https://stylelint.io/user-guide/configure">multiple ways</a>. One of them through using a <code>stylelint</code> property in <code>package.json</code> as follows:</p>
<pre><code class="lang-json"><span class="hljs-string">"stylelint"</span>: {
    <span class="hljs-attr">"rules"</span>: {
      <span class="hljs-attr">"color-no-invalid-hex"</span>: <span class="hljs-literal">true</span>
    }
  }
</code></pre>
<p>Inside the <code>stylelint</code> we have multiple options to configure. Here we will only cover the "rules" option which lets you define are the rules that the linter should looks for and gives errors when they are not followed.</p>
<p>The <code>"color-no-invalid-hex": true</code> rules give an error in the terminal if an invalid hex value is provided as a color for a given CSS property.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/invalid-1.PNG" alt="Image" width="600" height="400" loading="lazy">
<em>Styleint linter gives an error as an invalid hex value provided as color at line 11.</em></p>
<p><strong>Note:</strong> No rules are turned on by default and there are no default values. You must explicitly configure each rule to turn it on.</p>
<h2 id="heading-cssnanohttpscssnanocodocsintroduction"><a target="_blank" href="https://cssnano.co/docs/Introduction/">Cssnano</a></h2>
<p>This is a minifier used to reduce the final CSS file size as much as possible so your code is ready for a production environment.</p>
<p>Some parts will be altered to reduce the size as much as possible, like removing unnecessary spaces, new lines, renaming values and variables, selectors merged together, and so on.</p>
<p>So here is our final CSS code before the minification process:</p>
<pre><code class="lang-css">* {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
}

<span class="hljs-selector-tag">article</span> {
    <span class="hljs-attribute">background</span>: purple
}

<span class="hljs-selector-tag">article</span> <span class="hljs-selector-class">.title</span> {
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">6rem</span>;
    }

<span class="hljs-selector-tag">article</span> <span class="hljs-selector-tag">li</span> {
        <span class="hljs-attribute">list-style-type</span>: none;
    }

<span class="hljs-selector-tag">nav</span> <span class="hljs-selector-tag">ul</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">list-style</span>: none;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">font-family</span>: sans-serif, Calibri;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>;
}

<span class="hljs-selector-tag">label</span> {
  <span class="hljs-attribute">-webkit-user-select</span>: none;
     <span class="hljs-attribute">-moz-user-select</span>: none;
      <span class="hljs-attribute">-ms-user-select</span>: none;
          <span class="hljs-attribute">user-select</span>: none;
}

<span class="hljs-selector-pseudo">::-moz-selection</span> {
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">background</span>: blue;
}

<span class="hljs-selector-pseudo">::selection</span> {
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">background</span>: blue;
}

<span class="hljs-selector-pseudo">::-moz-placeholder</span> {
  <span class="hljs-attribute">color</span>: gray;
}

<span class="hljs-selector-pseudo">:-ms-input-placeholder</span> {
  <span class="hljs-attribute">color</span>: gray;
}

<span class="hljs-selector-pseudo">::placeholder</span> {
  <span class="hljs-attribute">color</span>: gray;
}
</code></pre>
<p>After the minification process, our final CSS code that is ready for the production environment will be like this:</p>
<pre><code class="lang-css">*{<span class="hljs-attribute">margin</span>:<span class="hljs-number">0</span>;<span class="hljs-attribute">padding</span>:<span class="hljs-number">0</span>}<span class="hljs-selector-tag">article</span>{<span class="hljs-attribute">background</span>:purple}<span class="hljs-selector-tag">article</span> <span class="hljs-selector-class">.title</span>{<span class="hljs-attribute">font-size</span>:<span class="hljs-number">6rem</span>}<span class="hljs-selector-tag">article</span> <span class="hljs-selector-tag">li</span>{<span class="hljs-attribute">list-style-type</span>:none}<span class="hljs-selector-tag">nav</span> <span class="hljs-selector-tag">ul</span>{<span class="hljs-attribute">list-style</span>:none;<span class="hljs-attribute">margin</span>:<span class="hljs-number">0</span>;<span class="hljs-attribute">padding</span>:<span class="hljs-number">0</span>}<span class="hljs-selector-tag">body</span>{<span class="hljs-attribute">font-family</span>:sans-serif,Calibri;<span class="hljs-attribute">font-size</span>:<span class="hljs-number">16px</span>}<span class="hljs-selector-tag">label</span>{<span class="hljs-attribute">-webkit-user-select</span>:none;<span class="hljs-attribute">-moz-user-select</span>:none;<span class="hljs-attribute">-ms-user-select</span>:none;<span class="hljs-attribute">user-select</span>:none}<span class="hljs-selector-pseudo">::-moz-selection</span>{<span class="hljs-attribute">background</span>:blue;<span class="hljs-attribute">color</span>:<span class="hljs-number">#fff</span>}<span class="hljs-selector-pseudo">::selection</span>{<span class="hljs-attribute">background</span>:blue;<span class="hljs-attribute">color</span>:<span class="hljs-number">#fff</span>}<span class="hljs-selector-pseudo">::-moz-placeholder</span>{<span class="hljs-attribute">color</span>:gray}<span class="hljs-selector-pseudo">:-ms-input-placeholder</span>{<span class="hljs-attribute">color</span>:gray}<span class="hljs-selector-pseudo">::placeholder</span>{<span class="hljs-attribute">color</span>:gray}
</code></pre>
<h2 id="heading-postcss-normalizehttpsgithubcomcsstoolspostcss-normalize"><a target="_blank" href="https://github.com/csstools/postcss-normalize">PostCSS Normalize</a></h2>
<p>This plugin lets you use some parts of the popular library <a target="_blank" href="https://github.com/csstools/normalize.css">normalize.css</a> or <a target="_blank" href="https://github.com/csstools/sanitize.css">sanitize.css</a>.</p>
<p>These CSS libraries provide consistent, cross-browser default styling of HTML elements, also they correct bugs and common browser inconsistencies.</p>
<p>This plugin depends on the values you provides for the <code>"**browserslist"**</code> to show the correct styles for the HTML elements. Here is an <a target="_blank" href="https://github.com/csstools/postcss-normalize#examples">example</a> of that.</p>
<h1 id="heading-how-to-set-up-postcss">How to Set Up PostCSS</h1>
<p>To start using PostCSS, we need first to install it and its <a target="_blank" href="https://github.com/postcss/postcss-cli">command-line interface</a> (CLI) globally using this command:</p>
<pre><code class="lang-bash">npm i -g postcss-cli
</code></pre>
<ul>
<li><code>-g</code> to download it globally.</li>
</ul>
<p>Then install PostCSS locally using the following command:</p>
<pre><code class="lang-bash">npm i -D postcss
</code></pre>
<ul>
<li><code>-D</code> is short for <code>--save-dev</code> to save the installed packages as dev dependencies.</li>
</ul>
<p>To begin using PostCSS, we need to have at least one plugin downloaded.</p>
<p>If you are following along using the <a target="_blank" href="https://github.com/adamA113/postcss-tutorial">postcss-tutorial</a> repo, you can simply run <code>npm install</code> to download all the packages and dependencies.</p>
<h2 id="heading-setup-postcss-using-the-postcss-cli"><strong>Setup PostCSS Using the PostCSS CLI</strong></h2>
<p>The General Syntax for the command that needs to be run in the terminal is:</p>
<pre><code> postcss [input.css] [OPTIONS] [-o|--output output.css] [--watch|-w]
 postcss &lt;input.css&gt; [OPTIONS] --dir &lt;output-directory&gt; [--watch|-w]
</code></pre><p>We can run the following command directly in the terminal:</p>
<pre><code class="lang-bash">postcss src/style.css --use postcss-import --dir public --watch
</code></pre>
<p>The <code>--use</code> option lists the plugins we're using.</p>
<p>The <code>--watch</code> option watches the files for any changes and recompiles them.</p>
<h2 id="heading-setup-postcss-through-npm-scripts-in-the-packagejson-file"><strong>Setup PostCSS Through NPM scripts in the package.json File</strong></h2>
<p>Inside the package.json file in the "scripts", we need to type the following:</p>
<pre><code class="lang-json"><span class="hljs-string">"postcss:watch"</span>: <span class="hljs-string">"postcss src/style.css --use postcss-import 
--dir public --watch"</span>
</code></pre>
<p>The above command will create a new directory called 'public' which contains our final Vanilla CSS file, which has the same name as the source file (style.css).</p>
<p>If we want the output file to have a different name than the source file name, we need to replace <code>--dir public</code> with <code>-o public/&lt;file-name&gt;</code>.</p>
<p>Like for example: <code>-o public/main.css</code>.</p>
<p>We can configure our command to run in PostCSS CLI with different <a target="_blank" href="https://github.com/postcss/postcss-cli">options</a> to get our desired result.</p>
<p>Now to run the command above, we type <code>npm run &lt;command name&gt;</code> in our terminal. (our <code>&lt;command name&gt;</code> is <strong>postcss:watch</strong>, you can pick any name you want).</p>
<p>As our project gets bigger, we are more likely to add more plugins. For every plugin used, we need to write its name down after the <code>--use</code> keyword in the command above which makes it incredibly long and not a good practice.</p>
<p>The alternative solution is to create a postcss.config.js file.</p>
<h2 id="heading-setup-postcss-by-setting-up-a-postcss-config-file">Setup PostCSS by Setting Up a PostCSS Config File</h2>
<p>In the root directory of your project, create a file and name it <strong>postcss.config.js</strong>.</p>
<p>The code inside it will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">plugins</span>: [
         <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-import'</span>),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-mixins'</span>),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">"stylelint"</span>),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-preset-env'</span>)({ <span class="hljs-attr">stage</span>: <span class="hljs-number">1</span> }),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'cssnano'</span>),
    ],
}
</code></pre>
<p>Inside the plugins array, we add our plugins.</p>
<p><strong>Note:</strong> It is very important to add the postcss-import plugin at the top of our list since it is required by the documentation.</p>
<p>The command that runs PostCSS in our package.json file needs to be changed to:</p>
<pre><code class="lang-json"><span class="hljs-string">"postcss:watch"</span>: <span class="hljs-string">"postcss src/style.css --dir public --watch"</span>
</code></pre>
<p>As you can see, the only change required is to remove the <code>--use</code> option since the list of our plugins is mentioned is a separate file now.</p>
<h2 id="heading-setup-postcss-by-using-task-runners-or-module-bundlers"><strong>Setup PostCSS by Using Task Runners (or M</strong>odule Bundlers)</h2>
<p>PostCSS can be set to work with various task runners like <a target="_blank" href="https://github.com/postcss/gulp-postcss">Gulp</a>, <a target="_blank" href="https://github.com/C-Lodder/grunt-postcss">Grunt</a>, and module bundlers like <a target="_blank" href="https://github.com/egoist/rollup-plugin-postcss">Rollup</a> and <a target="_blank" href="https://github.com/webpack-contrib/postcss-loader">Webpack</a>.</p>
<p>In this section, we'll see how to set up Grunt for PostCSS.</p>
<p>First, we need to install grunt locally into the “dev” dependencies:</p>
<pre><code class="lang-bash">npm i -D grunt
</code></pre>
<p>And then install grunt-cli globally:</p>
<pre><code class="lang-bash">npm install -g grunt-cli
</code></pre>
<p>Now we need to create a file in the root of our project and name it <strong>Gruntfile.js</strong>.</p>
<p>Then we need to install a specific plugin <a target="_blank" href="https://www.npmjs.com/package/@lodder/grunt-postcss">@lodder/grunt-postcss</a> to let us run PostCSS using Grunt through the following command:</p>
<pre><code class="lang-bash">npm i -D @lodder/grunt-postcss
</code></pre>
<p>Inside the <code>initCnfig</code> function we set up our PostCSS configuration.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">grunt</span>) </span>{

    grunt.initConfig({
        <span class="hljs-attr">postcss</span>: {
            <span class="hljs-attr">options</span>: {
                <span class="hljs-attr">processors</span>: [
                    <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-import'</span>)(),
                    <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-mixins'</span>),
                    <span class="hljs-built_in">require</span>(<span class="hljs-string">"stylelint"</span>),
                    <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-preset-env'</span>)({ <span class="hljs-attr">stage</span>: <span class="hljs-number">1</span> }),
                    <span class="hljs-built_in">require</span>(<span class="hljs-string">'cssnano'</span>)(),
                ]
            },
            <span class="hljs-attr">dist</span>: {
                <span class="hljs-attr">src</span>: <span class="hljs-string">'src/style.css'</span>,
                <span class="hljs-attr">dest</span>: <span class="hljs-string">'public/style.css'</span>
            }
        }
    })

    grunt.loadNpmTasks(<span class="hljs-string">'@lodder/grunt-postcss'</span>);
}
</code></pre>
<p>Here we will stick to the basic minimum to run PostCSS, which is:</p>
<ul>
<li>Calling our plugins inside the <code>processors</code> array.</li>
<li>Setting up the source file and destination file in the <code>dist</code> object.</li>
</ul>
<p>For more configuration, you can always check out the official documentation for the <a target="_blank" href="https://github.com/C-Lodder/grunt-postcss">@lodder/grunt-postcss</a>.</p>
<p>To finish our configuration, we need to load our plugin using the <code>grunt.loadNpmTasks</code> method.</p>
<p>Finally to run our Grunt task we type:</p>
<pre><code class="lang-bash">grunt postcss
</code></pre>
<h1 id="heading-conclusion"><strong>Conclusion</strong></h1>
<p>PostCSS has been out there since 2015, and it is very popular among CSS preprocessors.</p>
<p>You can use it as a stand-alone tool or in conjunction with other existing preprocessors.</p>
<p>When you use it and how (stand-alone or in conjunction) depends on your project needs.</p>
<p>Now it is your time to go and discover the wide variety of plugins it offers and start playing around with it. Happy Coding :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Tailwind CSS and How Can I Add it to my Website or React App? ]]>
                </title>
                <description>
                    <![CDATA[ CSS is a technology that can be your best or worst friend. While it's incredibly flexible and can produce what seems like magic, without the proper care and attention, it can become hard to manage like any other code.  How can Tailwind CSS help us to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-tailwind-css-and-how-can-i-add-it-to-my-website-or-react-app/</link>
                <guid isPermaLink="false">66b8e39e0196ee8e3efce546</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS Framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PostCSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tailwind ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 19 May 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/tailwind-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>CSS is a technology that can be your best or worst friend. While it's incredibly flexible and can produce what seems like magic, without the proper care and attention, it can become hard to manage like any other code. </p>
<p>How can Tailwind CSS help us to take control of our styles?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-tailwind">What is Tailwind?</a></li>
<li><a class="post-section-overview" href="#heading-so-what-makes-tailwind-great">So what makes Tailwind great?</a></li>
<li><a class="post-section-overview" href="#heading-part-1-adding-tailwind-css-to-a-static-html-page">Part 1: Adding Tailwind CSS to a static HTML page</a></li>
<li><a class="post-section-overview" href="#heading-part-2-adding-tailwind-css-to-a-react-app">Part 2: Adding Tailwind CSS to a React app</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/7KeZcRMltP0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-is-tailwind">What is Tailwind?</h2>
<p><a target="_blank" href="https://tailwindcss.com/">Tailwind CSS</a> is a "utility-first" CSS framework that provides a deep catalog of CSS classes and tools that lets you easily get started styling your website or application.</p>
<p>The underlying goal is that as you're building your project, you don't need to deal with cascading styles and worrying about how to override that 10-selector pileup that's been haunting your app for the last 2 years.</p>
<h2 id="heading-so-what-makes-tailwind-great">So what makes Tailwind great?</h2>
<p>Taildwind's solution is to provide a wide variety of CSS classes that each have their own focused use. Instead of a class called <code>.btn</code> that is created with a bunch of CSS attributes directly, in Tailwind, you would either apply a bunch of classes like <code>bg-blue-500 py-2 px-4 rounded</code> to the button element or build a <code>.btn</code> class by <a target="_blank" href="https://tailwindcss.com/docs/functions-and-directives/#apply">applying</a> those utility class to that selector.</p>
<p>While Tailwind has a lot more going for it, we're going to focus on these basics for this tutorial, so let's dig in!</p>
<h2 id="heading-part-1-adding-tailwind-css-to-a-static-html-page">Part 1: Adding Tailwind CSS to a static HTML page</h2>
<p>We're going to start off by applying Tailwind CSS straight to a static HTML page. The hope is that by focusing on Tailwind and not the app, we can get a better understanding of what's actually happening with the framework.</p>
<h3 id="heading-step-1-creating-a-new-page">Step 1: Creating a new page</h3>
<p>You can get started by simply creating a new HTML file. For the content, you can use whatever you want, but I'm going to use <a target="_blank" href="http://fillerama.io/">fillerama.io</a> so the filler content is a bit more fun.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-with-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New HTML page with content</em></p>
<p>If you want to simplify this step, you can just <a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/c7db11899c9cd193cdd666fd228cfaefe75623f2#diff-eacf331f0ffc35d4b482f1d15a887d3b">copy the file I created</a> to get started.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/c7db11899c9cd193cdd666fd228cfaefe75623f2">Follow along with the commit!</a></p>
<h3 id="heading-step-2-adding-tailwind-css-via-cdn">Step 2: Adding Tailwind CSS via CDN</h3>
<p>Tailwind typically recommends that you install through <a target="_blank" href="https://www.npmjs.com/package/tailwindcss">npm</a> to get the full functionality, but again, we're just trying to understand how this works first.</p>
<p>So let's add a link to the CDN file in the <code>&lt;head&gt;</code> of our document:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
</code></pre>
<p>Once you save and reload the page, the first thing you'll notice is that all of the styles were stripped!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-tailwind-base.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with the Tailwind CSS base</em></p>
<p>This is expected. Tailwind includes a set of <a target="_blank" href="https://tailwindcss.com/docs/preflight">preflight styles</a> to fix cross-browser inconsistencies. For one, they include the popular <a target="_blank" href="https://github.com/necolas/normalize.css/">normalize.css</a> which they build upon with their own styles.</p>
<p>But we're going to learn how to use Tailwind to add back our styles and set things up how we want!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/b431b75cee0a03154a70b194b6dfcf028bc65942">Follow along with the commit!</a></p>
<h3 id="heading-step-3-using-tailwind-css-to-add-styles-to-your-page">Step 3: Using Tailwind CSS to add styles to your page</h3>
<p>Now that we have Tailwind installed, we've added the ability to make use of their huge library of utility classes that we'll now use to add styles back to our page.</p>
<p>Let's start off by adding some margin to all of our paragraphs (<code>&lt;p&gt;</code>) and our list elements (<code>&lt;ol&gt;</code>, <code>&lt;ul&gt;</code>). We can do this by adding the <code>.my-5</code> class to each element like so:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"my-5"</span>&gt;</span>
  Bender, quit destroying the universe! Yeah, I do that with my stupidness. I never loved you. Moving along…
  Belligerent and numerous.
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>The class name follows a pattern that you'll notice with the rest of the utility classes – <code>.my-5</code> stands for margin (m) applied to the y-axis (y) with a value of 5 which in Tailwind's case, it uses <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units">rem</a>, so the value is 5rem.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-paragraph-styles.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with basic paragraph styles</em></p>
<p>Next, let's make our headers look like actual headers. Starting with our <code>h1</code> tag, let's add:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-2xl font-bold mt-8 mb-5"</span>&gt;</span>
</code></pre>
<p>Here's what's happening:</p>
<ul>
<li><code>text-2xl</code>: set the text size (font-size) to 2xl. In Tailwind, that 2xl will equate to 1.5rem</li>
<li><code>font-bold</code>: set the weight of the text (font-weight) to bold</li>
<li><code>mt-8</code>: Similar to <code>my-5</code>, this will set the margin top (t) to 8rem</li>
<li><code>mb-5</code>: And this will set the margin bottom (b) to 5rem</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-header-styles.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with styled H1</em></p>
<p>With those classes added to the <code>h1</code>, let's apply those same exact classes to the rest of our header elements, but as we go down the list, reduce the size of the font size, so it will look like:</p>
<ul>
<li>h2: <code>text-xl</code></li>
<li>h3: <code>text-lg</code></li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-all-headers-style.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with all headers styled</em></p>
<p>Now let's make our list elements look like lists. Starting with our unordered list (<code>&lt;ul&gt;</code>), let's add these classes:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"list-disc list-inside my-5 pl-2"</span>&gt;</span>
</code></pre>
<p>Here's what we're adding:</p>
<ul>
<li><code>list-disc</code>: set the list-style-stype to disc (the markers on each line item)</li>
<li><code>list-inside</code>: sets the position of the list markers using  relative to the list items and the list itself with list-style-position to inside</li>
<li><code>my-5</code>: set the margin of the y axis to 5rem</li>
<li><code>pl-2</code>: set the left padding to 2rem</li>
</ul>
<p>Then we can apply the exact same classes to our ordered list (<code>&lt;ol&gt;</code>), except instead of <code>list-disc</code>, we want to change our style type to <code>list-decimal</code>, so that we can see numbers given it's an ordered list.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ol</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"list-decimal list-inside my-5 pl-2"</span>&gt;</span>
</code></pre>
<p>And we have our lists!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-styled-lists.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with styled lists</em></p>
<p>Finally, let's make our content a little easier to read by setting a max width and centering the content. On the <code>&lt;body&gt;</code> tag, add the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"max-w-4xl mx-auto"</span>&gt;</span>
</code></pre>
<p>/Note: Typically you wouldn't want to apply these classes to the <code>&lt;body&gt;</code> itself, rather, you can wrap all of your content with a <code>&lt;main&gt;</code> tag, but since we're just trying to get an idea of how this works, we'll roll with this. Feel free to add the <code>&lt;main&gt;</code> tag with those classes instead if you prefer!/</p>
<p>And with that, we have our page!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-content-centered.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with centered content</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/06fd719c98d17e2242b61ec2ab7034436c1c2ba6">Follow along with the commit!</a></p>
<h3 id="heading-step-4-adding-a-button-and-other-components">Step 4: Adding a button and other components</h3>
<p>For the last part of our static example, let's add a button.</p>
<p>The trick with Tailwind, is they intentionally don't provide pre-baked component classes with the idea being that likely people would need to override these components anyways to make them look how they wanted.</p>
<p>So that means, we're going to have to create our own using the utility classes!</p>
<p>First, let's add a new button. Somewhere on the page, add the following snippet. I'm going to add it right below the first paragraph (<code>&lt;p&gt;</code>) tag:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Party with Slurm!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-unstyled-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with unstyled button</em></p>
<p>You'll notice just like all of the other elements, that it's unstyled, however, if you try clicking it, you'll notice it still has the click actions. So let's make it look like a button.</p>
<p>Let's add the following classes:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-white font-bold bg-purple-700 hover:bg-purple-800 py-2 px-4 rounded"</span>&gt;</span>
  Party with Slurm!
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>Here's a breakdown of what's happening:</p>
<ul>
<li><code>text-white</code>: we're setting our text color to white</li>
<li><code>font-bold</code>: set the weight of the text to bold (font-weight)</li>
<li><code>bg-purple-700</code>: set the background color of the button to purple with a shade of 700. The 700 is relative to the other colors defined as purple, you can find these values on their <a target="_blank" href="https://tailwindcss.com/docs/customizing-colors#default-color-palette">palette documentation page</a></li>
<li><code>hover:bg-purple-800</code>: when someone hovers over the button, set the background color to purple shade 800. Tailwind provides these helper classes that allow us to easily define interactive stiles with things like <a target="_blank" href="https://tailwindcss.com/course/hover-focus-and-active-styles/">hover, focus, and active modifiers</a></li>
<li><code>py-2</code>: set the padding of the y-axis to 2rem</li>
<li><code>px-4</code>: set the padding of the  x-axis to 4rem</li>
<li><code>rounded</code>: round the corners of the element by setting the border radius. With tailwind, it sets the border-radius value to .25rem</li>
</ul>
<p>And with all of that, we have our button!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/html-page-styled-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>HTML page with a styled button</em></p>
<p>You can apply this methodology to any other component that you'd like to build. Though it's a manual process, we'll find out how we can make this process easier when building in more dynamic projects like those based on React.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-static/commit/09312336dce316a75e8007d6c935133490f16c25">Follow along with the commit!</a></p>
<h2 id="heading-part-2-adding-tailwind-css-to-a-react-app">Part 2: Adding Tailwind CSS to a React app</h2>
<p>For more of a real-world use case, we're going to add Tailwind CSS to an app created with <a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">Create React App</a>.</p>
<p>First, we'll walk through the steps you need to take to add tailwind to your project using a fresh install of Create React App, then we'll use our content from our last example to recreate it in React.</p>
<h3 id="heading-step-1-spinning-up-a-new-react-app">Step 1: Spinning up a new React app</h3>
<p>I'm not going to detail this step out too much. The gist is we'll bootstrap a new React app using Create React App.</p>
<p>To get started, you can follow along <a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">with the directions</a> from the official React documentation:</p>
<p><a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">https://reactjs.org/docs/create-a-new-react-app.html</a></p>
<p>And once you start your development server, you should now see an app!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/create-react-app-starting-page.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Create React App starting page</em></p>
<p>Finally, let's migrate all of our old content to our app. To do this, copy everything inside of the <code>&lt;body&gt;</code> tag of our static example and paste it inside of the wrapper <code>&lt;div className="App"&gt;</code> in the new React project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/code-migrating-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Migrating code to React app</em></p>
<p>Next, change all <code>class="</code> attributes from the content we pasted in to <code>className="</code> so that it's using proper React attributes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/code-fixing-class-attribute.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Fixing class attribute in content</em></p>
<p>And lastly, replace the className <code>App</code> on our wrapper <code>&lt;div&gt;</code> to the classes we used on our static <code>&lt;body&gt;</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/code-wrapper-styles.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Adding wrapper styles to the app</em></p>
<p>Once you save your changes and spin back up your server, it will look deceivingly okay.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-app-basic-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>React app with basic content</em></p>
<p>React includes some basic styles itself, so while it looks okay, we're not actually using Tailwind yet. So let's get started by installing it!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-dynamic/commit/57993883c77739f71072bcc02ed2398543efc2fd">Follow along with the commit!</a></p>
<h3 id="heading-step-2-installing-tailwind-in-your-react-app">Step 2: Installing Tailwind in your React app</h3>
<p>There are a few steps we'll need to go through in order to get Tailwind up and running on our app. Make sure you follow these steps carefully to ensure it's properly configured.</p>
<p>First, let's add our dependencies:</p>
<pre><code>yarn add tailwindcss postcss-cli autoprefixer
# or
npm install tailwindcss postcss-cli autoprefixer
</code></pre><p><a target="_blank" href="https://tailwindcss.com/docs/installation#4-process-your-css-with-tailwind">Per Tailwind's documentation</a>, we need to be able to process our styles so that they can be properly added to our pipeline. So in the above, we're adding:</p>
<ul>
<li><a target="_blank" href="https://tailwindcss.com/">tailwindcss</a>: the core Tailwind package</li>
<li><a target="_blank" href="https://github.com/postcss/postcss">postcss-cli</a>: Create React App already uses postcss, but we need to configure Tailwind to be part of that build process and run it's own processing</li>
<li><a target="_blank" href="https://github.com/postcss/autoprefixer">autoprefixer</a>: Tailwind doesn't include vendor prefixes, so we want to add autoprefixer to handle this for us. This runs as part of our postcss configuration</li>
</ul>
<p>We're also going to add two dev dependencies that make it easier to work with our code:</p>
<pre><code>yarn add concurrently chokidar-cli -D
# or
npm install concurrently chokidar-cli --save-dev
</code></pre><ul>
<li><a target="_blank" href="https://github.com/kimmobrunfeldt/concurrently">concurrently</a>: a package that lets us set up the ability to run multiple commands at once. This is helpful since we'll need to watch both the styles and React app itself.</li>
<li><a target="_blank" href="https://github.com/kimmobrunfeldt/chokidar-cli">chokidar-cli</a>: let's us watch files and run a command when changed. We'll use this to watch our CSS file and run the build process of the CSS on cahnge</li>
</ul>
<p>Next, let's configure postcss, so create a new file in the root of your project called <code>postcss.config.js</code> and include the following:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Inside postcss.config.js</span>
<span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">plugins</span>: [
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'tailwindcss'</span>),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'autoprefixer'</span>)
    ],
};
</code></pre>
<p>This will add the Tailwindcss and Autoprefixer plugins to our postcss config.</p>
<p>With our configuration, we need to include it as part of the build and watch processes. Inside <code>package.json</code>, add the following to definitions to your <code>scripts</code> property:</p>
<pre><code class="lang-json"><span class="hljs-string">"build:css"</span>: <span class="hljs-string">"tailwind build src/App.css -o src/index.css"</span>,
<span class="hljs-string">"watch:css"</span>: <span class="hljs-string">"chokidar 'src/App.css' -c 'npm run build:css'"</span>,
</code></pre>
<p>Additionally, modify the <code>start</code> and <code>build</code> scripts to now include those commands:</p>
<pre><code class="lang-json"><span class="hljs-string">"start"</span>: <span class="hljs-string">"concurrently -n Tailwind,React 'npm run watch:css' 'react-scripts start'"</span>,
<span class="hljs-string">"build"</span>: <span class="hljs-string">"npm run build:css &amp;&amp; react-scripts build"</span>,
</code></pre>
<p>With our configuration ready to go, let's try our styles back to where they were when we left off from the static example.</p>
<p>Inside the <code>App.css</code> file, replace the entire content with:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;
</code></pre>
<p>This is going to import Tailwind's base styles, components, and utility classes that allow Tailwind to work as you would expect it to.</p>
<p>We can also remove the <code>App.css</code> import from our <code>App.js</code> file because it's now getting injected directly into our <code>index.css</code> file. So remove this line:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
</code></pre>
<p>Once you're done, you can start back up your development server! If it was already started, make sure to restart it so all of the configuration changes take effect.</p>
<p>And now the page should look exactly like it did in our static example!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-app-with-styled-content.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>React app with content styled</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-dynamic/commit/5f50cc218ef58f469dad7f09bdad31f36b58a896">Follow along with the commit!</a></p>
<h3 id="heading-step-3-creating-a-new-button-component-class-with-tailwind">Step 3: Creating a new button component class with Tailwind</h3>
<p>Tailwind doesn't ship with prebaked component classes, but it does make it easy to create them!</p>
<p>We're going to use our button that we already created as an example of creating a new component. We'll create a new class <code>btn</code> as well as a color modifier <code>btn-purple</code> to accomplish this.</p>
<p>The first thing we'll want to do is open up our App.css file where we'll create our new class. Inside that file, let's add:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.btn</span> {
  @apply font-bold py-2 px-4 rounded;
}
</code></pre>
<p>If you remember from our HTML, we're already including those same classes to our <code>&lt;button&gt;</code> element.  Tailwind let's us "apply" or include the styles that make up these utility classes to another class, in this case, the <code>.btn</code> class.</p>
<p>And now that we're creating that class, let's apply it to our button:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn text-white bg-purple-700 hover:bg-purple-800"</span>&gt;</span>
  Party with Slurm!
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>And if we open up our page, we can see our button still looks the same. If we inspect the element, we can see our new <code>.btn</code> class generated with those styles.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-tailwind-button-class.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>.btn class in a React app with Tailwind</em></p>
<p>Next, let's create a color modifier. Similar to what we just did, we're going to add the following rules:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.btn-purple</span> {
  @apply bg-purple-700 text-white;
}

<span class="hljs-selector-class">.btn-purple</span><span class="hljs-selector-pseudo">:hover</span> {
  @apply bg-purple-800;
}
</code></pre>
<p>Here, we're adding our background color and our text color to our button class. We're also applying a darker button color when someone hovers over the button.</p>
<p>We'll also want to update our HTML button to include our new class and remove the ones we just applied:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn btn-purple"</span>&gt;</span>
  Party with Slurm!
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>And with that change, we can still see that nothing has changed and we have our new button class!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/react-tailwind-styled-button.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Styled button in React with Tailwind</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-tailwind-dynamic/commit/7a76e8a4583b0a4c523ea902d73e889c7b86f437">Follow along with the commit!</a></p>
<h2 id="heading-applying-these-concepts-to-more-components">Applying these concepts to more components</h2>
<p>Through this walkthrough, we learned how to create a new component class using the Tailwind apply directive. This allowed us to create reusable classes that represent a component like a button.</p>
<p>We can apply this to any number of components in our design system. For instance, if we wanted to always show our lists the way we set them up here, we could create a <code>.list-ul</code> class that represented an unordered list with the Tailwind utilities <code>list-disc list-inside my-5 pl-2</code> applied.</p>
<h2 id="heading-what-tips-and-tricks-do-you-like-to-use-with-tailwind">What tips and tricks do you like to use with Tailwind?</h2>
<p>Share with me on <a target="_blank" href="https://twitter.com/colbyfayock">Twitter</a>!</p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
