<?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: Charlie Joel</title>
    <description>The latest articles on DEV Community by Charlie Joel (@charliejoel).</description>
    <link>https://dev.to/charliejoel</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%2F678131%2F912cb22f-e745-4f1f-a921-d6d0194a0390.png</url>
      <title>DEV Community: Charlie Joel</title>
      <link>https://dev.to/charliejoel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charliejoel"/>
    <language>en</language>
    <item>
      <title>3 ways your team can improve code quality</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Mon, 25 Apr 2022 10:04:57 +0000</pubDate>
      <link>https://dev.to/charliejoel/3-ways-your-team-can-improve-code-quality-o78</link>
      <guid>https://dev.to/charliejoel/3-ways-your-team-can-improve-code-quality-o78</guid>
      <description>&lt;h2&gt;
  
  
  Pair programming with new hires
&lt;/h2&gt;

&lt;p&gt;Even if the new hire is a great developer, they will inevitably have their own way of doing things that may not marry up perfectly to the way your agency does things. Taking the time to do some pair programming and code reviews can go a long way in getting them onto the same page.&lt;/p&gt;

&lt;p&gt;There are also production benefits to this practise: &lt;a href="https://www.researchgate.net/publication/2333697_The_Costs_and_Benefits_of_Pair_Programming"&gt;Williams et al (2000), The Costs and Benefits of Pair Programming&lt;/a&gt;, indicates that for a slightly increased development time of around 15%, projects which utilise pair programming show a reduction in bugs and risk, as well as improving team skills and communication.&lt;/p&gt;

&lt;p&gt;While some managers may wince at the idea of increasing development time, take this into consideration: between bugfixing, repeated deployments, QA testing and back-and-forth with clients, program defects can take up as much development time as building the thing in the first place. Even worse, if hard limits on time allocated to bugfixing is not discussed with the client, agencies can easily overspend on time spent simply getting a website up to standard. Without a doubt, it is more cost effective to do things right the first time around. In the long run pair programming could greatly decrease the cost and development time of projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r5bEi4PB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4pvjo60fnhqlrrpsdl0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r5bEi4PB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4pvjo60fnhqlrrpsdl0.jpg" alt="Pair programming" width="880" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pair programming has also been &lt;a href="https://www.researchgate.net/publication/220422564_Pair_programming_improves_student_retention_confidence_and_program_quality"&gt;shown to improve developer engagement and satisfaction&lt;/a&gt;, as well as making devs &lt;a href="https://files.eric.ed.gov/fulltext/EJ1140923.pdf"&gt;more confident in their solutions&lt;/a&gt;. There's also evidence that pair programming may help with inclusivity, particularly improving female representation in programming. It might be that it's a break from the monotony of independent work,  the learning experience or just the chance to improve work relationships, but it's clear that developers who code in pairs are happier and have more pride in their work.&lt;/p&gt;

&lt;p&gt;There are even Git workflows, such as &lt;a href="https://trunkbaseddevelopment.com/"&gt;Trunk-based development&lt;/a&gt;, which embrace the idea of pair programming whole-heartedly. This style of development is not only great for improving development quality in small teams, but also improves each team member by forcing them to explain and justify their code while taking in contributions from their peers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have everyone use the same auto-formatter
&lt;/h2&gt;

&lt;p&gt;Formatting code is one of the longest running arguments in programming. Line length, tabs vs spaces, padding parenthesis with whitespace - all these issues can be made consistent by using a formatter. Even better, you can enable format-on-save in most IDE settings, meaning you can forget about formatting entirely. Just press save, et voila! Beautiful code.&lt;/p&gt;

&lt;p&gt;However, this becomes an issue when working on a team of developers. Why? Well, if only one person is using a formatter, every time they save a file the whole structure will change. This will show up in git, so it becomes impossible to see what has changed with each commit, because when a formatter does its job it can change every single line of code. If you can't see what's changed, it becomes hard to figure out how something went wrong when it inevitably does. It also really messes up any merges you try. The same goes for if multiple people are using formatters with different settings. Each will end up overwriting the previous developer's code every time they work on a file.&lt;/p&gt;

&lt;p&gt;The solution is for everyone on the team to use the same settings. We can then have beautiful, readable code, with no effort and no problems with source control. This takes a bit of time to setup, but for the time saved later on it's worth it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Formatters
&lt;/h3&gt;

&lt;p&gt;There are a few known formatters for most editors - I'll be focusing on VSCode, since it's what I used. If you use a different editor, google is your friend: experience will vary based on what you use.&lt;/p&gt;

&lt;p&gt;Personally, I have been using the &lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode"&gt;Prettier&lt;/a&gt; extension to do my formatting as it supports all the languages I use on a regular basis. If you're a frontend developer, chances are this will cover the majority of languages you need to use.&lt;/p&gt;

&lt;p&gt;For other languages, there are plenty of other extensions that will handle formatting of these languages. You may need to configure your VSCode settings to get them working for specific languages.&lt;/p&gt;

&lt;p&gt;If you're a backend developer and use Visual Studio, there are similar extensions which can handle formatting of any language you require.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linters
&lt;/h3&gt;

&lt;p&gt;Formatters tend to take their rules from linters - scripts that raise issues if your code doesn't follow a particular standard. It's a good idea to run linters alongside your formatter, so they can highlight any issues you missed or if you forgot to format a particular file. This might be redundant, however, if you opt to enable format-on-save in VSCode. This way, you won't even need to think about formatting - every time you save a file, everything is automatically taken care of.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xxzcPvBu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sn5t5ogffehzs6gk69so.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xxzcPvBu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sn5t5ogffehzs6gk69so.png" alt="Image description" width="880" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up format-on-save in VSCode
&lt;/h3&gt;

&lt;p&gt;VSCode official supports format-on-save, so this can be enabled by changing a property in your settings.json file. To access this file, press Ctrl + Shift + P and type in 'settings' - then select 'Preferences: Open settings (JSON)'.&lt;/p&gt;

&lt;p&gt;Add the following line:&lt;/p&gt;

&lt;p&gt;"editor.formatOnSave": true&lt;/p&gt;

&lt;p&gt;If not already set, you will also want to set your default formatter here:&lt;/p&gt;

&lt;p&gt;"editor.defaultFormatter": "esbenp.prettier-vscode"&lt;/p&gt;

&lt;p&gt;Once you've done this, save the file and reload your VSCode. Your files will now be formatted automatically, with zero time and effort!&lt;/p&gt;

&lt;h2&gt;
  
  
  Write up a methodology guidebook
&lt;/h2&gt;

&lt;p&gt;We all know (roughly) how to use BEM, sure. We all know how to name variables, how to use the block-element-modifier pattern, and how to structure our CSS for performance and readability.&lt;/p&gt;

&lt;p&gt;The problem is that even within those rules, everyone has idiosyncrasies in the way they use them. Some people who use BEM will insist on heavy nesting. Some people will style elements directly, even though it encourages the unholy !important rule.&lt;/p&gt;

&lt;p&gt;Drilling down into exactly what the guidelines for code quality are helps new developers understand what is expected of them, encourages learning and higher code quality, and overall reduces potential problems caused by different approaches. It also helps bridge the gap between senior and junior/mid developers - by having the important information in writing, it's not locked away in the minds of only a few developers.&lt;/p&gt;

&lt;p&gt;Take CSS, for example. It's a great language - very powerful. The problem is that, by using its multitude of features without any rules, we end up writing difficult to understand code. This is circumvented by methodologies, yes, but methodologies don't always go into the detail they should. Over time, agencies and individuals accumulate a set of rules which guide them to a cleaner codebase.&lt;/p&gt;

&lt;p&gt;Keeping and maintaining a document or web page that explains these rules, including the minute details and unique features of an agencies own approach, is a fantastic tool for both new hires and old heads. Including this document in the required reading for new hires gives them a head-start, and being strict about these rules when reviewing pull requests can help to solidify the best approach in the workflow of developers.&lt;/p&gt;

&lt;p&gt;There are a few principles which make up a solid coding style guide:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Comprehensive &amp;amp; accessible
&lt;/h3&gt;

&lt;p&gt;Your style guide should be well documented: Lack of documentation will lead to confusion, and allows developers to fill in the blanks themselves. On the flipside, this document should be no longer than it needs to be. Nobody will be able to remember a hundred different rules, and so code standards will be fragmented and inconsistent.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Logical &amp;amp; justified
&lt;/h3&gt;

&lt;p&gt;This material should not boil down to someone's opinion, and if it is it must be well thought out and justified. If not, it's likely that developers will disagree with the style guide and may push to change the guide. It's a good idea to get everyone's own opinion from your team and then debate pros and cons of each. The standards should work for everyone, not just one or two developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Purpose-built
&lt;/h3&gt;

&lt;p&gt;While online guides are a fantastic starting point, they may not consider all the nuances and workflows of your team. Whether you need commits written a certain way for Git flow, or you're using a CSS framework such as &lt;a href="https://charliejoel.dev/blog/6-reasons-to-use-tailwind-over-traditional-css"&gt;Tailwind&lt;/a&gt;, there will be unique requirements for every team.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Enforced
&lt;/h3&gt;

&lt;p&gt;It's no use having a style guide if it's just going to be ignored! The two most obvious ways to enforce standards are with pull requests, and pair programming. I would personally advocate for pair programming, since it's a much more focused format and because it's easy to skim over a pull request on a really busy day, but as with the previous point: Whatever works best for your team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coding Standards Resources &amp;amp; Examples
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.geeksforgeeks.org/coding-standards-and-guidelines/#:~:text=A%20coding%20standard%20gives%20a,increases%20efficiency%20of%20the%20programmers."&gt;GeeksforGeeks - Code Standards and Guidelines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/cxpartners/coding-standards"&gt;CXPartners front-end coding standards&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/o3world/o3w-frontend-guidelines"&gt;O3 World Front-End Coding Standards (HTML &amp;amp; CSS)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://handbook.imarc.com/frontend"&gt;imarc Frontend Handbook&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>6 tips to avoid headaches in SCSS</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Mon, 13 Dec 2021 14:03:23 +0000</pubDate>
      <link>https://dev.to/charliejoel/6-tips-to-avoid-headaches-in-scss-jp0</link>
      <guid>https://dev.to/charliejoel/6-tips-to-avoid-headaches-in-scss-jp0</guid>
      <description>&lt;h2&gt;1. Never style elements&lt;/h2&gt;

&lt;p&gt;This is probably the biggest cause of headaches, at least in my experience. It seems innocent enough to style a button or a heading - they're buttons and headings, of course they should look like buttons and headings.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// don't do this!
button {
  background-color: $color-btn;
  border-radius: 4px;
}

