<?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: Nancy</title>
    <description>The latest articles on DEV Community by Nancy (@nhuynh1).</description>
    <link>https://dev.to/nhuynh1</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%2F366756%2Fb2c13696-7ad9-4f15-92bb-45df94741f6e.jpeg</url>
      <title>DEV Community: Nancy</title>
      <link>https://dev.to/nhuynh1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nhuynh1"/>
    <language>en</language>
    <item>
      <title>Refactoring code from a year ago helped me with my imposter syndrome</title>
      <dc:creator>Nancy</dc:creator>
      <pubDate>Fri, 23 Oct 2020 20:59:11 +0000</pubDate>
      <link>https://dev.to/nhuynh1/refactoring-code-from-a-year-ago-helped-me-with-my-imposter-syndrome-2ahp</link>
      <guid>https://dev.to/nhuynh1/refactoring-code-from-a-year-ago-helped-me-with-my-imposter-syndrome-2ahp</guid>
      <description>&lt;p&gt;As a self-taught front-end developer while also freelancing in technology research, learning to code has been a sloooow burn. Looking back on some code from a year ago, when I first started learning modern JavaScript, I can confidently say that a year ago my code was a cluster-f***. The process of refactoring the code a year later really highlighted how much I learned and help me deal with imposter syndrome&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;I had three key wins that helped me feel more confident:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I know more than I thought I did, like applying the MVC pattern to code and how to structure code clearly&lt;/li&gt;
&lt;li&gt;I can figure out my own solution by using tools I'm not familiar with like pug and Node by reading documentation and doing research&lt;/li&gt;
&lt;li&gt;I overcame my fear of Webpack&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;The project I'm refactoring is called Remixoji. Remixoji was a vanilla JavaScript webapp I was building to learn about modern JavaScript. With Remixoji, I ended up in a rabbit hole of learning how to manipulate Canvas and SVG elements and the DOM in general. Remixoji takes different aspects of emojis to create a new emoji&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzvp62v6tecnxs8hq6xhx.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzvp62v6tecnxs8hq6xhx.png" alt="Remixoji enables users to takes different aspects of emojis from Twitter's open source emojis to create new emojis."&gt;&lt;/a&gt;&lt;/p&gt;
Remixoji enables users to takes different aspects of emojis from Twitter's open source emojis to create new emojis