// nooooo!
h2 {
  font-size: 40px;
  font-weight: bold;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But!&lt;/p&gt;

&lt;p&gt;What if you have an element that should look like a link, but is really a button? Or if you have a button which needs to look different from all the others, such as with hamburger/pancake menus (there's a lot of debate on exactly which food item these look like, I think it's a pancake).&lt;/p&gt;

&lt;p&gt;What if your headings need a different size or style in a particular context?&lt;/p&gt;

&lt;p&gt;In all these cases, you would have to manually un-style these elements in their own class. And because element styling wins specificity wars over classes, you would often need to use the &lt;code&gt;!important&lt;/code&gt; rule - a huge no-no.&lt;/p&gt;

&lt;p&gt;Instead, assign classes to your elements. This is much more expressive than styling raw elements as you can state the intention of the element through it's class. You can also reuse the class on different elements, such as with buttons and links.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// better
.button {}
.heading-2 {}&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;// now you can reuse the classes!
&amp;lt;button class="button"&amp;gt;I am a button&amp;lt;/&amp;gt;
&amp;lt;a class="button"&amp;gt;I am link, but I look like a button&amp;lt;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you need to style elements for a Rich Text Editor or WYSIWYG section, or anywhere else you might not be able to add classes directly, you can do so by nesting. By putting a &lt;code&gt;.rte&lt;/code&gt; class on the container for these sections, you can scope your element styles to only target what you need to.&lt;/p&gt;

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

.rte {
  &amp;amp; h2 {
    font-size: 28px;
    font-family: $font-headings;
    font-weight: bold;
    line-height: 1.3;
  }

  &amp;amp; p {
    font-size: 16px;
    margin-bottom: 16px;
  }

  &amp;amp; ul {
    // etc...
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;// article template

&amp;lt;article class="rte"&amp;gt;
  &amp;lt;!-- content added by cms --&amp;gt;
&amp;lt;/article&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;2. Strive to never use !important&lt;/h2&gt;

&lt;p&gt;Your CSS should follow rules, and your classes shouldn't overstep each other. The more tangled up in the web of specificity and nested selectors your code becomes, the harder your codebase will be to work with. You'll end up adding &lt;code&gt;!important&lt;/code&gt; to properties that really have no need to be, and the more of these rules you have in the first place the more you'll have to use it again to override these rules. It's a downward spiral of manually forcing specificity, and it has rippling consequences for your CSS.&lt;/p&gt;

&lt;p&gt;There are a few ways to avoid using !important[]: For one, keeping your CSS structure as flat as possible can avoid any specificity wars that could crop up. Nesting CSS, and using complex selectors to target classes in specific situations, are things many developers do without realising they are lining up headaches and delays for themselves in future.&lt;/p&gt;

&lt;h2&gt;3. Use reset.css&lt;/h2&gt;

&lt;p&gt;Cross-browser consistency is one of the major problems surrounding not only CSS, but also JS and even accessibility with ARIA. In CSS, we can lay out a level playing field using a reset.css file. This will remove any browser-specified styles, such as margins, font sizes, button styles etc. so every browser will show the same thing.&lt;/p&gt;

&lt;p&gt;reset.css is also great because we don't need to waste time overwriting default styles: If your &amp;lt;button /&amp;gt; needs to have a transparent background and no borders, we would normally need to specify these in our own CSS. This way, we know any CSS we are writing is &lt;em&gt;additive&lt;/em&gt; instead of being &lt;em&gt;subtractive&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.button {
  // these properties wouldn't be necessary with reset.css
  background-color: transparent;
  border: none;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Subtractive CSS, where we write styles to overwrite other styles, is generally a big no-no as it adds a level of confusion to what a class is doing. CSS classes, as with anything in programming, should be concise and to the point. If you find yourself writing subtractive or overwriting CSS, it may be worth tracing back to find what it's overwriting, and breaking down the original styles further using placeholders[link] or mixins[link].&lt;/p&gt;

&lt;p&gt;You could also use normalize.css. This will maintain a set of default page margins and other element-level styles across browsers. Personally, I prefer reset.css due to the fact that I want to control everything on a page without being interrupted by default styles - I don't want any page to have a margin on the body, for example, and writing code to undo these margins makes my code confusing. However, this might work better for you if you want some defaults.&lt;/p&gt;

&lt;h2&gt;4. Use variables to stay DRY&lt;/h2&gt;

&lt;p&gt;DRY, meaning Don't Repeat Yourself, is a key concept to understand for any kind of programming. In SCSS, the best place to start with this is in using variables, placeholders and mixins. The most common of these you'll be using is variables.&lt;/p&gt;

&lt;p&gt;Let's say you're looking at a design you need to create, and it has many colours across it. You can make your life much easier by assigning these colours to variables, perhaps with a kind of hierarchy which relates to the brand you're working with. There are lots of different ways to name variables, &lt;a href="https://css-tricks.com/what-do-you-name-color-variables/" rel="noopener noreferrer"&gt;as outlined in this CSS Tricks article.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another great use of SCSS variables is naming the top level of components. Here, I use &lt;code&gt;$module&lt;/code&gt; to store the name of the component and am then free to reuse it in other places, without needing to worry if I want to change the name of that component for some reason.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// we can change $module at any time in one place
$module: 'nav';

.#{$module} {
  &amp;amp;__dropdown-link {
    position: relative;
  }

  &amp;amp;__dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    display: hidden;
    
    .#{$module}__dropdown-link:hover &amp;amp; {
      display: block;
    }
  }&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;// above css applied to html, for reference

&amp;lt;li class="nav__dropdown-link&amp;gt;
  &amp;lt;a&amp;gt;Link title&amp;lt;/a&amp;gt;
  &amp;lt;ul class="nav__dropdown"&amp;gt;
    ...
  &amp;lt;/ul&amp;gt;
&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;5. Use placeholders&lt;/h2&gt;

&lt;p&gt;Placeholders are a great way to save time and file size with SCSS. They are essentially groups of properties which you can apply in a similar way to variables, and further build on top of them.&lt;/p&gt;

&lt;p&gt;I've used placeholders on &lt;a href="https://charliejoel.dev/" rel="noopener noreferrer"&gt;my own site&lt;/a&gt; to help generate a set of paragraph styles using the &lt;a href="https://grtcalculator.com/" rel="noopener noreferrer"&gt;Golden Ratio Typography Calculator&lt;/a&gt; (check it out!) which downsize appropriately at different resolutions:&lt;/p&gt;

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

%t-1\/2 {
  font-size: 14px;
  line-height: 1.786;
}

%t-1 {
  font-size: 18px;
  line-height: 1.722;
}

%t-2 {
  font-size: 23px;
  line-height: 1.652;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;// ...can be easily reused for different breakpoints
.t {
  &amp;amp;-1 {
    @extend %t-1\/2;
    @screen lg { // @screen is a tailwind directive - these are just desktop-first breakpoints!
      @extend %t-1;
    }
  }
  &amp;amp;-2 {
    @extend %t-1;
    @screen lg {
      @extend %t-2;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As well as needing to write less code, we are also building a sensible design system with our CSS to ensure consistency between elements and enforce a single source of truth.&lt;/p&gt;

&lt;h2&gt;6. Don't set a max-width on &amp;lt;main&amp;gt;&lt;/h2&gt;

&lt;p&gt;More often than not, any content on a webpage has a certain &lt;code&gt;max-width&lt;/code&gt; which it cannot exceed. This helps with readability and keeps the page content flush all the way down.&lt;/p&gt;

&lt;p&gt;If you're a beginner, it may be instinctive to set this &lt;code&gt;max-width&lt;/code&gt; on an element that's quite high up in the hierarchy - the &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; element for instance, or even the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;. On a page that has the same background color all the way down, this might be perfectly fine. Most webpages, however, are broken up by different sections that have a background color spanning the entire width of the page. &lt;/p&gt;

&lt;p&gt;The issue you will run into by setting a max-width on the &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, is that this background color will be limited by the max-width. Beyond this &lt;code&gt;max-width&lt;/code&gt;, the background color will be white (or whatever color the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; is set to).&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%2Fapi.charliejoel.dev%2Fwp-content%2Fuploads%2F2021%2F12%2Fimage-3-1024x449-1.png" 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%2Fapi.charliejoel.dev%2Fwp-content%2Fuploads%2F2021%2F12%2Fimage-3-1024x449-1.png" alt=""&gt;&lt;/a&gt;Ugly whitespace!&lt;/p&gt;

&lt;p&gt;You can avoid this by segregating this max-width effect into sections. To do so, you will need a parent element which takes on the background color you want, and a child element inside it that applies the max-width effect. Repeat for each section of the page, and you will end up with the desired effect.&lt;/p&gt;

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

&amp;lt;main&amp;gt;
  &amp;lt;section class="section section--bg-primary"&amp;gt;
    &amp;lt;div class="section__inner"&amp;gt;
      &amp;lt;h2&amp;gt;Hello world!&amp;lt;/h2&amp;gt;
      &amp;lt;p class="paragraph"&amp;gt;
        Lorem ipsum dolor sit amet...
      &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/section&amp;gt;
  &amp;lt;section class="section section--bg-secondary"&amp;gt;
    &amp;lt;div class="section__inner"&amp;gt;
      &amp;lt;h2&amp;gt;Hello again world!&amp;lt;/h2&amp;gt;
      &amp;lt;p class="paragraph"&amp;gt;
        Lorem ipsum dolor sit amet...
      &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/section&amp;gt;
&amp;lt;/main&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;// layout/_section.scss

.section {
  // use the parent element to add padding
  padding: 48px 16px;

  &amp;amp;--bg-primary {
    background-color: $color-primary;
    color: white;
  }
  
  &amp;amp;--bg-secondary {
    background-color: $color-secondary;
    color: black;
  }

  &amp;amp;__inner {
    // set the max-width on the inner element
    max-width: $max-w-page;
    width: 100%;
    margin: 0 auto;
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here it is - a layout with full-width background colors, padding and a max-width. You might want to set some of these values as variables or placeholders so you can repeat in other areas - for instance, a nav bar will often need the same effect, as will a footer.&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%2Fapi.charliejoel.dev%2Fwp-content%2Fuploads%2F2021%2F12%2Fimage-4-1024x452.png" 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%2Fapi.charliejoel.dev%2Fwp-content%2Fuploads%2F2021%2F12%2Fimage-4-1024x452.png" alt=""&gt;&lt;/a&gt;Lovely full-width background color&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>css</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Don't mix Tailwind with CSS</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Fri, 03 Dec 2021 11:41:31 +0000</pubDate>
      <link>https://dev.to/charliejoel/dont-mix-tailwind-with-css-5c05</link>
      <guid>https://dev.to/charliejoel/dont-mix-tailwind-with-css-5c05</guid>
      <description>&lt;p&gt;Tailwind is the new kid on the block; it's fast, it's got a tiny footprint, and it encourages a new way of working in component-based architectures. That being said, it gets a lot of hate in the Frontend community and it's easy to see why.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Followers of traditional HTML-CSS-JS workflows complain that it works against the principles we have all followed for the past 10-20 years of web development. Keeping all your styles in one place makes sense, and makes life much easier when it comes to maintaining a frontend. If you use a methodology like BEM, you can understand where the styles for a component will be just by reading the class name.&lt;/p&gt;

&lt;p&gt;When we add Tailwind into a traditional frontend, every one of these principles goes straight out the window. Styling is no longer confined to one area or file type - it's split between CSS, HTML and sometimes even JavaScript. We might change a CSS property, only to realise there's a Tailwind class that overrides it completely. All of this leads to a mess that is difficult to understand and maintain. The choice between the two approaches should be either-or: No mixing Tailwind with CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  So it Tailwind actually bad?
&lt;/h2&gt;

&lt;p&gt;Tailwind, just like regular CSS, can work beautifully if used correctly. As is often the case with styles, the issues start to appear in droves as soon as we misuse the technology and ignore the rules that keep developers sane. Poorly written CSS is just as confusing as misused Tailwind.&lt;/p&gt;

&lt;p&gt;This technology is still in it's early stages, but I'm a huge advocate for Tailwind and have used it in quite a few different projects. I've written more about why it's so good, and particularly how to use it, in my other articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://charliejoel.dev/blog/6-reasons-to-use-tailwind-over-traditional-css"&gt;6 reasons to use Tailwind over traditional CSS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://charliejoel.dev/blog/how-to-keep-tailwind-dry"&gt;How to keep Tailwind DRY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://charliejoel.dev/blog/how-to-love-tailwind"&gt;How to love Tailwind&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>tailwindcss</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>!!null = false: How to evaluate any expression to a boolean</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Mon, 01 Nov 2021 20:04:30 +0000</pubDate>
      <link>https://dev.to/charliejoel/null-false-how-to-evaluate-any-expression-to-a-boolean-2m2</link>
      <guid>https://dev.to/charliejoel/null-false-how-to-evaluate-any-expression-to-a-boolean-2m2</guid>
      <description>&lt;p&gt;Here is a quick trick that I've been enjoying quite a bit. I'll start with this expression as an example of the problem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if (x !== undefined &amp;amp;&amp;amp; x !== null &amp;amp;&amp;amp; x !== "" &amp;amp;&amp;amp; x !== 0) {
  // do something
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you've spent any time with JavaScript, and especially with React, you will probably have written something similar to this. Being a &lt;a href="https://flaviocopes.com/loosely-strongly-typed/" rel="noreferrer noopener"&gt;loosely typed&lt;/a&gt; language, it's often necessary to check for multiple 'falsey' types to avoid errors. &lt;/p&gt;

&lt;p&gt;There's nothing inherently wrong with it, but it's quite wordy. In my opinion, long expressions like this make it harder to parse through a file and understand what's going on. I'm a big advocate for making code as human-readable as possible, so using multiple lines to express just one thing is a big no-no for me.&lt;/p&gt;

&lt;p&gt;However, there is a better option!&lt;/p&gt;

&lt;p&gt;A while ago I discovered that alongside being able to invert an expression using the &lt;code&gt;NOT&lt;/code&gt; &lt;code&gt;!&lt;/code&gt; operator, it's also possible to chain more than one of these together. This means you can evaluate any variable or expression to a boolean, so you can check if something exists using just 2 characters even if that thing could appear as multiple types.&lt;/p&gt;

&lt;p&gt;Here's an example in React:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{!!props.heading &amp;amp;&amp;amp; (
  &amp;lt;h2&amp;gt;{ props.heading }&amp;lt;/h2&amp;gt;
)}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this scenario, props.heading could appear as &lt;code&gt;undefined&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt;, OR it could appear as an empty string &lt;code&gt;""&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The main problem this trick solves is that &lt;code&gt;null&lt;/code&gt; doesn't actually evaluate to &lt;code&gt;false&lt;/code&gt; on it's own: it's a unique and slightly irritating type that can cause all sorts of problems in JavaScript. Using the double &lt;code&gt;NOT&lt;/code&gt; operator &lt;code&gt;!!&lt;/code&gt; fixes this issue and avoids the need for additional expressions to check for other falsey cases.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// this wordy expression
(x !== undefined &amp;amp;&amp;amp; x !== null &amp;amp;&amp;amp; x !== "" &amp;amp;&amp;amp; x !== 0)

// can be reduced down to this!
!!x&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's also, in my opinion, much easier to read. If I see two exclamation marks before a variable or expression, I know it's definitely checking if the variable exists. I prefer this over simply writing, &lt;code&gt;{ props.heading &amp;amp;&amp;amp; (&amp;lt;&amp;gt;...&amp;lt;/&amp;gt;) }&lt;/code&gt; because with the latter example props.heading could be &lt;code&gt;null&lt;/code&gt;, which doesn't immediately evaluate to &lt;code&gt;false&lt;/code&gt;, or the string could be empty, which doesn't evaluate to &lt;code&gt;false&lt;/code&gt; either. This extra step ensures the data is actually useful for something before moving on while communicating to the developer that this is the intention of the expression.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// null exists in a world of its own

null === false // false
null === true // false

'' === false // false&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;When to avoid the double NOT operator&lt;/h2&gt;

&lt;p&gt;As useful as this little trick is, you should avoid it when working with numbers. This is because the number &lt;code&gt;0&lt;/code&gt; is inherently falsey. If you're checking if the number exists, and it does exist but the number is &lt;code&gt;0&lt;/code&gt;, it will think that the number doesn't exist. This might be what you want in some situations, but it's good to be aware of. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>css</category>
    </item>
    <item>
      <title>Progressing from a beginner to intermediate developer</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Mon, 20 Sep 2021 08:14:04 +0000</pubDate>
      <link>https://dev.to/charliejoel/progressing-from-a-beginner-to-intermediate-developer-2jk1</link>
      <guid>https://dev.to/charliejoel/progressing-from-a-beginner-to-intermediate-developer-2jk1</guid>
      <description>&lt;p&gt;So, you're not a complete beginner anymore: You've built a few webpages, learned the basics of HTML, CSS and JS, and perhaps you've landed a job as a junior developer.&lt;/p&gt;

&lt;p&gt;What now?&lt;/p&gt;

&lt;p&gt;There is a hell of a lot of information online about what you should do as a beginner just starting out, but the roadmap becomes less clear once you've got a handle on the basics. It's not for lack of content: there are plenty of guides out there for all skill levels. Rather, the sheer amount of information, tutorials, opinions and technologies makes it impossible to know which route to go down.&lt;/p&gt;

&lt;h2&gt;Building a strong foundation&lt;/h2&gt;

&lt;p&gt;Your route to improvement will generally depend on what you want to do. With that said, you can't go wrong with simply improving your fundamental skills. Let's say you want to eventually be a React developer: Yes, learning React now would certainly get you into the ecosystem faster, but ignoring what React is built on - plain old JavaScript - can limit you in future. If you want to raise the ceiling of your potential skill level, learning the ins and outs of the base language is the way to go. You will end up with more clean, intentional code that you understand completely, and spend less time figuring out why it's not working straight away. Don't feel like you can't experiment with different technologies: Learning SASS, for example, isn't so far off CSS that it can't teach you the basics while also gaining the benefit of a preprocessor. React is still just JavaScript under the hood. You'll get the best results by pushing yourself out of your comfort zone just enough to make sure you're learning at a steady rate, while also making sure you give yourself enough time to soak in all the information.&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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2Fpyramid.jpg%3Fw%3D480" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2Fpyramid.jpg%3Fw%3D480" alt=""&gt;&lt;/a&gt;Everything is built on core skills&lt;/p&gt;

&lt;p&gt;If you want to be a frontend at an agency, master basic CSS and fully understand what each line of your CSS is doing. If you're a backend developer, wrap your head around the key concepts and build as much as possible yourself before reaching for a framework. If you'd rather be making frontend apps in the future, get to grips with vanilla JavaScript - ignore jQuery and any flashy framework for now. Of course, feel free to dip your toes - but remember that learning programming is a life's work, and building upwards with a poor foundation will reflect in the quality of your work.&lt;/p&gt;

&lt;p&gt;Bear in mind that I'm a frontend, and this advice is generally geared towards other frontends. I don't think everyone should aim to become a full-stack developer; however, I think it's worth everyone having some awareness of the entire ecosystem, as even a little experience will make it easier to work in teams.&lt;/p&gt;

&lt;p&gt;Don't take this list as the be-all and end-all to improving: how you improve depends on what you want to do. However, these are some areas that most developers could learn from in some way.&lt;/p&gt;

&lt;h2&gt;1. CSS organisation&lt;/h2&gt;

&lt;p&gt;It's not sexy, but poor CSS organisation is the most prevalent cause of headaches in web development.&lt;/p&gt;

&lt;p&gt;How many times have you gone to change a class only to realise it's affected elements across the whole website? Or changed some HTML very slightly, only for the whole component to break?&lt;/p&gt;

&lt;p&gt;Methodologies exist as an attempt to systematically avoid these types of issues. By following a particular syntax when writing CSS classes and following a set of rules, we can filter out most of the common problems and allow ourselves to just focus on building stuff.&lt;/p&gt;

&lt;p&gt;Oddly, most of these methodologies aim to make you use less of certain features in CSS. While it's a decent language, most devs know that CSS can be a chaotic language. Even between different methodologies, each has their own rules and situations where they work best.&lt;/p&gt;

&lt;p&gt;Being aware of a variety of these methodologies allows you to easy fit into any team easily, but it also gives inspiration for further refining your CSS development. And above all, you'll have less headaches! No methodology is perfect, so sometimes you'll want to adapt your method for a certain project. CSS organisation is far from a 'solved' problem, as the flexibility of the languages allows plenty of room for new approaches.&lt;/p&gt;

&lt;p&gt;Utility-first frameworks have become very popular lately, especially amongst React and Vue developers. I've written quite a bit about &lt;a rel="noreferrer noopener" href="https://charliejoel.dev/blog/6-reasons-to-use-tailwind-over-traditional-css"&gt;Tailwind CSS&lt;/a&gt;, which is just one flavour of the utility-first ideology, but I wouldn't recommend any beginner to jump into a framework such as Tailwind, Bootstrap or anything that packages CSS classes for you until you deeply understand vanilla CSS and SCSS. If you want to give it a go, try to think about &lt;a href="https://charliejoel.dev/blog/how-to-keep-tailwind-dry" rel="noopener noreferrer"&gt;how to keep your CSS DRY&lt;/a&gt; using these technologies.&lt;/p&gt;

&lt;h2&gt;2. Go CSS-only&lt;/h2&gt;

&lt;p&gt;Here's a fun exercise: build a functional navigation, with hamburger button and multi-level sliding mobile menu without a single line of JavaScript. It doesn't really matter how it looks, just that it functions as you'd expect a mobile nav to. It's surprising how much use you can squeeze out of plain old CSS for simple things such as toggling a 'class'. You can use sibling selectors &lt;code&gt;~&lt;/code&gt; or &lt;code&gt;+&lt;/code&gt; alongside &lt;code&gt;checkbox:checked&lt;/code&gt; to create toggles and trigger them using a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;CSS is much more performant than JavaScript, so while you shouldn't go overboard with these hacks it's good to be aware of performance shortcuts like these. In general, even if JavaScript is unavoidable a good rule is to keep it as minimal as possible without affecting functionality. Usually the simpler something is, the less there is that can go wrong with it. A common example is hover states: You COULD use the &lt;code&gt;mouseover&lt;/code&gt; event to add a class that makes a dropdown visible, but in most cases there's no need as you could use a nested hover state which would be easier on the user's hardware.&lt;/p&gt;

&lt;p&gt;How about no images? The &lt;code&gt;background&lt;/code&gt; property is surprisingly powerful: it can be used to create complex shapes similar to SVG. &lt;a rel="noreferrer noopener" href="https://dev.to/alvaromontoro"&gt;Alvaro Montoro&lt;/a&gt; even created &lt;a href="https://dev.to/alvaromontoro/homer-simpson-in-css-with-a-single-html-element-4ood" rel="noreferrer noopener"&gt;Homer Simpson using just one element.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;3. Single source of truth&lt;/h2&gt;

&lt;p&gt;In all your programming, you should aim to have a single source of truth for everything. This is the core idea behind DRY - Don't Repeat Yourself - programming. In order to not repeat yourself, you need to define everything only once. This plays out in different ways depending on the context.&lt;/p&gt;

&lt;p&gt;In CSS, you want to store all the values that appear time and time again in variables. Colors, fonts, max-widths, even spacing such as padding or margins are all properties that tend to be consistent across an entire project. You can often define variables for a stylesheet based on the brand guidelines, if you have access. Otherwise it's a good idea to go through the site designs and define your variables before starting.&lt;/p&gt;

&lt;p&gt;In JavaScript, every function you write should only appear once. If you need to reuse it in a different place, isolate it from the context you're working in by putting it into it's own file. You'll often see a &lt;code&gt;util&lt;/code&gt; folder in JavaScript file structures - generally this is where you'll find more generic functions used across the app.&lt;/p&gt;

&lt;p&gt;Variables can also be sources of truth. It's a good idea to put global constants - variables that will never change that are used across the app - into their own file for organisation. Some developers name global constants with &lt;code&gt;CAPITALISED_SNAKE_CASE&lt;/code&gt; to differentiate them from regular variables.&lt;/p&gt;

&lt;p&gt;In a similar vein, get used to using environment variables. These are global constants that change depending on the environment: Say you have a 'development' API for testing and a 'live' API for production - you can define both in separate files, and when the time comes to build your app you can ask it to build for either a 'development' or a 'production' environment. This means you don't need to change a load of variables when releasing an app - super helpful!&lt;/p&gt;

&lt;h2&gt;3. Go vanilla&lt;/h2&gt;

&lt;p&gt;Forget jQuery or any other libraries you might normally reach for. Try building your sites using no external packages, just vanilla JS. Feel free to compile your ES6/7 if you need to, but that's it.&lt;/p&gt;

&lt;p&gt;You'll find this difficult at first, but eschewing 3rd-party code forces you to learn how every piece of your application works. Focus on creating reusable utilities for things such as selecting elements, manipulating the DOM, and handling requests.&lt;/p&gt;

&lt;p&gt;Development will be slow, but the goal isn't to build things quickly: Rather, you should spend plenty of time on the research to get these things to understand the building blocks of your craft.&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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2F5ng2dq.jpg%3Fw%3D513" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2F5ng2dq.jpg%3Fw%3D513" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Learn string and array methods, how to work with objects, using Promises and so on. Doing daily exercises with a service such as &lt;a rel="noreferrer noopener" href="https://exercism.org/tracks/javascript/exercises"&gt;Exercism&lt;/a&gt; is a great way to learn each method, but using them in context is what will take you from beginner to expert level. You'll see that there are many ways to skin a cat, and how you choose to solve a particular problem will depend on the situation as well as (to an extend) your personal style. For example, some people prefer to handle promises using &lt;code&gt;.then().catch()&lt;/code&gt;, but I would always use &lt;code&gt;async/await&lt;/code&gt; as I find the syntax much tidier. There are people who will argue you should use x over y, but it's a good idea to understand every possible way of doing something since you don't know if you'll be dropped into a project with legacy code or if the previous developer just had a different way of doing things.`&lt;/p&gt;

&lt;p&gt;How about building your own reactive framework? &lt;a rel="noreferrer noopener" href="https://www.youtube.com/watch?v=f2mMOiCSj5c"&gt;Watch Tejas Kumar's fantastic talk&lt;/a&gt; about creating a rudimentary React clone. You don't need to build it, just try to understand it. You'll find that the technologies you use every day, while undoubtedly complex, aren't so impossible to understand as they first appear.&lt;/p&gt;

&lt;h2&gt;4. Manage your own server&lt;/h2&gt;

&lt;p&gt;Although DevOps and servers can be scary to a beginner, having a small server to mess around with will help to introduce you without any pressure. Start small and build up: You don't need to learn everything straight away: exposure to concepts and configurations surrounding your server will gradually engrain the knowledge in your head.&lt;/p&gt;

&lt;p&gt;Even if you're solely a frontend or aren't interested in running your own websites, understanding things like htaccess, robots.txt and deployment pipelines will make you much more desirable to employers. You will almost definitely need to deploy to a server at some point, so getting the learning in ahead of time will put you a step ahead of the competition. Having a platform to showcase your ideas opens up limitless possibilities, improves your knowledge, and it's just good fun.&lt;/p&gt;

&lt;h2&gt;5. Learn regex&lt;/h2&gt;

&lt;p&gt;Learning the regex for your language of choice opens up a &lt;a rel="noreferrer noopener" href="https://blog.katherinempeterson.com/practical-applications-for-regex"&gt;whole host of opportunities&lt;/a&gt; including web scraping, which allows you to use any web page as your data source. It also allows you to write complicated logic for strings, such as validating form content, with much more brevity than when using string functions. Regex is commonly used for verifying the format of strings, for example ensuring a phone number is the correct length or a postcode/zip code is in the right format.&lt;/p&gt;

&lt;p&gt;To get you started, here's a quick rundown of a pattern I use constantly in JavaScript (syntax may change depending on language). &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// replace 'tag' with your html tag of choice
/&amp;lt;tag(.*?)&amp;gt;|&amp;lt;\/tag&amp;gt;/gi&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can use &lt;code&gt;(.*?)&lt;/code&gt; to create a capture group that will match any content between the string to the left and right of it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;() - creates a capture group
.  - matches any single character
*  - matches the previous character infinitely e.g. 'heel'.match(/e*/) = 'ee'
?  - tells * to match the minimum number of times. You might not need this!
|  - 'or' operator&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This allows you to find all instances of a particular HTML tag, regardless of the attributes assigned to it. This is really helpful for finding and replacing in your IDE, and can be adapted to fit your specific needs.&lt;/p&gt;

&lt;p&gt;You could include another capture group to match the entire element instead of just the tags:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;'&amp;lt;div class="something"&amp;gt;Some content&amp;lt;/div&amp;gt;'.match(/&amp;lt;div(.*?)&amp;gt;(.*?)&amp;lt;\/div&amp;gt;/gi) // matches&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From here, you can go further and find all tags containing a certain class or attribute, capture the innerHtml of all tags with a certain class, find and replace all instances of a particular class to change it from a link to a button, you get the idea... You can do a lot with regex.&lt;/p&gt;

&lt;p&gt;I recommend MDN's (javascript) &lt;a rel="noreferrer noopener" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet"&gt;cheat sheet&lt;/a&gt; and regex101's &lt;a rel="noreferrer noopener" href="https://regex101.com/"&gt;Regex Tester&lt;/a&gt; to get you started.&lt;/p&gt;

&lt;h2&gt;6. Don't get stuck in your ways&lt;/h2&gt;

&lt;p&gt;The most important thing to remember to stay competitive as a developer, is that the industry is constantly changing. There are new ideas and technologies appearing every day. Although you shouldn't be distracted by these new things, as they come just as often as they go, it's good to have some awareness of what your industry is using so you don't fall too far behind. &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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2F19fq7c002w021.png%3Fw%3D1017" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2F19fq7c002w021.png%3Fw%3D1017" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's also important to accept that even if you believe in a certain way of doing something, there might be something that comes along to solve your problem even more effectively. It's good to have opinions, but many developers fall into the trap of believing that &lt;em&gt;their&lt;/em&gt; way is the best way. &lt;/p&gt;

&lt;p&gt;Programming is far from cut-and-dry: Everything has it's upsides and downsides. Every project has it's own needs, and the same technology or approach isn't always best for all of them.&lt;/p&gt;

&lt;h2&gt;7. Be business-aware&lt;/h2&gt;

&lt;p&gt;We all love to code, but at the end of the day most of us do this to pay the bills. We're (aside from freelancers and hobbyists) employed by businesses with clients, deadlines and budgets, and our performance in delivering projects is what reflects us more than the quality of our code - although high-quality code will generally make delivery go much smoother. &lt;/p&gt;

&lt;p&gt;Becoming a mid-level or even senior developer is as much about what you know as it is about the responsibility you can take on and your commitment to delivering the best you reasonably can in the time you're given. If you create the best damn website the world has ever seen, but it's a month late, it won't reflect on you well. Sometimes you will need to find shortcuts or outright cut things out of a project: At the end of the day, your company only has a limited budget they can spend before they start to make a loss.&lt;/p&gt;

&lt;p&gt;Senior developers are paid what they're paid because they're reliable. Yes, they can solve problems faster and know a hell of a lot, but they will also do what it takes to deliver a project on time. They understand which technologies and approaches will fit the needs of a project without being overkill, taking too much time or requiring too much custom code.&lt;/p&gt;

&lt;p&gt;This isn't the most exciting or inspiring part of being a developer, but it's what the people who pay you will notice more than how efficient a function you wrote is.&lt;/p&gt;

&lt;h2&gt;8. Be patient, and practise often&lt;/h2&gt;

&lt;p&gt;I'm a big fan of the phrase, "you don't know what you don't know". Progamming is a long game: it takes years to become a truly competent developer, and the more you know the more you realise you &lt;em&gt;don't&lt;/em&gt; know very much at all. Have humility, and just keep on building things. Push yourself further each time, try new things and refine your techniques. Forget about the destination and focus on the journey.&lt;/p&gt;

&lt;p&gt;Eventually you will have some idea, or you'll start a project, and notice how much better you code is without even needing to think about it. You'll have the knowledge engrained into your head enough that problem solving becomes trivial, and you can use the freed-up brain power to tackle even greater problems. Be persistent but patient, and you will become a great developer right under your own nose.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to use Next.js + React Query for insane loads times with dynamic content</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Mon, 13 Sep 2021 07:02:57 +0000</pubDate>
      <link>https://dev.to/charliejoel/isr-react-query-insanely-fast-nearly-dynamic-sites-43im</link>
      <guid>https://dev.to/charliejoel/isr-react-query-insanely-fast-nearly-dynamic-sites-43im</guid>
      <description>&lt;p&gt;&lt;a href="https://www.infoq.com/news/2020/11/ux-stale-while-revalidate/" rel="noopener noreferrer"&gt;Stale-while-revalidate&lt;/a&gt; has some exciting implications for the future of web performance: by serving stale data instead of loading spinners, the user experience can be smoother and snappier. It also opens up the possibility for pages with dynamic content to be built to static files at intervals without the need to be server-side rendered on demand, meaning websites can utilise features of a dynamic website without sacrificing the speed of a static one.&lt;/p&gt;

&lt;p&gt;This is feasible thanks to a few new technologies which have been cropping up on the JS horizon: A new build option for Next.js, called &lt;a href="https://vercel.com/docs/next.js/incremental-static-regeneration" rel="noopener noreferrer"&gt;Incremental Static Regeneration,&lt;/a&gt; and a cache-revalidation package called &lt;a href="https://react-query.tanstack.com/" rel="noopener noreferrer"&gt;React Query&lt;/a&gt;. Alternatives have appeared, such as Vercel's own &lt;a href="https://swr.vercel.app/" rel="noopener noreferrer"&gt;SWR&lt;/a&gt; package, but all aim to reach the same goal: To handle query caching, error handling, polling and most importantly, to revalidate data when required. These two technologies work in perfect harmony to create super-fast, up-to-date static websites that will amaze clients and improve SEO. &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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2Fezgif.com-video-to-gif.gif%3Fw%3D600" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F09%2Fezgif.com-video-to-gif.gif%3Fw%3D600" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I'll be showing you how to get the best of both worlds by setting up ISR to do the main content fetching and React Query to 'fill in the gaps' and provide more recent data.&lt;/p&gt;

&lt;h2&gt;How it works&lt;/h2&gt;

&lt;p&gt;ISR works by building static 'snapshots' of a populated site: It will go through each page and make all the requests it needs to, finally building each page to a static HTML file. This isn't much different to a regular static site builder; what ISR does differently is it goes back and checks at regular intervals if the data it served has changed. If it has, ISR will rebuild &lt;em&gt;only the pages which have changed&lt;/em&gt;. If you have a site with 100 pages and only 5 pages were changed, it skips over the 95 that didn't change and only rebuilds the 5 that did. This saves a lot of processing power while also allowing for more 'dynamic' sites that still have the speed of static sites. It also means that both the developer and the client don't need to worry about rebuilding the site: Everything is handled automatically.&lt;/p&gt;

&lt;p&gt;There's a little more to it than that, but that's the general gist. &lt;a href="https://vercel.com/docs/next.js/incremental-static-regeneration" rel="noopener noreferrer"&gt;You can read more about the details of ISR here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;ISR can do the majority of the heavy lifting: For most posts and pages, content does not need to be up to date to the exact minute. Usually 30 seconds or a minute is enough, or even higher in some cases.&lt;/p&gt;

&lt;p&gt;Sometimes, however, you need the data you're displaying to be precise. Perhaps you're building an online shop with stock indicators that need to be exact, or you're building a recruitment website that always needs to display fresh jobs. That's where React Query comes in. Using a combination of ISR for menus and general page data alongside React Query for up-to-date listing information, you can build a frontend that is not only fast but also completely up to date.&lt;/p&gt;

&lt;h2&gt;0. Installation&lt;/h2&gt;

&lt;p&gt;Start by creating your Next.js project using &lt;code&gt;create-next-app&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;npx create-next-app my-project&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, let's add &lt;code&gt;react-query&lt;/code&gt; to the mix.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;npm i react-query&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will also want some kind of CMS which serves up a REST API - your data will be served as JSON objects. I'm using Wordpress' REST API feature for demonstration.&lt;/p&gt;

&lt;p&gt;Now we've got everything installed, it's time to get started.&lt;/p&gt;

&lt;h2&gt;1. Set up your Next.js page to use Incremental Static Regeneration&lt;/h2&gt;

&lt;p&gt;Set up your page in Next.js under the &lt;code&gt;pages&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;You can use this method for either non-dynamic routes for things like homepages and unique pages, or you can use dynamic routes which allow you to re-use the same template for different pages. I'm hard-coding my page ID here for the sake of the tutorial, but I intend on writing a guide for dynamic routes in Next.js in future.&lt;/p&gt;

&lt;p&gt;You can style up the page now if you want, or wait until you have your data to worry about displaying it on the page.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// pages/index.js

export default function Home(props) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;My App&amp;lt;/title&amp;gt;
        &amp;lt;link rel="icon" href="/favicon.ico" /&amp;gt;
      &amp;lt;/Head&amp;gt;

      &amp;lt;main&amp;gt;
        &amp;lt;-- your page content --&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export const getStaticProps = async () =&amp;gt; {...}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The area you need to pay attention to when setting up ISR is the &lt;code&gt;getStaticProps&lt;/code&gt; function below the main body. This function is run on the server side during its rendering process, and can be used to prefetch any queries required for that page. In the example below, we use this function to prefetch page data:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// pages/index.js

export const getStaticProps = async ({ params }) =&amp;gt; {
  const pageId = 1; // pageId could be dynamic

  // fetch page data using id
  const pageData = await getPageById(pageId);

  return {
    props: {
      pageData
    }
  };
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The request function, &lt;code&gt;getPageById&lt;/code&gt;, can be anything you like so long as it returns the data you're trying to fetch. I used Axios:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// util/queries/pages.js

export const getPageById = async (id) =&amp;gt; {
  const res = await axios
    .get("http://localhost/wp-json/wp/v2/pages/" + id)
    .catch((err) =&amp;gt; err);

  return res;
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Setting up Incremental Static Regeneration from here is simple: All you need to do is add a &lt;code&gt;revalidate&lt;/code&gt; property to the return object. This value is the number of seconds before Next.js will wait before attempting to revalidate and rebuild the page, once a user requests it again.&lt;/p&gt;

&lt;p&gt;If someone visits the page before that number of seconds is up, they will be served the old, cached version of the page. However if someone visits the page after that amount of time, they will be served the old version but a new version of the site will regenerate in the background and update the user when it's ready. That new version is then cached and the cycle repeats.&lt;/p&gt;

&lt;p&gt;I've used 60 seconds for the sake of testing, but the time period you use will depend on the app requirements. If it's just a blog, you can probably get away with a longer time period.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// pages/index.js - getStaticProps()

return {
  props: {
    pageData
  },
  revalidate: 60
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To test if ISR is working, you can put some dates on the page. One is returned from &lt;code&gt;getStaticProps&lt;/code&gt; at build time, and the other is returned when the page is loaded. I've used &lt;a href="https://momentjs.com/" rel="noopener noreferrer"&gt;moment&lt;/a&gt; to format the dates to time. Your page will look something like this:&lt;/p&gt;

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

export default function Home({ data, updatedAt }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;My App&amp;lt;/title&amp;gt;
        &amp;lt;link rel="icon" href="/favicon.ico" /&amp;gt;
      &amp;lt;/Head&amp;gt;

      &amp;lt;main className="p-12"&amp;gt;
        &amp;lt;p className="text-48"&amp;gt;
          Rendered: {moment(new Date(updatedAt)).format("h:mm:ssa")}
          &amp;lt;br /&amp;gt;
          Loaded: {moment(new Date(Date.now())).format("h:mm:ssa")}
        &amp;lt;/p&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export const getStaticProps = async ({ params }) =&amp;gt; {
  const pageId = 1;

  // fetch page data using id
  const pageData = await getPageById(pageId);

  return {
    props: {
      pageData,
      updatedAt: Date.now(),
    },
    revalidate: 60,
  };
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run &lt;code&gt;npm run build&lt;/code&gt; followed by &lt;code&gt;npm run start&lt;/code&gt; to see the result - ISR won't be enabled in dev mode. If the timestamps don't match up, ISR is enabled. You should be able to continually refresh the page for the duration of the &lt;code&gt;revalidate&lt;/code&gt; timer before the 'rendered' timestamp updates.&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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Fscreenshot-from-2021-08-09-17-20-49-1.png%3Fw%3D598" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Fscreenshot-from-2021-08-09-17-20-49-1.png%3Fw%3D598" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;2. Add React Query context to _app.js&lt;/h2&gt;

&lt;p&gt;Now ISR is set up and we've tested it works, it's time to get React Query working. We'll need to create a QueryClient to handle our queries, then add some context to provide our app with a central point of control. The QueryClientProvider allows us to access the same QueryClient using Hooks.&lt;/p&gt;

&lt;p&gt;First we'll need to import some things from React Query:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// pages/_app.js

import { useRef } from "react";
import { QueryClient, QueryClientProvider } from "react-query";&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next we create a reference to attach to the QueryClientProvider and add logic to create a new QueryClient if one doesn't exist.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// pages/_app.js

const queryClientRef = useRef();
  if (!queryClientRef.current) {
    queryClientRef.current = new QueryClient();
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, we can add our QueryClientProvider and attach our QueryClient using the reference we just made.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// pages/_app.js

return (
    &amp;lt;QueryClientProvider client={queryClientRef.current}&amp;gt;
        &amp;lt;Component {...pageProps} /&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  );&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here's how the whole &lt;code&gt;_app.js&lt;/code&gt; should look:&lt;/p&gt;

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

import { useRef } from "react";
import { QueryClient, QueryClientProvider } from "react-query";

function MyApp({ Component, pageProps }) {
  const queryClientRef = useRef();
  if (!queryClientRef.current) {
    queryClientRef.current = new QueryClient();
  }

  return (
    &amp;lt;QueryClientProvider client={queryClientRef.current}&amp;gt;
      &amp;lt;Component {...pageProps} /&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  );
}

export default MyApp;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;3. Prefetch page queries&lt;/h2&gt;

&lt;p&gt;We've now got a QueryClient on the app, so let's give it some data to revalidate. This is the exact same process as you'd usually use to populate a page using &lt;code&gt;getStaticProps&lt;/code&gt; - essentially, return the data inside the &lt;code&gt;props&lt;/code&gt; object as usual. This data will be revalidated according to the &lt;code&gt;revalidate&lt;/code&gt; timer we set before.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// pages/index.js

export const getStaticProps = async ({ params }) =&amp;gt; {
  const pageId = 1; // pageId could be dynamic

  // fetch page data using id
  const pageData = await getPageById(pageId);

  return {
    props: {
      pageData, // this could be data from any kind of request
      pageId
    },
    revalidate: 60 * 5, // 5 minutes
  };
};&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;4. Set up client-side queries&lt;/h2&gt;

&lt;p&gt;This is where React Query comes in: if ISR will revalidate our page every 5 minutes, React Query is going to revalidate it immediately upon page load to make sure everything is 100% up-to-date.&lt;/p&gt;

&lt;p&gt;We'll use the useQuery hook, set an ID for the request in the first parameter, then an arrow function that returns our request function, and for the third parameter we'll tell it the data it's going to be revalidating. This means that the &lt;code&gt;data&lt;/code&gt; const we created will initially be set to the data provided in getStaticProps, but when it's revalidated this value will be automatically updated to the new result.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export default function Home({ pageData, pageId }) {
  const { isLoading, isError, data } = useQuery(
    ["page-data"],
    () =&amp;gt; getPageById(pageId),
    {
      initialData: pageData
    }
  );

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;main className="p-12"&amp;gt;
        &amp;lt;h1 className="text-48"&amp;gt;{data?.title}&amp;lt;/h1&amp;gt;
        &amp;lt;p className="text-24"&amp;gt;{data?.body}&amp;lt;/p&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;5. Enjoy insane performance&lt;/h2&gt;

&lt;p&gt;That's it! You can do &lt;code&gt;npm run start&lt;/code&gt; and see your site working.&lt;/p&gt;

&lt;p&gt;To improve user experience, it's worth thinking about how you want to use each technology. After all, using React Query for all data is usually overkill.&lt;/p&gt;

&lt;p&gt;For page data that might not change often, perhaps just a few times per day or less, then ISR is probably enough. I tend to use ISR mainly for content coming from a CMS - it doesn't need to be live to the minute, it just needs to appear sometime soon after the client changes content.&lt;/p&gt;

&lt;p&gt;For data that is constantly updating - news feeds, weather results, any dynamic content - React Query is going to make sure that your page is always updated for every user, regardless of what time they access the site. You could even go a step further and take advantage of HttpOnly cookies with JWT authentication and use React Query for personalised user data, loading into a static 'frame' that is populated on load.&lt;/p&gt;

&lt;p&gt;I'm sure I've only scratched the surface of these technologies: There are so many potential applications for this and so much performance to be squeezed out. I hope to see more developers and organisations adopting stale-while-revalidate approaches in future.&lt;/p&gt;

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

export const getPageById = async (id) =&amp;gt; {
  const res = await axios
    .get(
      "https://jsonplaceholder.typicode.com/posts/" +
        (Math.floor(Math.random() * 100) + 1)
    )
    .catch((err) =&amp;gt; err);

  return res.data;
};&lt;/code&gt;&lt;/pre&gt;





</description>
    </item>
    <item>
      <title>How to keep Tailwind DRY</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Fri, 06 Aug 2021 09:24:28 +0000</pubDate>
      <link>https://dev.to/charliejoel/how-to-keep-tailwind-dry-2jfe</link>
      <guid>https://dev.to/charliejoel/how-to-keep-tailwind-dry-2jfe</guid>
      <description>&lt;p&gt;There's many complaints I see online about Tailwind: it's WET, not DRY, it's the same as inline styles, you can't make global changes, and it's hard to read. I understand how this may seem to be the case when you first start working with Tailwind. The thing to bear in mind is &lt;strong&gt;Tailwind is nothing like traditional CSS, and you shouldn't treat it as such&lt;/strong&gt;.



&lt;/p&gt;
&lt;p&gt;There's lots of ways that Tailwind can benefit us, such as its tiny bundle size and super-fast prototyping capabilities. I explained a bit more about that in a &lt;a href="https://npmrundev.wordpress.com/2021/08/04/6-reasons-to-use-tailwind-over-traditional-css/" rel="noopener noreferrer"&gt;previous article&lt;/a&gt;. But we can only get these benefits if we use it in the right situation; used in the wrong context, Tailwind will only bring you headaches.&lt;/p&gt;

&lt;h2&gt;When is the wrong time to use Tailwind CSS?&lt;/h2&gt;

&lt;p&gt;The first thing I would recommend &lt;strong&gt;against&lt;/strong&gt; using Tailwind for is plain HTML static websites. When you're building a static site, you will inevitably end up copy and pasting HTML, since there's likely to be more than one occurrence of the same component/section on a single page. &lt;/p&gt;

&lt;p&gt;This is totally fine if you're using a traditional CSS methodology such as &lt;a href="http://getbem.com/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt;: your CSS and HTML exist completely separately, so you can rely on your CSS as your single source of truth for how your website will look. If you change a CSS class, the change will be reflected everywhere the class is used without having to update the HTML. In this way, it doesn't really matter &lt;em&gt;too much&lt;/em&gt; if you've copy and pasted some HTML.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// you can copy and paste these classes anywhere
&amp;lt;button class="button button--negative"&amp;gt;&amp;lt;/button&amp;gt;

&amp;lt;button class="button button--negative"&amp;gt;&amp;lt;/button&amp;gt;

// but you could also break rules like this
&amp;lt;div class="button"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Fhtml-files-suck.png%3Fw%3D263" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Fhtml-files-suck.png%3Fw%3D263" alt=""&gt;&lt;/a&gt;Separation of concerns is traditionally defined by language&lt;/p&gt;

&lt;p&gt;This is about as much as you can do when it comes to &lt;strong&gt;separation of concerns&lt;/strong&gt; with CSS and plain HTML. Personally, I still think this method isn't properly DRY since you're copy and pasting the same code in multiple places, but it's about the best you can do with basic HTML- something that never sat right with me while I was learning CSS. To make this system truly DRY, you would want to use some form of templating or a component-based framework so you could only write HTML for a section one time, and then re-use the component wherever you like. This brings me onto...&lt;/p&gt;

&lt;h2&gt;When is the right time to use Tailwind CSS? &lt;/h2&gt;

&lt;p&gt;I'm glad you asked! If you don't want to repeat yourself when building websites with Tailwind, you're probably going to want to use some kind of JavaScript framework. Whether it's React, Vue or some other new-fangled framework, the important thing is that you can build JS components which can be reused over and over. You might be able to get it to work with PHP templates, but I'd say this method is best for JavaScript since you can keep your HTML, JS and CSS all in the same file.&lt;/p&gt;

&lt;p&gt;That's the real way Tailwind should be used: as an entirely different paradigm where separation of concerns doesn't mean separating HTML, CSS and JS, it means separating entire components instead, and keeping everything related to that component inside one file or folder. It's a pretty different way of working to how we're used to with its own challenges, but this method has some great benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Components can behave independently of each other and be used across different projects without much hassle&lt;/li&gt;
&lt;li&gt;Components can be tested on their own so you don't need to worry about things changing later on&lt;/li&gt;
&lt;li&gt;Prototyping is much faster since you don't need to write a custom class for every single element&lt;/li&gt;
&lt;li&gt;Full access to use JavaScript for more advanced conditional styling than with regular HTML&lt;/li&gt;
&lt;li&gt;Encourages component composition - once you have a bunch of components, it's easy to build pages or even new variants of components by combining what you already have&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Embracing component-based architecture&lt;/h2&gt;

&lt;p&gt;Once you have your HTML, JavaScript and CSS all in one place, you'll realise it's much easier to contain components within their own folders rather than having resources stretched across your whole project in different file trees. Working in this way opens up new opportunities, such as being able to use JavaScript to dictate your styles and building more complex logic for views.&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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Ffilez-1.png%3Fw%3D275" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Ffilez-1.png%3Fw%3D275" alt=""&gt;&lt;/a&gt;File structure in component-based development&lt;/p&gt;

&lt;p&gt;Here's some tips to help you adjust to component-based development:&lt;/p&gt;

&lt;h2&gt;1. Break components down into small, reusable pieces&lt;/h2&gt;

&lt;p&gt;Have you ever noticed, when looking at a design, that there tend to be lots of repeating patterns? You can take advantage of this with class composition. It's common to see a 50/50 layout with text on one side, and some type of media on the other. I tend to call them &lt;code&gt;SplitContent&lt;/code&gt; blocks. There are often variants on this, perhaps some of the text is a different size or the media slot is filled with a carousel instead of an image.&lt;/p&gt;

&lt;p&gt;Instead of building two components that use the exact same styles for the most part, you could create a container component with props, slots where you can add any kind of content. You could set up logic for your styles inside - maybe you want a prop that changes which side the content will appear on, or add padding to a certain side. Alternatively, you could just add a prop which can be passed a string of class names, giving you the ability to customise the container as it's used in different contexts.&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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Fbreaking-down-components-01.png%3Fw%3D1024" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Fbreaking-down-components-01.png%3Fw%3D1024" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For areas where I want to use SplitContent as a dynamic content block with a CMS such as Wordpress, I might create a &lt;code&gt;Handler&lt;/code&gt; component which breaks down the style options defined in the CMS and passes on the relevant combinations of components.&lt;/p&gt;

&lt;p&gt;You might, for example, want your client to only have access to one SplitContent component in the CMS, but have the choice to create many different layouts using that one component. Some of the choices might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which type of content do you want on each side?&lt;/li&gt;
&lt;li&gt;Which side should each content type be on?&lt;/li&gt;
&lt;li&gt;Does this component need a different colour scheme?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These options can be taken in by the component Handler and it will return the correct layout, while keeping all this logic contained within itself so the other components can still be used across different components.&lt;/p&gt;

&lt;p&gt;I usually keep everything related to SplitContent under one folder, and add a subfolder of smaller pieces which make up the main components:&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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Ffilez-2-1.png%3Fw%3D264" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Ffilez-2-1.png%3Fw%3D264" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just one example; essentially, your components should all have a single purpose so it's easier to build larger and more complex components using the pieces you have created.&lt;/p&gt;

&lt;h2&gt;2. Use JS to build class lists&lt;/h2&gt;

&lt;p&gt;If you find Tailwind hard to read, you're not alone. It's one of the most common complaints and I can understand why: you have to read each class to understand what's going on, which doesn't work for everyone.&lt;/p&gt;

&lt;p&gt;It may help to rely on JavaScript to build your class names. I often prefer this method over composing new CSS classes for the sake of it, especially when they might only be used in one place. Some people might say this is the same as using the &lt;a class="mentioned-user" href="https://dev.to/apply"&gt;@apply&lt;/a&gt; directive, but if the class isn't going to be used anywhere else there's no reason to write a whole new class for it. Writing classes with JavaScript like this helps to keep everything related to that component in a similar place, rather than placing it miles away in the CSS folder.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// components/Modal/View.jsx

export default function ModalView () {
  const modalContainerClass = "bg-white p-4 rounded shadow";
  const modalHeadingClass = "heading-1 text-darkgrey";

  return (
    &amp;lt;aside className={modalContainerClass}&amp;gt;
      &amp;lt;h1 className={modalHeadingClass}&amp;gt;...&amp;lt;/h1&amp;gt;
    &amp;lt;/aside&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Storing classes in JavaScript variables makes it a little clearer what is trying to be accomplished with it, while also opening up the opportunity to use more advanced logic than would be possible with CSS.&lt;/p&gt;

&lt;h2&gt;3. Use props to extend components&lt;/h2&gt;

&lt;p&gt;One of the problems we encounter with Tailwind compared to normal CSS is that we lose the ability to extend a basic version of a component into a new modified version with classes:&lt;/p&gt;

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

.button {
  padding: 20px;
  border: 1px solid black;
}
.button--negative {
  border-colour: red;
}

// index.html

&amp;lt;button class="button"&amp;gt;Accept&amp;lt;/button&amp;gt;
&amp;lt;button class="button button--negative"&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course we could manually add the &lt;code&gt;border-red&lt;/code&gt; Tailwind class to any button we want to make negative, but what if there's more than one style? What if the background and text colour also change?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// this would be a nightmare if the negative styles ever changed

&amp;lt;button class="p-5 border-red bg-red text-white"&amp;gt;Cancel&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;The solution: Extend your components using JavaScript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we make the switch over to component-based development, we gain the ability to use JavaScript in place of CSS for creating components. Since you're no longer tied to a separate stylesheet, you can create variants of your components by abstracting them to different files, using your base component as the starting point.&lt;/p&gt;

&lt;p&gt;One of the most flexible ways of doing this is to pass class names down as props, and merge them with the existing classes on a component. This is an example of &lt;a href="https://reactpatterns.com/#merge-destructured-props-with-other-values" rel="noopener noreferrer"&gt;merging destructured props with other values&lt;/a&gt;, as shown on the fantastic resource &lt;a href="https://reactpatterns.com/" rel="noopener noreferrer"&gt;reactpatterns.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's how our button variants might look using this method:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// components/Button/index.jsx

export default function Button = ({ classnames, handleOnClick, label }) {
  const buttonClass = [
    "p-5 border-1", // default button styles
    classnames      // any additional styles
  ].join(' ');
  
  return (
    &amp;lt;button className={buttonClass} onClick={handleOnClick}&amp;gt;
      {label}
    &amp;lt;/button&amp;gt;
  )
}

// components/Button/Negative.jsx

export default function ButtonNegative = (props) {
  return (
    &amp;lt;Button
      classnames="border-red bg-red text-white"
      {...props}
    /&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we can use &lt;code&gt;index.jsx&lt;/code&gt; as the base layer of our button, and keep all the logic on that level, while also having variants of that button clearly defined without any change to functionality. This way, if the styles change later on, anywhere &lt;code&gt;&amp;lt;ButtonNegative /&amp;gt;&lt;/code&gt; is used will reflect changes made in that file.&lt;/p&gt;

&lt;h2&gt;4. Move view logic and business logic to separate files&lt;/h2&gt;

&lt;p&gt;This is quite a general tip for working with JavaScript frameworks, but in Tailwind it can help even more so because it separates your styles from your business logic without relegating them to a completely different folder. You can enter your Button folder, and know that everything in that folder will be related to buttons.&lt;/p&gt;

&lt;p&gt;Once you've got everything in one place, you can start to break it down further: In React, you can keep the way your component looks separate from how it behaves. Here's an example of this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// components/Carousel/View.jsx (view logic only)
export default function CarouselView ({ slides }) {
  return (
    &amp;lt;SomeCarouselPlugin&amp;gt;
      {Array.isArray(slides) &amp;amp;&amp;amp; slides.map(slide =&amp;gt; (
        &amp;lt;CarouselSlide {...slide} /&amp;gt;
      ))}
    &amp;lt;/SomeCarouselPlugin&amp;gt;
  )
}

// components/Carousel/Jobs.jsx (business logic only)
export default function JobsCarousel () {
  const [jobs, setJobs] = useState(null);
  
  const fetchJobs = async () =&amp;gt; {
    const res = await request({
      url: 'my-api-url.com/jobs?limit=16',
      method: 'GET'
    })
    setJobs(res.data)
  }
  
  useEffect(() =&amp;gt; {
    fetchJobs();
  }, [])
  
  return !!jobs ? (
    &amp;lt;CarouselView slides={jobs.map(job =&amp;gt; ({
      title: job.title,
      description: job.description,
      salary: 'Up to ' + job.salary.max
    }))} /&amp;gt;
  ) : &amp;lt;&amp;gt;Loading...&amp;lt;/&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we wanted to make another carousel which used the same styles, perhaps we want the carousel to be filled with staff members instead of jobs, we could do that by creating a new container component in &lt;code&gt;Carousel/Staff.jsx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This massively helps with breaking down huge components with hundreds or even thousands of lines, and this method means you could also include extra layers if you wanted to for even more customisation. This system of extension makes it easier to break down what a component is supposed to be doing, while making sure you don't repeat yourself.&lt;/p&gt;

&lt;h2&gt;5. Use class composition for containers, text styles and anything used between components&lt;/h2&gt;

&lt;p&gt;That's right: Even when components are your source of truth, there is still a place for custom classes. For example, you are likely to use a container class on many different components with a max width, margin: auto and some side padding. Since these aren't likely to change, it makes sense to compose a new custom class using the &lt;a class="mentioned-user" href="https://dev.to/apply"&gt;@apply&lt;/a&gt; directive. &lt;/p&gt;

&lt;p&gt;Personally, I also like to include typographic classes such as for headings, standard blocks of content and the like. These are things that don't necessarily make a lot of sense to create a new JavaScript component for, but they combine the same styles in multiple places nevertheless.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.page-wrap {
  @apply max-w-page mx-auto px-4 tablet:px-5 laptop:px-6;
}

.paragraph {
  @apply text-16 font-body leading-loose;
}

// we can still create variants of .paragraph
&amp;lt;p class="paragraph text-white"&amp;gt;Hello world!&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;6. When composing classes, avoid using margins&lt;/h2&gt;

&lt;p&gt;You can make classes more reusable by making them position agnostic. If you leave out properties such as margins which only affect the position of the element, you are able to reuse it more often.&lt;/p&gt;

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

.heading-2 {
  @apply text-black text-24 bold;
}&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;h2 className="heading-2 mb-4"&amp;gt;Hello world!&amp;lt;/h2&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This might not be what you want in every situation - maybe you &lt;em&gt;do&lt;/em&gt; want every heading to have a certain margin. But for many cases it's a trick worth keeping in mind that makes your components much more flexible and less dependent on their position on the page.&lt;/p&gt;

&lt;h2&gt;7. Treat tailwind.config.js as your source of truth&lt;/h2&gt;

&lt;p&gt;In SCSS or LESS, you might create variables for constants such as colours, fonts and max widths. You can reuse those variables anywhere in your CSS, and if you change the variable this change will be reflected everywhere it's used.&lt;/p&gt;

&lt;p&gt;Tailwind works in much the same way, except &lt;em&gt;everything&lt;/em&gt; is defined by variables. That means not just the text or background colours you can use, but also spacing, sizing, borders and almost any other property you can think of. You can make use of this with the &lt;code&gt;theme&lt;/code&gt; object in &lt;code&gt;tailwind.config.js&lt;/code&gt;, or extend the default theme with the &lt;code&gt;extend&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;This file defined the way your whole app will look: If your designer has used a design system which commonly uses numbers like &lt;code&gt;4, 8, 12, 16, 32&lt;/code&gt; etc. you can build that system right into your CSS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;spacing: {
  1: '4px',
  2: '8px',
  3: '12px',
  4: '16px',
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These classes are then ready to use, straight away, and in the case of the &lt;code&gt;spacing&lt;/code&gt; property will be applied to &lt;code&gt;padding&lt;/code&gt;, &lt;code&gt;margin&lt;/code&gt; and &lt;code&gt;relative&lt;/code&gt; positioning classes such as &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Don't forget that you can also use regular JavaScript to generate some of these properties, which can save a bit of time and clean the file up. I like to make a &lt;code&gt;const&lt;/code&gt; containing an array similar to the one above, and using it for &lt;code&gt;spacing&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt; and any other similar properties - even &lt;code&gt;font size&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I've also entertained the idea of such a spacing/font system generated using the &lt;a href="https://grtcalculator.com/" rel="noopener noreferrer"&gt;golden ratio&lt;/a&gt;, which might be a great option for fast prototyping while also maintaining a great visual flow.&lt;/p&gt;

&lt;h2&gt;8. Use tools to spot repeating patterns&lt;/h2&gt;

&lt;p&gt;On the topic of composing classes, there are some great tools to help you find repeating patterns in your class lists so you can refactor these into their own generic classes.&lt;/p&gt;

&lt;p&gt;One of the most useful is Refactor CSS, a VS Code extension that automatically finds and presents very similar strings of classes, which helps when finding common patterns to abstract into new classes. Class strings will be highlighted if they have more than 3 classes and these 3 classes repeat more than 3 times in the current document. The order of classes is ignored, so you don't need to worry about maintaining a &lt;a href="https://www.matuzo.at/blog/ordering-css-properties/" rel="noopener noreferrer"&gt;property sort order&lt;/a&gt; to make sure the tool works.&lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;are&lt;/em&gt; worried about property sort order (Tailwind is much more readable if you are) then you can use another tool to deal with that for you: &lt;a href="https://github.com/heybourn/headwind" rel="noopener noreferrer"&gt;Headwind&lt;/a&gt;. This VS Code extension will format your Tailwind classes on save and group them by their function, making sure everything is where you expect it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// before saving
&amp;lt;div class="bg-red container mb-6 text-white"&amp;gt;&amp;lt;/div&amp;gt;

// after saving
&amp;lt;div class="container mb-6 text-white bg-red"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also change the regex of Headwind, so you can customise the sort order exactly how you like. &lt;/p&gt;

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

&lt;p&gt;I'll won't pretend moving to this way of working is particularly easy, and there are many problems that still need solving. We're still in the early (ish) days of utility-first frameworks and component-based development, so everything hasn't been figured out yet.&lt;/p&gt;

&lt;p&gt;Despite this, I feel confident that we'll start to see new tools, packages and methodologies that aim to tackle any issues we may face. What we can get out of this approach are lightweight, fast applications that are truly DRY. Isolated, independent components are great for building across different platforms, so I think we'll see a lot of companies building headless systems picking up this way of working.&lt;/p&gt;

&lt;p&gt;I write more articles like this one about headless systems and component-based development over on my blog at &lt;a href="https://npmrundev.wordpress.com/" rel="noopener noreferrer"&gt;npm run dev&lt;/a&gt;. Check it out if you want, and I'd love to get some feedback on my thoughts and writing style. Thanks for reading!&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>css</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>6 reasons to use Tailwind over traditional CSS</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Thu, 05 Aug 2021 08:46:50 +0000</pubDate>
      <link>https://dev.to/charliejoel/6-reasons-to-use-tailwind-over-traditional-css-1nc3</link>
      <guid>https://dev.to/charliejoel/6-reasons-to-use-tailwind-over-traditional-css-1nc3</guid>
      <description>&lt;h2&gt;1. Tiny bundle size = incredible performance&lt;/h2&gt;

&lt;p&gt;When in development mode, the size of Tailwind's output is pretty large. This is by design: Every possible class is generated at this stage so you don't need to wait for a build process to finish when you want to use something.&lt;/p&gt;

&lt;p&gt;Once Tailwind CSS is put into production mode, however, it will &lt;strong&gt;purge&lt;/strong&gt; any classes which aren't used with a tool called PurgeCSS. This works by searching through your project files for the names of the classes, keeping only those which are used. You can configure which file paths it will search through in your &lt;code&gt;tailwind.config.js&lt;/code&gt; in the &lt;code&gt;purge&lt;/code&gt; array.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// tailwind.config.js
module.exports = {
  purge: [
    './src/components/**/**/*.jsx',
    './src/layout/**/**/*.jsx',
    './src/pages/**/**/*.jsx',
  ],
  theme: {},
  variants: {},
  plugins: [],
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's quite easy to get a very small CSS bundle size without even trying, which really helps in getting your performance score up. You'd be pretty hard pressed to get a bundle size over 10kb, so websites that use Tailwind tend to load very quickly without needing much optimisation on the CSS front - so long as the rest of the site is also optimised.&lt;/p&gt;

&lt;p&gt;All you need to do is make sure you always reference classes by their full name, not by building names using JavaScript.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// bad
&amp;lt;div className={ 'bg-' + props.isDark ? 'neutral-dark' : 'neutral-light' }&amp;gt;

// good
&amp;lt;div className={ props.isDark ? 'bg-neutral-dark' : 'bg-neutral-light' }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also, while this would go mostly unnoticed on faster machines, the simplicity of Tailwind classes, in that they aren't built using &lt;a href="https://csswizardry.com/2011/09/writing-efficient-css-selectors/" rel="noopener noreferrer"&gt;complex selectors&lt;/a&gt;, means your browser is a little bit faster when parsing and rendering CSS. This helps with performance on slower computers and old phones. As someone whose phone was already slow when I bought it 6 years ago, I'll take any improvement I can get.&lt;/p&gt;

&lt;h2&gt;2. Prototype and build quickly&lt;/h2&gt;

&lt;p&gt;With regular SCSS, you need to write custom classes for every single element on your page. While it can offer finer control, writing custom classes takes a decent amount of time: You have to add the class in the HTML, then create it in the CSS, and then write out every property in long format. Then you have to wait for the CSS to build before you can see the result - plus, if you need to make more changes you'll need to rebuild every time, which can take valuable seconds and interrupt your flow.&lt;/p&gt;

&lt;p&gt;Tailwind CSS takes out those extra steps and gives you a simple, snappy developer experience when styling elements. You see the element you want to style, add the properties it needs using shorthand, and the changes appear very quickly without having to wait for a CSS bundle. Your attention can stay in one place so you aren't switching around to different files constantly, and the whole process just feels &lt;em&gt;simple&lt;/em&gt;.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;div class="bg-white rounded p-4"&amp;gt;
  &amp;lt;h1 class="text-24 font-heading underline"&amp;gt;
    Foobar
  &amp;lt;/h1&amp;gt;
  &amp;lt;p class="text-16 font-body&amp;gt;
    Hello world!
  &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;I can understand that it may take a while to learn all the shorthand. There's some good tools to help with this, chiefly the &lt;a href="https://tailwindcss.com/docs" rel="noopener noreferrer"&gt;official docs&lt;/a&gt; or &lt;a href="https://twitter.com/nerdcave" rel="noopener noreferrer"&gt;@nerdcave&lt;/a&gt;'s &lt;a href="https://nerdcave.com/tailwind-cheat-sheet" rel="noopener noreferrer"&gt;Tailwind cheat sheet&lt;/a&gt;. But to be honest, after spending a week or so using it you will have remembered most of the important stuff. There's a couple of weird gotchas, such as not having classes for &lt;code&gt;flex-basis&lt;/code&gt;, but there's always a good reason: In this case, you can just use the width attributes such as &lt;code&gt;w-1/2&lt;/code&gt; in its stead. It just takes a little bit of time, but has the potential to save a whole lot more.&lt;/p&gt;

&lt;p&gt;I've used Tailwind in some production sites that had very tight deadlines and I have to say, it definitely took a lot of pressure off when it came to styling up the frontend. If you're on a tight deadline, Tailwind could make life a little easier.&lt;/p&gt;

&lt;h2&gt;3. It handles CSS variables automatically&lt;/h2&gt;

&lt;p&gt;Tailwind generates a file called &lt;code&gt;tailwind.config.js&lt;/code&gt;. This file contains all your settings for your theme, including colours, widths, spacing (used for padding, margins and similar properties), fonts and so on. Your entire CSS bundle and all the classes you use will be based on this file.&lt;/p&gt;

&lt;p&gt;Each property can be assigned a name which will be how you can refer to the classes associated. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// tailwind.config.js

colors: {
  brand: {
    DEFAULT: '#f0000',   // bg-brand
    primary: '#f0000',   // bg-brand-primary
    secondary: '#f0000'  // bg-brand-secondary
}

// other ways to use these colours
.text-brand
.border-brand-secondary&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you can change all these properties any time you like, the names will stay the same unless you change them. So Tailwind will handle all of your CSS variables - it influences the entire look of your site. &lt;em&gt;This &lt;/em&gt;is your source of truth - if a brand colour changes, or you need to change the fonts everywhere, &lt;code&gt;tailwind.config.js&lt;/code&gt; is where you can do that.&lt;/p&gt;

&lt;h2&gt;4. Eliminates scope leak&lt;/h2&gt;

&lt;p&gt;One of the traits people love of BEM and why it's so popular today, is that the naming system classes are built to represent the structure of a component. While making it easy to read and understand, developers also benefit from a side effect of this structure: Since the layout is easy to understand, you can write classes without using CSS selectors.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// this
.block {
  &amp;amp;__element { ... }
  &amp;amp;__element--modifier { ... }
}

// not this
.block {
  &amp;amp; &amp;gt; .element {
    &amp;amp;.modifier { ... }
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem with CSS selectors is they introduce complexity into CSS where components become very dependent on a particular HTML structure. Since generic CSS classes such as &lt;code&gt;.container&lt;/code&gt; can repeat a lot, using these names can lead to overlap, where changing one class will affect many other classes. It's one of the main reasons we use BEM, because it makes this structure clear and flattens every class to the top-level scope so nothing depends on anything else. Working without a CSS methodology like this can lead to headaches, and keeping it as simple as possible means more people can understand it more easily.&lt;/p&gt;

&lt;p&gt;The way utility-first CSS works is by embracing this idea: Don't have anything depend on anything else. In Tailwind classes are single purpose, generally made up of only one or two CSS properties, and they never depend on each other except for intentional exceptions, such as the group hover feature. You really don't even need to think about scope leak, because unless you add those selectors yourself with custom CSS, the option to nest classes in complex selectors isn't really built in.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// this is all tailwind classes are
.w-1/2 {
  width: 50%;
}
.mx-auto {
  margin-left: auto;
  margin-right: auto;
}&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;// using hover groups
&amp;lt;div class="group bg-white hover:bg-black"&amp;gt;
  &amp;lt;h3 class="text-grey group-hover:text-black group-hover:underline"&amp;gt;Title&amp;lt;/h3&amp;gt;
  &amp;lt;p class="text-grey group-hover:text-black"
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What I really like about it is that there's no need for vague, overly specific or generally throwaway class names. You don't need to name every text style, every random CSS shape or flourish. Again, you're still free to comment the HTML if you need to, but sometimes there's no need to name every class that only has &lt;code&gt;display: flex&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if I still need to use selectors?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, there are times when selectors may be the best option, such as for styling WYSIWYG blocks, but generally avoiding selectors can help to maintain an easy to read and understand codebase. Remember you can still use SCSS alongside Tailwind if you prefer. If you do need to use selectors, prefixes can help to keep track of what's custom CSS and what's not. I like to use this method for WYSIWYGs:&lt;/p&gt;

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

.t-wysiwyg {
   &amp;amp; p {
     font-size: 12px;
   }
   &amp;amp; strong {
     @apply font-bold;
   }
}

.t-wysiwyg--contact { ... }&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;5. SCSS is still there if you need it&lt;/h2&gt;

&lt;p&gt;It's good to keep in mind that you don't need to use Tailwind CSS &lt;em&gt;instead of&lt;/em&gt; SCSS. There will still be times when you need to create an element that uses :&lt;code&gt;before&lt;/code&gt; and &lt;code&gt;:after&lt;/code&gt; elements, or when you need a custom keyframe animation. When this happens, you can just use SCSS or any other preprocesser in the exact same way you did before - no need to make a choice between the two.&lt;/p&gt;

&lt;p&gt; I prefer to use Tailwind for all the heavy lifting, and for elements that need CSS features I can switch over to SCSS. This allows me to work much faster while still achieving a high level of quality, customisation and detail.&lt;/p&gt;

&lt;p&gt;The simplicity of using shorthand classes over long, descriptive class names does feel freeing. There's no denying that BEM or a similar methodology's class names are helpful - you're informed on exactly what a class is meant to do. At least, that's the theory. The issue is that when &lt;em&gt;every&lt;/em&gt; element needs to have a unique class name, you end up with some vague, strange, or downright daft classes. It can be difficult to get used to not having classes described, but once you have a good understanding of the syntax it's just like reading regular CSS, and you can always comment your HTML with a description of what the class is.&lt;/p&gt;

&lt;p&gt;In my other post, &lt;a href="https://dev.to/npmrundev/how-to-keep-tailwind-dry-2jfe"&gt;How to keep Tailwind DRY&lt;/a&gt;, I explore how we can make use of JavaScript frameworks such as Vue or React to build truly DRY applications that mesh with the utility-first way of working.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;-- Contact Section - 2 column, 1 column on mobile --&amp;gt;
&amp;lt;div class="flex flex-row items-center"&amp;gt;
  &amp;lt;-- Map --&amp;gt;
  &amp;lt;div class="w-full tablet:w-1/2"&amp;gt;
    &amp;lt;img src="map.jpg" /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;-- Content --&amp;gt;
  &amp;lt;div class="w-full tablet:w-1/2"&amp;gt;
    &amp;lt;h3&amp;gt;&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;ul&amp;gt;&amp;lt;/ul&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;6. Works great with JavaScript frameworks&lt;/h2&gt;

&lt;p&gt;It should be known that Tailwind is not going to be DRY when used in an environment where you'll be copy and pasting HTML, so don't expect things to go well if you're working with plain HTML files. Once you start copy and pasting like this, you no longer have a central source of truth where you can change the way your components look, since the source of truth for your website styling is no longer tied to CSS files.&lt;/p&gt;

&lt;p&gt;Modern JavaScript frameworks are where Tailwind's features can really shine. This is because frameworks like Vue or React are based around creating reusable components, in order to minimise the amount of HTML that needs to be written. These components are the building blocks of your application, and can be a simple container or a large component composed of smaller components.&lt;/p&gt;

&lt;p&gt;These components are stored in their own custom files which combine HTML and JS, and in Vue you have the option to combine your CSS into a single file as well. This means your sources of truth no longer need to be separated by file type, they can all exist in the same file which handles a single component. This is what's known as component-based development, which JavaScript frameworks embrace with open arms: we've seen styled-components, CSS-in-JS, and now Tailwind, all of which help to contain all the CSS related to a component within that component. They can still be split out into different files, but if you want to make a change to that component you will be going straight to that component's folder instead of three separate locations.&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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Ffilez.png%3Fw%3D275" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F08%2Ffilez.png%3Fw%3D275" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've written about this concept more in my other post, &lt;a href="https://npmrundev.wordpress.com/2021/08/01/learning-to-love-tailwind/" rel="noopener noreferrer"&gt;How to love Tailwind&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;I'll be the first to admit that Tailwind CSS probably isn't the right choice in every situation. It has some really fantastic features, it's really speedy and it compiles down to ridiculous file sizes, but it requires a totally different mindset and set of tools to take advantage of these features without getting frustrated.&lt;/p&gt;

&lt;p&gt;I've noticed a lot of teams, particularly those building headless sites with frontend frameworks, are adopting Tailwind and solutions like it. I think we're still in the early days of this approach and there's a lot to figure out, but the potential is huge. I'm excited to see where it goes in future.&lt;/p&gt;

</description>
      <category>css</category>
      <category>tailwindcss</category>
      <category>react</category>
      <category>vue</category>
    </item>
    <item>
      <title>How to love Tailwind</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Tue, 03 Aug 2021 13:53:15 +0000</pubDate>
      <link>https://dev.to/charliejoel/learning-to-love-tailwind-320d</link>
      <guid>https://dev.to/charliejoel/learning-to-love-tailwind-320d</guid>
      <description>&lt;p&gt;In recent years there's been a rise in what some people call utility-first CSS frameworks: Taking an atomic approach to CSS by combining single-purpose classes straight onto your HTML. It's easy to see why this format has taken off: you can build layouts more quickly when you don't need to write custom CSS, and no need to rebuild the files every time you make a change. Utility-first frameworks can also be configured to follow a strict design system, which feels lovely when you're building a design that follows the same design systems - designers often use consistent measures of space and width, so it feels great for your CSS to be so in-line with their vision straight out of the box.&lt;/p&gt;

&lt;p&gt;One popular framework has been rising to dominance, with many agencies and software houses making use of the fast prototyping capabilities it has to offer. It's called Tailwind, and it looks like it could be a major player in the world of frontend development in the future. &lt;/p&gt;

&lt;h2&gt;So what's the problem?&lt;/h2&gt;

&lt;p&gt;Tailwind CSS tends to be a very divisive topic between developers: a bit like Marmite, you either love it or you hate it. And I think that's a crying shame, because most of the arguments against it could be addressed with a change in mindset. It's important to keep in mind that, as with anything in life, you should always pick the right tool for the job. I won't sit and pretend Tailwind solves everything: it's only useful in the right situation. &lt;/p&gt;

&lt;p&gt;The thing is, Tailwind and other utility-first frameworks aren't at all like traditional CSS. If you look at a methodology we're all pretty familiar with, such as BEM, there is a massive difference in the &lt;em&gt;source of truth&lt;/em&gt; of styles.&lt;/p&gt;

&lt;h2&gt;A new source of truth&lt;/h2&gt;

&lt;p&gt;With a methodology like BEM, there's a focus on maintaining a separation of concerns between your HTML, CSS and JavaScript. The CSS is generally considered to be the source of truth when it comes to styling, whereas HTML should only concern content. This works really well for monolithic sites such as Wordpress or static HTML sites, where you would be writing HTML that may repeat itself. For example, here's a simple &lt;a href="http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code/"&gt;media object&lt;/a&gt; structure:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class="media-object"&amp;gt;
  &amp;lt;div class="media-object__media"&amp;gt;
    &amp;lt;img src="avatar.jpg" /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class="media-object__content"&amp;gt;
    Hello world! Here's some content.
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;$module: 'media-object';

.#{$module} {
  display: flex;
  flex-direction: row;
  
  &amp;amp;__media {
    flex-basis: 48px;
  }
  
  &amp;amp;__content {
    flex: 1 0 auto;
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The HTML for this object can be copy &amp;amp; pasted ad infinium, as would be the case if you were building a basic HTML page. Since the CSS is stored away in its source of truth, it doesn't matter too much if we repeat the HTML so long as the structure remains the same. It's not perfect and doesn't always feel right to copy and paste in this way, but by working in this way we can keep the styling pretty consistent even if it changes later down the line. If we change &lt;code&gt;.media-object&lt;/code&gt; later on by adding padding, the change will be reflected wherever the class is used. This is where the confusion starts when moving over to Tailwind.&lt;/p&gt;

&lt;p&gt;The problem is that many developers will move over to Tailwind and use it in exactly the same way as they used BEM: By copy-pasting HTML structures wherever required. Since Tailwind uses class composition to create styles, your source of truth no longer lies in the CSS files. The HTML itself becomes the source of truth for the way it looks. Here's the same component built using Tailwind's utility classes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class="flex flex-row"&amp;gt;
  &amp;lt;div class="w-7"&amp;gt;
    &amp;lt;img src="avatar.jpg" /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class="flex-grow w-auto"&amp;gt;
    Hello world! Here's some content.
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Imagine we have this media object copy-pasted all over a website; If we want to add padding to the top element, we would have to go through the whole site and manually add the padding class to each instance. Sure, you could use a find-and-replace tool to help, but this technique could lead to mistakes if you're not careful, and will become difficult to manage as the site grows.&lt;/p&gt;

&lt;p&gt;This is why &lt;strong&gt;I wouldn't recommend Tailwind if you're not using component-based framework.&lt;/strong&gt; This is why so many people grow to hate Tailwind: because they're using the wrong tool for the job, and it's working against them. It's just not designed to be used in the traditional sense.&lt;/p&gt;

&lt;h2&gt;Component-based architecture&lt;/h2&gt;

&lt;p&gt;The place where Tailwind really shines is in modern frameworks: Be it JavaScript frameworks such as React and Vue, or template systems like Twig, this approach to CSS thrives when combined with a &lt;em&gt;component-based &lt;/em&gt;architecture.&lt;/p&gt;

&lt;p&gt;In such systems, the source of truth for the styles can be merged with the structure of the site. In these systems, developers are encouraged to build reusable, composable components. For example here's the same media object built using React:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// MediaObject.js
export default function MediaObject({ children, img}) {
  return (
    &amp;lt;div class="flex flex-row"&amp;gt;
      &amp;lt;div class="w-7"&amp;gt;
        &amp;lt;img src={ img } /&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="flex-grow w-auto"&amp;gt;
        { children }
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This file, &lt;code&gt;MediaObject.js&lt;/code&gt;, is now the absolute source of truth for the way the component looks and feels: There's no CSS file off in the distance being relied on, no HTML that needs to be copy-pasted a gazillion times. Everything's here in this one file.&lt;/p&gt;

&lt;p&gt;As you can see, this component doesn't care about the content it contains: both the media and the text content are props passed down when component is used anywhere. Here's an example of how &lt;code&gt;MediaObject&lt;/code&gt; would be called on a page:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;MediaObject media="avatar.jpg"&amp;gt;
  &amp;lt;h3&amp;gt;Person Personson&amp;lt;/h3&amp;gt;
  &amp;lt;p&amp;gt;Hello world!&amp;lt;/p&amp;gt;
&amp;lt;/MediaObject&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;"But what about modifiers?", I hear you ask. Well, component-based frameworks can handle that easily too, and do much cooler things while they're at it.&lt;/p&gt;

&lt;p&gt;For example, let's say we also have a dark variant of the media object with a dark grey background. Not only does the background colour need to change, but the colour of the text inside needs to change to contract with the darker background.&lt;/p&gt;

&lt;p&gt;`{% raw %} - please excuse these tags, I'm not used to dev.to and the page won't render without them. But if anyone knows how to hide them, please let me know!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// MediaObject.js
export default function MediaObject({ children, img, modifiers }) {
  const bgC = modifiers.isDarkBG ? 'bg-dark-grey' : 'bg-transparent';
  const textC = modifiers.isDarkBG ? 'text-white' : 'text-dark-grey';
  
  return (
    &amp;lt;div class={`flex flex-row ${ bgC }`}&amp;gt;
      &amp;lt;div class="w-7"&amp;gt;
        &amp;lt;img src={ img }
      &amp;lt;/div&amp;gt;
      &amp;lt;div class={`flex-grow w-auto ${ textC }`}&amp;gt;
        { children }
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;{% endraw %}`&lt;/p&gt;

&lt;p&gt;Now we can make use of ordinary JavaScript to control look at feel using a 'modifiers' object, which gives us far more powerful tools for building conditional styles. There's so many more ways to use this, and once you get used to working in this way it starts to feel really natural and intuitive. You can define conditions inside the component itself, or pass a string of class names directly through for extra control.&lt;/p&gt;

&lt;p&gt;It's recommended when building components to take advantage of abstraction: You can move different levels of logic into different files for the same component. The best example of this in React is &lt;a href="https://medium.com/@yassimortensen/container-vs-presentational-components-in-react-8eea956e1cea"&gt;container components vs presentational components.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Abstract business logic to keep it tidy&lt;/h2&gt;

&lt;p&gt;By wrapping the view of the component (the way it looks) inside a container where the business logic (the way it works) is stored, you can isolate different concerns into different files. I'll often use a folder structure where the folder name is the name of the component, and there are two files, &lt;code&gt;index.js&lt;/code&gt; and &lt;code&gt;View.js&lt;/code&gt;. &lt;code&gt;index.js&lt;/code&gt; is the container component, while &lt;code&gt;View.js&lt;/code&gt; is the presentational component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U9LWE-UT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://npmrundev.files.wordpress.com/2021/08/file-structure.png%3Fw%3D262" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U9LWE-UT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://npmrundev.files.wordpress.com/2021/08/file-structure.png%3Fw%3D262" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By keeping all my presentational logic inside &lt;code&gt;View.js&lt;/code&gt;, including any conditional styles based on the &lt;code&gt;modifier&lt;/code&gt; prop, I can make sure any logic that doesn't concern the way the component is styles is kept in the container component, &lt;code&gt;index.js&lt;/code&gt;. This really helps with tidiness and staying sane, as everything has a logical place to go.&lt;/p&gt;

&lt;p&gt;`{% raw %}&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// View.js
export default function MediaObjectView({ children, img, modifiers }) {
  const bgC = modifiers.isDarkBG ? 'bg-dark-grey' : 'bg-transparent';
  const textC = modifiers.isDarkBG ? 'text-white' : 'text-dark-grey';
  
  return (
    &amp;lt;div class={`flex flex-row ${ bgC }`}&amp;gt;
      &amp;lt;div class="w-7"&amp;gt;
        &amp;lt;img src={ img }
      &amp;lt;/div&amp;gt;
      &amp;lt;div class={`flex-grow w-auto ${ textC }`}&amp;gt;
        { children }
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;{% endraw %}`&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// index.js
export default function MediaObject({ children, img, modifiers }) {
  // any business logic can go here and be passed to MediaObjectView using props
  
  return &amp;lt;MediaObjectView {...children, img, modifiers} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In theory, you could keep on abstracting components as many times as you like. It's generally recommended to stick with a max of 2, but I'm sure there's some cases where separating logic even further would be beneficial.&lt;/p&gt;

&lt;h2&gt;Is Tailwind right for me?&lt;/h2&gt;

&lt;p&gt;Well, maybe. If you're building static HTML sites, probably not. If you're building Wordpress sites with PHP, you'd be best off using some kind of templating engine to maintain your source of truth. But if you're using a modern JavaScript framework like React or Vue, I highly recommend giving it a try: It's very different and comes with its own challenges, but can be a joy to use and extremely powerful if used in the right way. Just don't expect to be able to use the same concepts you learned with BEM - it's a completely different box of frogs.&lt;/p&gt;

&lt;p&gt;Learn more about Tailwind on the &lt;a href="https://tailwindcss.com/"&gt;official website&lt;/a&gt;, and &lt;a href="https://www.youtube.com/watch?v=J_7_mnFSLDg"&gt;watch this great presentation&lt;/a&gt; for more details on how to use Tailwind in place of traditional CSS.&lt;/p&gt;

</description>
      <category>css</category>
      <category>tailwindcss</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>React Query with Next.js ISR: Static websites with dynamic content</title>
      <dc:creator>Charlie Joel</dc:creator>
      <pubDate>Sun, 01 Aug 2021 23:00:55 +0000</pubDate>
      <link>https://dev.to/charliejoel/react-query-with-next-js-isr-static-websites-with-dynamic-content-5f8d</link>
      <guid>https://dev.to/charliejoel/react-query-with-next-js-isr-static-websites-with-dynamic-content-5f8d</guid>
      <description>&lt;h2&gt;What is stale-while-revalidate?&lt;/h2&gt;

&lt;p&gt;If there's any one technology I'll be keeping an eye on in the next few years, it's stale-while-revalidate: The ability to serve queries made in the past (stale) and then re-run those same queries once on the client side (revalidate). I (and many others) believe this new tech has the ability to revolutionise page speed forever. In the React space alone, there's already 2 serious contenders fulfilling similar roles: &lt;a href="https://github.com/tannerlinsley" rel="noopener noreferrer"&gt;@tannerlinsley&lt;/a&gt;'s &lt;a href="https://github.com/tannerlinsley/react-query" rel="noopener noreferrer"&gt;react-query&lt;/a&gt; and &lt;a href="https://github.com/vercel" rel="noopener noreferrer"&gt;@vercel&lt;/a&gt;'s own &lt;a href="https://github.com/vercel/swr" rel="noopener noreferrer"&gt;swr&lt;/a&gt; package, with similar packages for other JavaScript frameworks. They both popped up at a similar time, too, with react-query's first commit back in September 2019 and swr starting just weeks later in late October 2019. While there are some minor differences between the two, they are aiming to solve the same problems.&lt;/p&gt;

&lt;h2&gt;What does SWR do?&lt;/h2&gt;

&lt;p&gt;The concept of stale-while-revalidate mainly aims to solve problems surrounded queries and caching, which can traditionally be clunky or fragile systems to custom-build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fetching and caching data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React Query and SWR do all the heavy lifting when it comes to data fetching: All you need to do is provide a query string and some options on when to refresh the data, and these packages will do the rest for you. Stale-while-revalidate packages use key strings to refer to queries, which can then be cached, refreshed in the background, or serve stale data while the new data is being fetched. All this comes with pretty much no configuration, which can save a lot of time.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;const {
  isLoading,
  isError,
  data,
  error
} = useQuery('menus', fetchMenus) // 'menus' is the key&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thanks to the use of multiple keys on a single query, React Query and SWR can also handle pagination and any queries which use pointers straight out of the box, which can make paged requests much easier to deal with rather than creating custom code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// page can be incremented and the query will update automatically
useQuery(
  ['products', page],
  () =&amp;gt; fetchProducts(page)
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Refetch on focus&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most handy features of stale-while-revalidate is refetch on focus: exactly what it sounds like, React Query will retry any queries specified once the user refocuses a window. This means if they've been on other sites, or just taken a break from the computer, the data will be refreshed the moment they return to your site - meaning complete data synchronisation with pretty much no effort. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request failure/retry handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If anything goes wrong with your request when using React Query or SWR, there's no need to worry: Errors and response failures are automatically handled. When something goes wrong, the error will be handled in the background and the query will be polled until it can get an 'OK' response. Until then, the stale data will be served so there's no need for a backup - just make sure you have a loading indicator so your users know what's going on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prefetching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For sites which are rendered on the server side, React Query can be set up to prefetch your page data using the same key system used on the page. There's a few unique functions to use for this - In React Query you can prefetchQuery:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// The results of this query will be cached like a normal query
const prefetchMenus = async () =&amp;gt; {
   await queryClient.prefetchQuery('menus', fetchMenus)
 }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These queries made on the server side are then synchronised to the same queries which can be made on the page, so even if the data becomes stale it can be refreshed again on the client side.&lt;/p&gt;

&lt;h2&gt;Use cases for stale-while-revalidate&lt;/h2&gt;

&lt;p&gt;On its own, a package such as react-query or swr can offer some really handy use cases such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making sure a feed is up-to-date when the user refocuses the window&lt;/li&gt;
&lt;li&gt;Caching data fetched within a dialogue or modal, even if the modal is closed&lt;/li&gt;
&lt;li&gt;Lazy loading - perform queries as and when required, serving stale data or placeholders until the request is fulfilled&lt;/li&gt;
&lt;li&gt;Easily handle paginated sections or infinite scrolling&lt;/li&gt;
&lt;li&gt;Improving fetching efficiency - since data is cached and assigned to a key in the background, this data is ready to be accessed anywhere on your application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Static vs dynamic websites&lt;/h2&gt;

&lt;p&gt;Traditionally, there have been two ways to serve websites: The first is static, where a site is exported into a plain HTML document only once before being served to all users, meaning the site content will be frozen from the point in time it was built. This means static sites are super fast to download and show content. One of the main drawbacks to static websites, however, is that the content they serve is frozen at the time the site is built. This is less than ideal for web apps, as one of the key features of the web is being up to date. This is the problem that dynamic websites aim to solve.&lt;/p&gt;

&lt;p&gt;A dynamic website is one where a new version of each page is built for a particular user at the time they visit that page. This means the page content can be up-to-date and tailored to each user. This means data is completely up-to-date whenever a user visits the page. However, rendering the site on each request can be taxing for the server and increases loading times.&lt;/p&gt;

&lt;p&gt;There's also the case that clients have an easier time editing dynamic websites thanks to their use of a content management system, although there are actually many static websites which also use a content management system, but these are less common. The main issue with using static websites alongside content management systems is they need to be rebuilt whenever any content changes, which might require either the client to manually rebuild the site through the console every time they make a change (good luck), or for webhooks to be added to the build process to detect changes and rebuild accordingly. Thankfully, Next.js has offered up a better way: Incremental Static Regeneration.&lt;/p&gt;

&lt;h2&gt;Incremental Static Regeneration with Next.js&lt;/h2&gt;

&lt;p&gt;You may have heard about a new feature of Next.js' build process - the name is a bit of a mouthful: Incremental Static Regeneration. Not the easiest to remember, but its benefits could leave a lasting impact on web performance in the 2020s - with 100/100 lighthouse performance scores every time and insanely fast page speeds&lt;/p&gt;

&lt;p&gt;Here's how it works: Instead of exporting the website once and deploying that snapshot of the site, you provide a 'revalidate' timer in the getStaticProps function on your page. When you do 'npm run start' on your server, an image of the site will be exported at the current time. The interesting bit happens when the 'revalidate' timer you set up earlier runs out.&lt;/p&gt;

&lt;p&gt;Once the timer gets down to 0, the server waits until another user visits a page on the site before rebuilding that page. This is where that 'stale-while-revalidate' concept comes back again: The user that revisits the page will get the stale content, but as soon as they refresh the page or another user comes along, they will receive the new, up-to-date version. In this way, ISR provides a deployment option that is somewhere between static and dynamic. The site will have the performance benefit of a static website, but the content will be up to date for most of the users.&lt;/p&gt;

&lt;p&gt;This is also great for clients and webmasters: Instead of having to rebuild the whole site manually every time a change is made, you can just visit the page you edited and it will be rebuilt automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But wait.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This still means that for users visiting a page that hasn't been visited in a while, the content will still be out of date. What can we do about that?&lt;/p&gt;

&lt;h2&gt;Using React Query with Next.js ISR to build static sites with dynamic content&lt;/h2&gt;

&lt;p&gt;Here comes the real beauty of using Next.js' ISR alongside React Query or a similar package. By asking React Query to re-run the same queries that were made when generating the site, this gap in fresh data can be immediately filled once the page is load client-side.&lt;/p&gt;

&lt;p&gt;By setting up your queries to run once the page is loaded, and thanks to the keyed query caching system provided by React Query, this feature can be added in quite easily. It's also easy enough to refactor old Next.js projects to use this feature, so you can jump in and try it out with minimal effort.&lt;/p&gt;

&lt;p&gt;Here's the performance score for a recent site I made. The only effort I really put into performance was to compress images and use optimal file types: everything else was handled by Next.js.&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%2Fnpmrundev.files.wordpress.com%2F2021%2F07%2Flighthouse.jpg%3Fw%3D730" 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%2Fnpmrundev.files.wordpress.com%2F2021%2F07%2Flighthouse.jpg%3Fw%3D730" alt="Lighthouse performance score"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you might be able to tell, I am really excited for this technology and any future developments of this idea: Perhaps in the future, a framework such as Next.js could handle all of this automatically, making super-fast dynamic websites the industry standard. For now, I encourage everyone working with headless systems to give this a try - extra performance is a great selling point for agencies and freelancers.&lt;/p&gt;

&lt;p&gt;I'll be writing more about building headless systems on this blog in future, so keep an eye out if you're interested. Thanks for getting this far - if you disagree with anything I've said please let me know and I'll address it ASAP. Take care!&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>performance</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