&lt;blockquote&gt;
&lt;p&gt;I knew then that the code was pretty poorly written, but I had not yet learn how to make it better, so it never went into production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Old code where basically everything ran from a single file: [&lt;a href="https://gist.github.com/nhuynh1/6cfddbbc8be6bc087c9cb46617ef67bc" rel="noopener noreferrer"&gt;Github Gist&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;New code with everything neatly structured: [&lt;a href="https://github.com/nhuynh1/remixoji" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Remixoji &lt;a href="https://remixoji.netlify.app/" rel="noopener noreferrer"&gt;[Live site]&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What I learned by refactoring Remixoji
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Using Class syntax with MVC pattern
&lt;/h2&gt;

&lt;p&gt;When refactoring the code I put relevant functions (including event handlers) and variables into logical classes using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes" rel="noopener noreferrer"&gt;ES6+ Class syntax&lt;/a&gt; with a simple MVC setup. This gave me the opportunity to better understand the MVC pattern and also to write Classes from scratch&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old index.html file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- DOM elements --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="cm"&gt;/* a whole bunch of functions not in any particular order */&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;New script.js file structure, split out from index.html&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmojiPart&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// This class ensures consistency of an EmojiPart object&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Remix&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Remix is the model which takes care of the data for the app&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="nf"&gt;addPart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="nf"&gt;removePart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;partType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="nf"&gt;removeAllParts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// The view takes care of displaying the app based on the data from the model&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="nf"&gt;displayRemix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="nf"&gt;updateSVGDownloadURL&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="c1"&gt;// more methods...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// App is the controller which tells the model to update in response to user input&lt;/span&gt;
    &lt;span class="c1"&gt;// App also providers a handler for Remix that tells View to update based on Remix data&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="nx"&gt;handleAddPart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;partID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;partType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="nx"&gt;handleUpdateVivew&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="c1"&gt;// more methods...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Win #1
&lt;/h3&gt;

&lt;p&gt;My original code had no real structure or pattern, but a year later I can apply MVC using Classes! 🙋🏻‍♀️&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Using build scripts and Pug to generate HTML
&lt;/h2&gt;

&lt;p&gt;My Remixoji scripts from one year ago inserted SVGs into the DOM on the client side. It would fetch a JSON file that listed all the SVGs that needed to be inserted and then get each SVG and insert it into the DOM. This approach was unnecessary since the SVGs I'm using do not change—they can be part of the static HTML&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzks4ppzpmk1s119aag58.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzks4ppzpmk1s119aag58.png" alt="Client-side only to insert SVGs"&gt;&lt;/a&gt;&lt;/p&gt;
Previously my code dynamically inserted SVGs on the client-side using JavaScript; there was no build process



&lt;p&gt;Using Pug I was able to build an html page with all the SVGs inserted. With the &lt;code&gt;pug&lt;/code&gt; package and a short script I got node to dynamically pass in the SVGs inline to the pug template via the list of SVG files listed in the original JSON file I had used before refactoring&lt;/p&gt;

&lt;p&gt;For each of the SVG files listed in the JSON, the script pulled in the file data, and pushed it to the  pug template so it can be inserted as inline SVGs. By building the HTML page with all the SVGs already in it I also cut out a lot of the client-side JavaScript that I was using for fetching and DOM manipulation&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsfbapshhz52bg4w91emm.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsfbapshhz52bg4w91emm.png" alt="Using a build process to insert SVGs"&gt;&lt;/a&gt;&lt;/p&gt;
When refactoring I dynamically inserted SVGs inline during the build process



&lt;h3&gt;
  
  
  Win #2
&lt;/h3&gt;

&lt;p&gt;I didn't know much about Pug and I didn't know how to use it in Node, nor would I consider myself a Node expert, but was able to read the documentation and do some googling to create a unique solution for this project. Win! 🙋🏻‍♀️&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Rolling my own webpack config
&lt;/h2&gt;

&lt;p&gt;I had read up a bit about webpack through React tutorials, but never wrote my own. Refactoring Remixoji is a great opportunity to write a basic &lt;a href="https://github.com/nhuynh1/remixoji/blob/main/webpack.config.js" rel="noopener noreferrer"&gt;&lt;code&gt;webpack.config.js&lt;/code&gt;&lt;/a&gt; file because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I needed to transpile my script.js file to ES5 using Babel so it would work for most users; not just people running the latest and greatest browser versions&lt;/li&gt;
&lt;li&gt;I wanted to minify my script.js and style.css files to improve performance for the user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I got the basics setup to compile my ES6 JavaScript to ES5 and to minify, but there's still more to learn in terms of fine tuning &lt;code&gt;webpack.config.js&lt;/code&gt; such as working with different types of sourcemaps&lt;/p&gt;

&lt;h3&gt;
  
  
  Win #3
&lt;/h3&gt;

&lt;p&gt;6 months ago I was so intimidated by Webpack that I metaphorically hid under the sheets. I went so far as to use Gulp instead, but during my refactoring of Remixoji I decided it was time to start reading their Getting Started and Documentation. While I can improve my Webpack setup, getting started is such a win! 🙋🏻‍♀️&lt;/p&gt;

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

&lt;p&gt;Refactoring Remixoji was a great learning experience, and it also meant I finally got to put some old code in production in an efficient, structured, and performant way. What was once an html file with a HUGE script section that did everything client-side became a project that builds a performant webapp without any frameworks that most users can use on their desktop and mobile devices&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>selftaught</category>
    </item>
    <item>
      <title>Five things I learned by building my own shopping cart and checkout with Gatsby and Stripe</title>
      <dc:creator>Nancy</dc:creator>
      <pubDate>Tue, 13 Oct 2020 19:48:20 +0000</pubDate>
      <link>https://dev.to/nhuynh1/five-things-i-learned-by-building-my-own-shopping-cart-and-checkout-with-gatsby-and-stripe-273k</link>
      <guid>https://dev.to/nhuynh1/five-things-i-learned-by-building-my-own-shopping-cart-and-checkout-with-gatsby-and-stripe-273k</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Don't build your own shopping cart and checkout experience unless it's a learning exercise or your client has a big budget&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you don't need a fully customized shopping cart and checkout experience then consider &lt;a href="https://snipcart.com/" rel="noopener noreferrer"&gt;Snipcart&lt;/a&gt; to save on dev time&lt;/li&gt;
&lt;li&gt;If you're using Gatsby or React and need a customized shopping cart consider using &lt;a href="https://useshoppingcart.com/" rel="noopener noreferrer"&gt;use-shopping-cart&lt;/a&gt; rather than building a React shopping cart from scratch&lt;/li&gt;
&lt;li&gt;If you need a fully customized checkout experience then you'll need to use Stripe's PaymentIntent API instead of Stripe's pre-built Checkout page. Budget more time for this&lt;/li&gt;
&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1aip3ljcfkeo20utp8oa.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1aip3ljcfkeo20utp8oa.png" alt="Shopping Cart Demo"&gt;&lt;/a&gt;&lt;br&gt;
Check out my &lt;a href="https://github.com/nhuynh1/muffinsplantshop" rel="noopener noreferrer"&gt;Muffin Plant Shop demo online store repo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Gatsby makes it easy to get something up fast
&lt;/h3&gt;

&lt;p&gt;For the small demo store I was working on, pulling product information from Markdown files was easy to setup by adapting &lt;a href="https://www.gatsbyjs.com/tutorial/" rel="noopener noreferrer"&gt;Gatsby's step-by-step tutorial&lt;/a&gt;.  Gatsby is built on React so there's lots of third-party components like &lt;a href="https://useshoppingcart.com/" rel="noopener noreferrer"&gt;use-shopping-cart&lt;/a&gt; instead of building things from scratch. Gatsby sites also shield you from CMS vulnerabilities (&lt;a href="https://wordpress.org/support/article/faq-my-site-was-hacked/" rel="noopener noreferrer"&gt;ahem Wordpress&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  2. No easy inventory solution with Stripe
&lt;/h3&gt;

&lt;p&gt;At some point I think Stripe offered inventory management, but that doesn't seem to be the case anymore since the &lt;a href="https://stripe.com/docs/orders" rel="noopener noreferrer"&gt;Orders API has been deprecated&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A custom checkout experience requires using Stripe's PaymentIntent API
&lt;/h3&gt;

&lt;p&gt;If you want to design your own checkout experience, then you'll have to use the PaymentIntent API and Stripe Elements. Stripe's &lt;a href="https://stripe.com/docs/payments/integration-builder" rel="noopener noreferrer"&gt;annotated code tutorial&lt;/a&gt; covers this pretty well, you'll just have to adapt the server side code if you're using a serverless functions. For more details check out my &lt;a href="https://nancyhuynh-til.netlify.app/stripe-react-notes/" rel="noopener noreferrer"&gt;notes and code for my Netlify Function&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Stripe's pre-built Checkout page is easy—but you still need a little bit of server code
&lt;/h3&gt;

&lt;p&gt;If you're ok with using Stripe's Checkout page (or convince your client to) then its super easy to offer card payments and digital wallets like Apple Pay. Stripe's &lt;a href="https://stripe.com/docs/payments/accept-a-payment" rel="noopener noreferrer"&gt;documentation for Checkout&lt;/a&gt; is nicely laid out, and Netlify also has a &lt;a href="https://www.netlify.com/blog/2020/04/13/learn-how-to-accept-money-on-jamstack-sites-in-38-minutes/" rel="noopener noreferrer"&gt;tutorial on setting up a Netlify Function for Stripe Checkout&lt;/a&gt;. Just remember that customers will get redirected to Stripe to checkout&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Freelancers and side-hustlers should seriously consider Snipcart
&lt;/h3&gt;

&lt;p&gt;If you're building an online shop for your side hustle or a small business client Snipcart &lt;em&gt;could&lt;/em&gt; be a better solution. Based on my research here are some pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snipcart offers inventory management if you don't already have a solution&lt;/li&gt;
&lt;li&gt;Snipcart already has a shopping cart if you don't need a fully customized cart&lt;/li&gt;
&lt;li&gt;Snipcart checkout does not redirect customers to another site&lt;/li&gt;
&lt;li&gt;If you just need a shopping cart and checkout then no server code or serverless functions are needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will definitely be considering Snipcart for my own online stores in the future&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stripe.com/docs/payments/accept-a-payment" rel="noopener noreferrer"&gt;Stripe Accept a payment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stripe.com/docs/payments/integration-builder" rel="noopener noreferrer"&gt;Stripe Accept a payment annotated code tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gatsbyjs.com/tutorial/" rel="noopener noreferrer"&gt;Gatsby.js Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.netlify.com/blog/2020/04/13/learn-how-to-accept-money-on-jamstack-sites-in-38-minutes/" rel="noopener noreferrer"&gt;Learn How to Accept Money on Jamstack Sites in 38 Minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.snipcart.com/v3/" rel="noopener noreferrer"&gt;Snipcart Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://useshoppingcart.com/" rel="noopener noreferrer"&gt;use-shopping-cart&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gatsby</category>
      <category>stripe</category>
      <category>react</category>
    </item>
    <item>
      <title>3 tips for working with dates using vanilla JS</title>
      <dc:creator>Nancy</dc:creator>
      <pubDate>Fri, 28 Aug 2020 20:08:19 +0000</pubDate>
      <link>https://dev.to/nhuynh1/3-tips-for-working-with-dates-using-vanilla-js-23h3</link>
      <guid>https://dev.to/nhuynh1/3-tips-for-working-with-dates-using-vanilla-js-23h3</guid>
      <description>&lt;p&gt;Ok, first off, I know that moment.js exists and I do use it. This article outlines a few tricks I learned by creating a calendar using the Date object &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date"&gt;(MDN web docs)&lt;/a&gt; in (vanilla) Javascript. These tips might be handy if you need to do one-off things with dates&lt;/p&gt;

&lt;h3&gt;
  
  
  Vanilla JS Calendar
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nhuynh1/embed/xxZXpBY?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  First day of the month
&lt;/h2&gt;

&lt;p&gt;Create a new date object with the current date, then set the day to 1 with &lt;code&gt;setDate()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Date object representing first day of current month&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Last day of the month
&lt;/h2&gt;

&lt;p&gt;Since the last day of the month can be different (28, 29, 30, 31 — ugh February!) this one isn't as straightforward. We first have to set the month to the next month and then call &lt;code&gt;setDate()&lt;/code&gt; with &lt;code&gt;0&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMonth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Date object representing last day of current month&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Formatting dates
&lt;/h2&gt;

&lt;p&gt;With the &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat"&gt;MDN web docs&lt;/a&gt;) object it is really easy to format dates—and you can also format them for different languages too&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;monthYearOpts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;monthYearString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;monthYearOpts&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;today&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;monthYearStringFrench&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fr-FR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;monthYearOpts&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dayDateMonthOpts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;weekday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dayDateMonth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dayDateMonthOpts&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;monthYearString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// August 2020, for example&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;monthYearStringFrench&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// août 2020, for example&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dayDateMonth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Sat, August 1, 2020, for example&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's worth noting that the level of customizing is not as granular as something like moment.js. For example &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; automatically places in punctuation automatically based on the language and region.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Built-in Javascript objects work in a pinch for date manipulation and formatting
&lt;/h2&gt;

&lt;p&gt;It's not as handy for more complex date manipulations but it works in a pinch of you need to do something simple. Even creating the Vanilla JS calendar was fairly straightforward&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat"&gt;Intl.DateTimeFormat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date"&gt;Date&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>vanillajs</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Overlaying elements with CSS Grid is so much cleaner than with position! 😲</title>
      <dc:creator>Nancy</dc:creator>
      <pubDate>Fri, 21 Aug 2020 18:11:22 +0000</pubDate>
      <link>https://dev.to/nhuynh1/overlaying-elements-with-css-grid-is-so-much-cleaner-than-with-position-4hcm</link>
      <guid>https://dev.to/nhuynh1/overlaying-elements-with-css-grid-is-so-much-cleaner-than-with-position-4hcm</guid>
      <description>&lt;p&gt;When I searched for ways to overlay content I usually come across the absolute position method, which by the looks of it has been &lt;a href="https://stackoverflow.com/a/2027678/14087332"&gt;around for a while&lt;/a&gt;. And then I learned about CSS Grid and how we can put multiple elements in the same grid area—and they will just lay on top of each other! &lt;/p&gt;

&lt;h2&gt;
  
  
  CSS Grid overlaying content
&lt;/h2&gt;

&lt;p&gt;This method requires some knowledge of how CSS Grid works and the &lt;a href="https://cssgrid.io/"&gt;CSS Grid course by Wes Bos&lt;/a&gt; is a great place to start. Wes briefly discusses this method in one of his course videos.&lt;/p&gt;

&lt;p&gt;With CSS Grid you can place one or more elements in the same grid area. Elements set to the same grid area will just overlay on top of each other. The following is a step-by-step on how to set this up&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add your html elements.&lt;/strong&gt; Create a container, this will be your 'grid container', and in it add the content element and the overlay element. In this example the container aptly has the class &lt;code&gt;grid-container&lt;/code&gt; and we will have the overlay element with class &lt;code&gt;item-grid-overlay&lt;/code&gt; and a content element with class &lt;code&gt;item-grid-content&lt;/code&gt;. I've put a placeholder image in the content element&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"grid-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"item item-grid-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://via.placeholder.com/250?text=Image"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"item item-grid-overlay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;❤️&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Make the &lt;code&gt;grid-container&lt;/code&gt; a 'grid container'&lt;/strong&gt; by giving it the property &lt;code&gt;display: grid&lt;/code&gt;. Doing this will automatically make the child elements 'grid items'. This means you do not have to do anything to &lt;code&gt;item-grid-content&lt;/code&gt; and &lt;code&gt;item-grid-overlay&lt;/code&gt; to make them 'grid items'.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.grid-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Define a 'grid area' in the grid-container&lt;/strong&gt; using &lt;code&gt;grid-template-areas&lt;/code&gt;. In this example, I create just one grid area called &lt;code&gt;overlaydemo&lt;/code&gt;, but the &lt;code&gt;grid-template-areas&lt;/code&gt; property enables you to define as many areas as you want. See the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas"&gt;documentation for grid-template-areas on MDN web docs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.grid-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"overlaydemo"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;/* create one grid area called overlaydemo */&lt;/span&gt;
    &lt;span class="c"&gt;/* you can give your area a different name */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Place both of the content and overlay elements in the 'grid area'&lt;/strong&gt; you defined by setting the grid-area property for each of &lt;code&gt;item-grid-content&lt;/code&gt; and &lt;code&gt;item-grid-overlay&lt;/code&gt; to &lt;code&gt;grid-area: overlaydemo&lt;/code&gt;. Use the same name you defined in &lt;code&gt;.grid-container&lt;/code&gt;, but without the quotes. Since &lt;code&gt;item-grid-overlay&lt;/code&gt; is after &lt;code&gt;item-grid-content&lt;/code&gt; in the HTML it will be on top by default&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item-grid-content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;overlaydemo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;/* use the same name you defined in the .grid-container */&lt;/span&gt;
    &lt;span class="c"&gt;/* notice that we don't use quotes */&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.item-grid-overlay&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;overlaydemo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;/* place the overlay element in the same grid area as the content element */&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;That's it!&lt;/strong&gt; For a bare bones basic implementation that's all you need&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nhuynh1/embed/ExVZzYp?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas"&gt;grid-template-areas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/snippets/css/complete-guide-grid/"&gt;A Complete Guide to Grid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cssgrid.io/"&gt;CSS Grid&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>cssgrid</category>
    </item>
    <item>
      <title>CSS Grid: auto is greedy until it's with fr</title>
      <dc:creator>Nancy</dc:creator>
      <pubDate>Fri, 12 Jun 2020 18:54:07 +0000</pubDate>
      <link>https://dev.to/nhuynh1/css-grid-auto-is-greedy-until-it-s-with-fr-45ko</link>
      <guid>https://dev.to/nhuynh1/css-grid-auto-is-greedy-until-it-s-with-fr-45ko</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclaimer:&lt;/em&gt; this article assumes you have some understanding of CSS Grid. If not, the &lt;a href="https://cssgrid.io/"&gt;CSS Grid course by Wes Bos&lt;/a&gt; (free) and the &lt;a href="https://css-tricks.com/snippets/css/complete-guide-grid/"&gt;CSS Grid Guide by CSS-Tricks&lt;/a&gt; are both great resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;TL; DR:&lt;/em&gt;&lt;/strong&gt; when setting a grid template, such as using &lt;code&gt;grid-template-columns&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt; is "greedy" for left over space except when it's used with &lt;code&gt;fr&lt;/code&gt; units. When &lt;code&gt;auto&lt;/code&gt; is used with &lt;code&gt;fr&lt;/code&gt;, the &lt;code&gt;auto&lt;/code&gt; row(s)/column(s) takes up just enough space to fit its content and any remaining space is given to the row(s)/columns(s) defined with &lt;code&gt;fr&lt;/code&gt; units.&lt;/p&gt;




&lt;p&gt;Note: All the examples in this post are available on &lt;a href="https://codepen.io/nhuynh1/pen/bGEpZKM"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the &lt;code&gt;fr&lt;/code&gt; unit?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;fr&lt;/code&gt; unit represents a fraction of the available space in the grid container. For example setting &lt;code&gt;grid-template-columns: 1fr 1fr 1fr;&lt;/code&gt; would create three equally sized columns that grow and shrink with the container. Also, &lt;code&gt;fr&lt;/code&gt; can be greater than 1, like &lt;code&gt;grid-template-columns: 2fr 1fr;&lt;/code&gt; which sets the first column to be twice as wide as the second column&lt;/p&gt;

&lt;h2&gt;
  
  
  What does &lt;code&gt;auto&lt;/code&gt; mean in CSS grid?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;auto&lt;/code&gt; keyword means to take up the available space to fit the content. If there's space left over then &lt;code&gt;auto&lt;/code&gt; is "greedy"; it will take up space to fit the content &lt;em&gt;plus&lt;/em&gt; the maximum left over space it can take (EXAMPLE 1). The exception is if &lt;code&gt;auto&lt;/code&gt; is used with &lt;code&gt;fr&lt;/code&gt;. If &lt;code&gt;min-width&lt;/code&gt;/&lt;code&gt;min-height&lt;/code&gt; is set on the grid item then the column would be at the smallest the size set by &lt;code&gt;min-width&lt;/code&gt;/&lt;code&gt;min-height&lt;/code&gt; (EXAMPLE 2)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FsYIdGTd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wsg5sdqprrbr3gq46tqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FsYIdGTd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wsg5sdqprrbr3gq46tqc.png" alt="Example 1: defining three columns using auto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KfMM5Fnd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rmu99tkna73due8ujodk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KfMM5Fnd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rmu99tkna73due8ujodk.png" alt="Example 2: defining three columns using auto; the first column has one item set with a min-width"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When &lt;code&gt;auto&lt;/code&gt; and &lt;code&gt;1fr&lt;/code&gt; have the same effect
&lt;/h2&gt;

&lt;p&gt;If the &lt;strong&gt;&lt;em&gt;grid item's contents takes up the same amount of space&lt;/em&gt;&lt;/strong&gt; then &lt;code&gt;auto&lt;/code&gt; and &lt;code&gt;1fr&lt;/code&gt; has the same effect, which is to evenly take up the available space (EXAMPLE 3)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8MJZtFsU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1ldg0l38py3om6ob5zga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8MJZtFsU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1ldg0l38py3om6ob5zga.png" alt="Example 3: when auto and 1fr have the same effect"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using &lt;code&gt;auto&lt;/code&gt; and &lt;code&gt;fr&lt;/code&gt; together
&lt;/h2&gt;

&lt;p&gt;If &lt;code&gt;auto&lt;/code&gt; and &lt;code&gt;fr&lt;/code&gt; are used together to define the grid template then &lt;code&gt;auto&lt;/code&gt; will take up the space it needs for the content. And the remaining space is divided up to the column(s)/row(s) defined by &lt;code&gt;fr&lt;/code&gt; units. The &lt;code&gt;auto&lt;/code&gt; defined column(s)/row(s) &lt;em&gt;won't&lt;/em&gt; get any more of the leftover space. (EXAMPLE 4)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ou1LTh0G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dhlg8d82du4rpd3hx2bh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ou1LTh0G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dhlg8d82du4rpd3hx2bh.png" alt="Example 4: auto is not as greedy when with fr"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout"&gt;Basic Concepts of Grid Layout MDN Web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/nhuynh1/pen/bGEpZKM"&gt;Examples on Codepen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cover image: by Sharon McCutcheon on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>cssgrid</category>
    </item>
    <item>
      <title>Highlighter effect: Adding box decorations—like padding—to inline elements that wrap onto multiple lines</title>
      <dc:creator>Nancy</dc:creator>
      <pubDate>Fri, 08 May 2020 14:23:14 +0000</pubDate>
      <link>https://dev.to/nhuynh1/highlighter-effect-adding-box-decorations-like-padding-to-inline-elements-that-wrap-onto-multiple-lines-10ip</link>
      <guid>https://dev.to/nhuynh1/highlighter-effect-adding-box-decorations-like-padding-to-inline-elements-that-wrap-onto-multiple-lines-10ip</guid>
      <description>&lt;p&gt;As a CSS learning exercise I took the design of &lt;a href="https://www.blogto.com/" rel="noopener noreferrer"&gt;blogTO's homepage&lt;/a&gt; and coded a clone using HTML and CSS. The titles for each article have a "highlight" effect in white, which seemed easy enough until they took up multiple lines&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqcgtuilcbcumv1hv91of.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqcgtuilcbcumv1hv91of.png" alt="Screen capture of article title missing padding on the right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlighting text is easy with &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Highlighting is easily added by wrapping the text you want highlighted with &lt;code&gt;span&lt;/code&gt; and setting a background colour for the &lt;code&gt;span&lt;/code&gt; in CSS. Note: &lt;code&gt;span&lt;/code&gt; is an inline element, meaning it does not start on a new line and only takes up as much width as needed&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgbbzhv656me9lx256r7m.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgbbzhv656me9lx256r7m.png" alt="Yellow highlighting of text"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;The spectacle before us was indeed sublime. 
Then &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"highlight"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;came the night of the first falling star.&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; 
Waves flung themselves at the blue evening.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;


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

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

&lt;span class="nc"&gt;.highlight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Trouble comes when we start adding box decorations
&lt;/h2&gt;

&lt;p&gt;When adding padding, border, margin, box-shadow, and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/box-decoration-break#Browser_compatibility" rel="noopener noreferrer"&gt;other box decorations&lt;/a&gt; to inline elements (i.e. &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;) these properties are not by default applied to the element where the the text wraps onto another line&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp3lli3oxvrd96s3pqigq.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp3lli3oxvrd96s3pqigq.png" alt="Yellow highlighting of text that wraps on two lines; padding and border-radius not added where the line breaks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CSS for highlighting with &lt;code&gt;padding&lt;/code&gt; and &lt;code&gt;border-radius&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.highlight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;box-decoration-break&lt;/code&gt; property solves this nicely
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;box-decoration-break&lt;/code&gt; property specifies how an element's box-decorations (i.e. padding, border) should be rendered when broken across multiple lines, columns, or pages. Options for &lt;code&gt;box-decoration-break&lt;/code&gt; are &lt;code&gt;slice&lt;/code&gt; and &lt;code&gt;clone&lt;/code&gt;. &lt;code&gt;slice&lt;/code&gt; is the default, which does not add the box-decoration when the element goes onto multiple lines. With &lt;code&gt;clone&lt;/code&gt;, the box-decoration is applied where the element breaks into multiple lines&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu8clbd4wrs26dqn25v40.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu8clbd4wrs26dqn25v40.png" alt="Yellow highlighting of text that wraps on two lines with padding and border-radius added to where the line breaks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CSS for highlighting with box-decoration-break&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.highlight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-decoration-break&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-box-decoration-break&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* most browsers need -webkit */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Most browsers support &lt;code&gt;box-decoration-break&lt;/code&gt; with the &lt;code&gt;-webkit-&lt;/code&gt; prefix&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nhuynh1/embed/dyYVmva?height=600&amp;amp;default-tab=css,result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser support
&lt;/h2&gt;

&lt;p&gt;There are some limitations when it comes to browser support. Some browsers do not support column or page breaks, but most support line breaks for inline elements. Not surprisingly IE does not support it, and Edge support starts from Edge 79. Check &lt;a href="https://caniuse.com/#feat=css-boxdecorationbreak" rel="noopener noreferrer"&gt;Can I Use&lt;/a&gt; for details&lt;/p&gt;

&lt;p&gt;If you need to support older browsers, a possible solution is styling three nested elements. The trick is adding an extra thick left-border on the outermost element. The innermost element contains the text, and is shifted over to the left. The middle-nested element adds top and bottom padding. See &lt;a href="https://css-tricks.com/multi-line-padded-text/" rel="noopener noreferrer"&gt;CSS Tricks&lt;/a&gt; for details&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/multi-line-padded-text/" rel="noopener noreferrer"&gt;Multi-Line Padded Text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codepen.io/chriscoyier/pen/hIvFe" rel="noopener noreferrer"&gt;Multiline Padding with box-decoration-break&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/box-decoration-break#Browser_compatibility" rel="noopener noreferrer"&gt;box-decoration-break&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://caniuse.com/#feat=css-boxdecorationbreak" rel="noopener noreferrer"&gt;Can I Use&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
