<?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: Peter</title>
    <description>The latest articles on DEV Community by Peter (@peterlunch).</description>
    <link>https://dev.to/peterlunch</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%2F358832%2Fda87fb8f-ff37-491a-b1a6-54bef42f0eb7.jpeg</url>
      <title>DEV Community: Peter</title>
      <link>https://dev.to/peterlunch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peterlunch"/>
    <language>en</language>
    <item>
      <title>How to write a PR that sparks joy</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Mon, 28 Mar 2022 22:32:18 +0000</pubDate>
      <link>https://dev.to/peterlunch/how-to-write-a-pr-that-sparks-joy-3364</link>
      <guid>https://dev.to/peterlunch/how-to-write-a-pr-that-sparks-joy-3364</guid>
      <description>&lt;p&gt;When I started my first job I struggled to write good pull requests(PRs). At first, I had no idea what to put in a PR or why you needed to write one. I thought you just submitted your code as a PR and then the person reviewing it would do the rest. It seemed straight forward.&lt;/p&gt;

&lt;p&gt;Boy was I wrong, because whenever I’d submit a PR it would explode with comments (a lot of comments). This would lead to refactoring, which led to more comments, leading to more refactoring and so on and so forth. Until a week later and it is finally done, and I’m left feeling like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4a2jfxnqx5lddmi118r.gif" 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%2Fuploads%2Farticles%2Fo4a2jfxnqx5lddmi118r.gif" alt="gif of frodo saying it's done with fire in the background, he is feeling exhausted"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was not a feeling of relief. Once the PR is closed and merged, I’d feel angry. Angry for wasting peoples time, angry that it got to this position and angry that I let it happen more than once.&lt;/p&gt;

&lt;p&gt;The good news is, my PRs have gotten a lot better. I’m now getting comments in them above the level of a linter. In fact, I now look forward to getting other developers to look at my code, and I think they enjoy reading my PRs (well as much as one can).&lt;/p&gt;

&lt;p&gt;This post is going to help improve how you write and manage your PRs, you are going to get so good that they spark joy for those reading them. However, you may be asking why you want to spark joy in your PR?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you should improve your PRs so they spark joy
&lt;/h2&gt;

&lt;p&gt;Improving code reviews not only helps you, it helps others to help you. Here are the main benefits you get from writing better PRs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You’ll show that you value your team members time&lt;/strong&gt;: Time is a non-renewable resource. Knowing that, do you want to eat away at your team members time by treating them like your personal linter? You should be valuing your reviewers time by making your PRs a pleasure and not serving them up a big dish of spaghetti code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less time refactoring more time building:&lt;/strong&gt; The less rounds of feedback the more time you have for picking up tickets, and therefore building on your reputation and abilities. Enhanced reputation and production often leads to tangible benefits like more money (who doesn’t love money).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhances your learning:&lt;/strong&gt; If reviewers are spending less time as your personal QA, then they will be able to pay more attention to areas of growth for you. Instead of pointing out sloppy errors, they will be able to point out ways for you to write better code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You now know the why, let’s look at the hard part, the &lt;strong&gt;how&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to write better pull requests
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Have a checklist
&lt;/h3&gt;

&lt;p&gt;Early on you are going to make mistakes in your PRs. Once or twice is okay, more than that and you’re being rude.&lt;/p&gt;

&lt;p&gt;If your colleagues keep pointing out the same mistakes on your PRs, like leaving console.logs in your code, or not following agreed naming conventions, add those to a checklist. You then run through the checklist each time before you submit your PR.&lt;/p&gt;

&lt;p&gt;Below is my checklist as it stands now. This is a living breathing checklist that I continually update.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PR Checklist
- Console.logs
- Naming conventions
- Unused comments
- Unused CSS
- Design patterns match rest of codebase
- No if else
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's inescapable that you will submit a PR with sloppy errors in it. Don’t fret, just add that mistake to your checklist. Also pay close attention to any pattern of errors you are making and add them to the list. The key is to not let errors happen frequently, because it says to your reviewer that you don’t value their time.&lt;/p&gt;

&lt;p&gt;I believe it is a good idea to add the next few techniques to your checklist, but let’s review them before we do that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before you submit, walk away and come back fresh
&lt;/h3&gt;

&lt;p&gt;Before I submit any PR I step away from the code, at least for a few hours, ideally I sleep on it.&lt;/p&gt;

&lt;p&gt;When you come back the next day, your code is going to look very different. You might even wonder who wrote that garbage (it was you!). That’s okay, you want this. If you struggle to understand it the next day, imagine how your reviewer would have felt.&lt;/p&gt;

&lt;p&gt;Now is your chance to fix those silly mistakes and to try and make it more readable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protip:&lt;/strong&gt; When reviewing your code pretend you are someone else in the team. Use the tools they would use to review your code like the diff checker and try to check the things they frequently call out in your code. For instance, one of my team members is a stickler for wording in test it blocks, so when I pretend to be them I go through and check that first. It’s amazing what I pick up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write code that explains itself
&lt;/h3&gt;

&lt;p&gt;Your code should be written so that reviews don’t have to ask you questions like “what is this function doing?”.&lt;/p&gt;

&lt;p&gt;Even if you are able to explain what the function is doing once someone asks in the PR, what happens when someone needs to understand it without the context of the PR?&lt;/p&gt;

&lt;p&gt;Therefore, if your code is hard to follow it needs to be rewritten. At the very least it needs to have comments explaining it.&lt;/p&gt;

&lt;p&gt;If you’re not sure how to write the function in a readable manner or you can’t explain it succinctly using comments, it’s okay to comment in your PR saying just that. PRs are a place to generate discussions, the goal of the PR is to generate the best outcome for all parties involved.&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%2Fuploads%2Farticles%2Fw6zo1cvgs8dl9j8oxsl2.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%2Fuploads%2Farticles%2Fw6zo1cvgs8dl9j8oxsl2.png" alt="screenshot of github comment in pr asking for discussion around a topic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are going to do this just make sure you explain what you tried and why you went with this approach in the end. Make it easier for the reviewers to give you better direction and then implement that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Have a changelist
&lt;/h3&gt;

&lt;p&gt;Changelist are a simple way for you to communicate to the reviewer what you’ve changed and to give them any background context they need.&lt;/p&gt;

&lt;p&gt;Try to think about the future when writing a change list. Imagine you’re someone 2 years from now who has to update that part of the codebase. That future reader should be able to understand the context of the change.&lt;/p&gt;

&lt;p&gt;My mentor says “a good change list is one that explains the what and the why”. The what, is &lt;em&gt;what this change achieves&lt;/em&gt; and the why, is &lt;em&gt;why you are making this change&lt;/em&gt;. It should then list what specifically was changed.&lt;/p&gt;

&lt;p&gt;You can also vastly improve your changelist by using screenshots and videos. After all a picture is worth a thousand words.&lt;/p&gt;

&lt;p&gt;Save your reviewers time by showing them before and after images of any visual changes, and show them what it looks like at different screen sizes. Use video to give them a demo of the new behaviour in the application. Help them to help you.&lt;/p&gt;

&lt;p&gt;Finally include any relevant links in the change list, below are some that are useful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Link to design files&lt;/li&gt;
&lt;li&gt;Link to any discussions outside of the card for example a slack discussion with a designer agreeing to any changes&lt;/li&gt;
&lt;li&gt;Link to the ticket&lt;/li&gt;
&lt;li&gt;Link to any relevant ADR’s&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Keep it in scope
&lt;/h3&gt;

&lt;p&gt;Scope creep is the mortal enemy of PRs.&lt;/p&gt;

&lt;p&gt;I’m talking about those small UI issues you notice, that you think I can quickly fix that up. Well those little UI changes have now muddled up the review and your reviewer has to spend energy thinking about what they are supposed to be reviewing.&lt;/p&gt;

&lt;p&gt;I know it’s tempting to make that quick change, but that change alters the purpose of the PR. You are better off making a new ticket that fixes the UI issue, so your reviewer can review the code they are supposed to be reviewing in isolation.&lt;/p&gt;

&lt;p&gt;Scope creep is tricky, it is hard to resist making that small little change. But, your reviewer will thank you when it comes time to review your PR because they don’t have to switch context while reviewing your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to handle a PR after submission
&lt;/h2&gt;

&lt;p&gt;Even well written PRs don’t end after you hit submit. They are still being written until you hit that merge button. Therefore, to write a good PR you need to handle your business until you’ve hit merge and closed the PR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check your ego
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Don’t take feedback personally.&lt;/strong&gt; Your code isn’t you. You need to be the bigger person when receiving feedback. Don’t get mad or take it as a personal attack (even if it is one). At the end of the day you are in control of one thing, yourself and how you respond. You can’t control how others will behave in your PR.&lt;/p&gt;

&lt;p&gt;If feedback isn’t clear, check the ego and request clarification in a nice way. Try something like, “Good point and I think I understand it. you please just clarify your point on X”. At the end of the day, the other person is just trying to improve your code (some just go about it better than others…developers!).&lt;/p&gt;

&lt;p&gt;Often feedback is a gift. It can be a real positive when your reviewer spots obscure issues in your code. Why? Because it shows you are writing your PRs at a high level. When your reviewer can go past obvious issues, they get to spend their time focusing on real issues like logic, design and edge cases, which results in feedback you actually want.&lt;/p&gt;

&lt;p&gt;Ensure that you respond to any learnings your reviewer has been kind enough to give you with gratefulness. If they have taken the time to teach you something, ensure that you respond in a way that shows your gratitude.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactor quickly
&lt;/h3&gt;

&lt;p&gt;Drake has a line in the song One Dance - “as soon as you see the text, reply me”. I like to switch it up and sing it like this to myself “as soon as you see the feedback, refactor me”.&lt;/p&gt;

&lt;p&gt;The best way to show your reviewer that you value their time is to be efficient in your response time. You do this by actioning their feedback quickly.&lt;/p&gt;

&lt;p&gt;Why is this important? It is important because it reduces your reviewers need to refamilarize themselves with your code.&lt;/p&gt;

&lt;p&gt;Look at it from their shoes. If you were to review their PR, provide feedback and then not hear from them until a few days later, it is likely you might have forgotten what the code they wrote does and why you left the feedback. So you essentially have to double review the code.&lt;/p&gt;

&lt;p&gt;By responding quickly you reduce the need for your reviewer to have to go over the code again, meaning they just focus on the code you have refactored.&lt;/p&gt;

&lt;p&gt;Now there is one thing to bear in mind with this, sometimes you will need to leave enough time for others to review the code. You don’t want to be constantly refactoring if there are disagreements on the feedback.&lt;/p&gt;

&lt;p&gt;The way I approach it is to ensure at least two reviewers leave feedback before I make any changes to the code. As soon as I have at least two devs who have reviewed the code, I will quickly make the changes I need to keep the PR moving forward.&lt;/p&gt;

&lt;p&gt;This is a judgement call and it depends on how your team works. I’d say a good rule of thumb is anymore than 24hrs between the feedback and refactor, you are making life harder for your reviewer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communicate changes
&lt;/h3&gt;

&lt;p&gt;As I’ve read more good PRs, I’ve noticed a superior pattern of communication when changes are made. That pattern is to communicate explicitly once changes have been made, where they have been made and that they are ready for another round of reviews.&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%2Fuploads%2Farticles%2Fj2ncg78zvs8fnr8w15rn.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%2Fuploads%2Farticles%2Fj2ncg78zvs8fnr8w15rn.png" alt="screenshot of github comment in pr where author post the number of the commit the changes requested were made"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is superior to the ambiguity of pushing changes and expecting your reviewer to jump back in because you remove a lot of uncertainty. The reviewer doesn’t have to guess if your changes are done and if they are ready for the next round of reviews. Thus, you are valuing the reviewers time. Helping them avoid re-reviewing half finished code.&lt;/p&gt;

&lt;p&gt;It also saves the reviewers time as they don’t have to search for where the changes have been made, they can quickly click your link and go straight to reviewing that section of code.&lt;/p&gt;

&lt;p&gt;It also helps to ensure you mark the feedback as resolved once it is. That way everyone knows that there is no need to look at this issue any further, meaning the reviewer can approve the code and you can merge it.&lt;/p&gt;

&lt;p&gt;Finally ensure you are communicating that you have made changes and that the PR is ready for another round of reviews in a public channel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t rub it in
&lt;/h3&gt;

&lt;p&gt;You will learn a lot from your senior colleagues. At the same time you need to understand that they can be wrong too, just like you will write code that is wrong and needs to be corrected. In these situations you will need to develop judgement, understanding, and persuasive skills to navigate them expertly.&lt;/p&gt;

&lt;p&gt;It’s human to want to react to reviewer mistakes, especially if you’ve been taken beatings in your PRs. I’ve felt the frustration, that feeling like you’re being targeted. But, don’t take that mistake as a personal slight.&lt;/p&gt;

&lt;p&gt;The important thing here is that you take the high road (as in don’t be a dick). In fact, it’s a good chance to reflect on your code again. If the reviewer is confused, perhaps your code isn’t clear enough. Take the opportunity to improve your code, or leave comments that give clarity.&lt;/p&gt;

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

&lt;p&gt;Writing good PRs is hard, especially when you are just starting out. As you get ready to write your next PR, remember what you control, there is no need to rush from finishing the work to submitting the PR.&lt;/p&gt;

&lt;p&gt;Start by looking over the code with fresh eyes, go over your checklist and handle any sloppy mistakes before you waste your reviewers time. Remove anything that isn’t in scope and set it aside for later. Next, check that your code explains itself, if it doesn’t address it in the PR. Finally, write a stellar changelist that shows the what and the why of the changes.&lt;/p&gt;

&lt;p&gt;Your job isn’t done once it is submitted, you need to address any feedback in a timely manner, and then communicate it explicitly. If you follow the above you are well on your way to writing better PRs that spark joy in your reviewers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want more content?&lt;/strong&gt; &lt;a href="https://twitter.com/thelynchpinau" rel="noopener noreferrer"&gt;Follow me on twitter&lt;/a&gt; and get things like &lt;a href="https://www.freecodecamp.org/news/level-up-developer-portfolio/" rel="noopener noreferrer"&gt;5 ways to level up your developer portfolio&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>github</category>
      <category>beginners</category>
      <category>git</category>
    </item>
    <item>
      <title>How to Level Up Your Developer Portfolio</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 08 Feb 2022 22:42:12 +0000</pubDate>
      <link>https://dev.to/peterlunch/how-to-level-up-your-developer-portfolio-109i</link>
      <guid>https://dev.to/peterlunch/how-to-level-up-your-developer-portfolio-109i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post originally appeared on FreeCodeCamp &lt;a href="https://www.freecodecamp.org/news/level-up-developer-portfolio/"&gt;here&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's not a big secret that building a developer portfolio can greatly increase your chances of getting hired.&lt;/p&gt;

&lt;p&gt;Everyone tells you that. But, they don't always tell you what makes a good one.&lt;/p&gt;

&lt;p&gt;You see, many portfolios are generic and rather uninspiring. If your portfolio looks just like everyone else's, then how can you expect it to stand out?&lt;/p&gt;

&lt;p&gt;Well, it won't stand out.&lt;/p&gt;

&lt;p&gt;But don't worry – I've been there. &lt;a href="https://peter-lynch.netlify.app/index.html"&gt;My first portfolio&lt;/a&gt; was bland, uninspiring, and had many of the not-to-do's I talk about in this post.&lt;/p&gt;

&lt;p&gt;However, I'm an ex-marketer, turned developer, I know how to make something stand out. I've made ad campaigns that have skyrocketed sales and had people talking. I realized I needed to think like a marketer to make my portfolio stand out.&lt;/p&gt;

&lt;p&gt;The good news is that the same principles can be applied to your portfolio to level it up. If you read this guide and implement the tips, you'll raise your portfolio above the sea of other junior developers trying to stand out.&lt;/p&gt;

&lt;p&gt;Before we launch into the five tips to level up your portfolio, let's just make sure we are on the same page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bare minimum of a portfolio
&lt;/h2&gt;

&lt;p&gt;These are the non-negotiables of any developer portfolio:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Responsive design (learn about how to do that &lt;a href="https://www.freecodecamp.org/learn/responsive-web-design/"&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Projects showcasing your work&lt;/li&gt;
&lt;li&gt;An "about me" section or somewhere people reading your site can learn about you&lt;/li&gt;
&lt;li&gt;Your portfolio needs to be accessible&lt;/li&gt;
&lt;li&gt;Your portfolio should have a custom domain. Buy a domain name – you can get them for less than $10. Don't send people to 39238834.netfily.com
A way for people to contact you, preferably your email
If you have these six non-negotiables on your portfolio, you are off to a good start.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let's look at five ways you can level up your portfolio, starting with a non-obvious one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five things you can do to level up your developer portfolio
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. Know your target audience
&lt;/h2&gt;

&lt;p&gt;One area that can help level up your portfolio is knowing exactly what the purpose of your portfolio is. That is, who is this portfolio for?&lt;/p&gt;

&lt;p&gt;If I asked you what the purpose of your portfolio was, does the output match that? Let's say, for example, the purpose of your portfolio is to land your first junior developer role. Then your portfolio is going to look very different from someone who is looking to be a freelance web developer.&lt;/p&gt;

&lt;p&gt;Therefore the first thing you need to do is ask what is the purpose of your portfolio. Start broad and then try to refine it. Keeping with the junior developer role example, you could refine it down to a junior frontend developer specializing in React.&lt;/p&gt;

&lt;p&gt;If you are a junior frontend developer, then your portfolio won't need things like the generic skill cards below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FkWWNih7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4xm4vjfn5xt6pqnow20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FkWWNih7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4xm4vjfn5xt6pqnow20.png" alt="Three generic skills cards with headings cross-industry experience, full stack development and design focus." width="880" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These cards are better suited for someone who is looking for freelance work.&lt;/p&gt;

&lt;p&gt;When you know the purpose of your portfolio, you can better tailor the information to communicate why someone should help you achieve your purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Level up your project details
&lt;/h2&gt;

&lt;p&gt;This is the most important section of your portfolio, and it is the one section I often see that is not well-executed.&lt;/p&gt;

&lt;p&gt;If you browse something like &lt;a href="https://www.reddit.com/r/webdev"&gt;r/webdev&lt;/a&gt; and search "portfolio" let me tell you what you're going to see if you click 90% of those portfolios and look at projects. You're going to see a calculator app, a weather app, tic tac toe, a movie finder app, "insert big website" clone, and so on.&lt;/p&gt;

&lt;p&gt;Now, don't get me wrong – these are useful projects for learning the skills they require. And people have spent time making them. The problem is that everyone builds the same stuff. You can often just follow along with a tutorial and create them without much thought.&lt;/p&gt;

&lt;p&gt;There are two problems here.&lt;/p&gt;

&lt;p&gt;The first is that you are not differentiating yourself. If I'm HR or the hiring manager why should I pick your calculator app over the other 30 in the inbox? Also, how can I trust that you built this thing yourself and that you didn't just copy/paste code from a tutorial?&lt;/p&gt;

&lt;p&gt;The second is that most people just put the project in, link to the GitHub repo, and maybe a live demo. This doesn't tell the person who is potentially going to hire you a lot, and it doesn't give them much reason to employ you over everyone else who has done the same.&lt;/p&gt;

&lt;p&gt;So then, how do you make your projects section stand out? Let's look at a few ways you could level up the projects section of your portfolio.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add original projects
&lt;/h3&gt;

&lt;p&gt;You don't have to reinvent the wheel or make the next great social media application. But it would be great if you tried to use a different API instead of the standard weather API.&lt;/p&gt;

&lt;p&gt;You could for instance create a surf report app that is the same as a weather app but instead you are calling different endpoints. This shows me that you know how to call an API outside of a tutorial.&lt;/p&gt;

&lt;p&gt;If you're not sure how to make your own original project then check out this guide on &lt;a href="https://www.peterlunch.com/blog/how-to-plan-and-build-a-programming-project"&gt;how to plan and build a programming project for beginners&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Give some details about the project
&lt;/h3&gt;

&lt;p&gt;The first problem is that many projects are unoriginal. The second is that most people don't give more than the basic details about the project.&lt;/p&gt;

&lt;p&gt;What will make you stand out is giving some details about your project. When I say details, what I mean is give me a story about the project. The best portfolios I see tell me about the project don't just show it to me.&lt;/p&gt;

&lt;p&gt;Try answering some of these questions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why did you choose to build this project?&lt;/li&gt;
&lt;li&gt;What challenged you when making this project?&lt;/li&gt;
&lt;li&gt;What did you learn from making this project?&lt;/li&gt;
&lt;li&gt;What learnings have you taken with you into other projects?&lt;/li&gt;
&lt;li&gt;What would you do differently next time?&lt;/li&gt;
&lt;li&gt;Did you get stuck at any point? How did you get unstuck?&lt;/li&gt;
&lt;li&gt;What was your process for completing this project? Did you do wireframes, make a Trello board, or did you just get stuck into it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you answer these questions and craft them into a few succinct paragraphs, I will now know a lot more about your abilities as a developer. I can see what interests you, how you overcome challenges, how you learn from those challenges, and what skill level you are.&lt;/p&gt;

&lt;p&gt;You're already well on your way to standing out if you follow this tip.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Remove Unnecessary Fluff from Your Portfolio
&lt;/h2&gt;

&lt;p&gt;Sometimes the best thing you can do to improve your portfolio is to remove things.&lt;/p&gt;

&lt;p&gt;You should remove things that add no value to your target audience and things that reduce your credibility.&lt;/p&gt;

&lt;p&gt;Here is a list of things you to remove and why.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step-by-step tutorial projects. These projects hurt your credibility. They are unoriginal, they don't show me what you can do. Rather, they show me that you can copy what someone else does.
&lt;/li&gt;
&lt;li&gt;Projects not related to development or the job you are trying to land. These just aren't relevant to your target audience.&lt;/li&gt;
&lt;li&gt;If one of your Projects is the portfolio itself. Why get rid of this? The reason is that they are on your portfolio now. They are interacting with the project. So save space for another project.&lt;/li&gt;
&lt;li&gt;Skill progress bars. While they look cool, they are bad. If you're a junior you probably know 10% JavaScript, would you want to represent that? What the heck does 80% CSS mean? If you remove one thing, please make it these.&lt;/li&gt;
&lt;li&gt;If your portfolio is a carbon copy of someone else's portfolio – start over. It's not cool for starters. Plus, I want to see what you're capable of doing, not what you're capable of copying. It can come back to hurt you in the long run.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Give your about me some personality
&lt;/h2&gt;

&lt;p&gt;There is this song by Paul Kelly called "Every F$*#%) City" and the general idea of the song is that every city is the same. Well, I've seen a lot of portfolio's and a lot of them look the same.&lt;/p&gt;

&lt;p&gt;The section that often comes off as the same is the about me section. Let's look at an example below.&lt;/p&gt;

&lt;p&gt;_"Hi, my name's Jonny Lucky, a Full-Stack Web Developer from Example Town. I love building websites that solve life's unique problems.&lt;/p&gt;

&lt;p&gt;I work primarily with MongoDB, Express, React, Node, and GraphQL and have set up countless WordPress and Shopify websites. My previous career was as an IT Consultant, E-commerce Business Owner, and Digital Marketer. I also really enjoy tinkering with CSS.&lt;/p&gt;

&lt;p&gt;In my spare time, I play video games and also work out."_&lt;/p&gt;

&lt;p&gt;Hello Jonny Lucky, or was it Lucy Lovely? I forgot because I'm the HR person and I've read 50 of these portfolios and they are all very similar.&lt;/p&gt;

&lt;p&gt;If I were to change your name, town, and tech stack, many of these candidates would just become one.&lt;/p&gt;

&lt;p&gt;To be fair, there are some personal touches like the that they "play video games and also workout". But, guess what? A lot of other applicants also enjoy these things.&lt;/p&gt;

&lt;p&gt;Can you see the problem, if you have an about me section like the above? You won't stand out and you'll come across as a little stiff.&lt;/p&gt;

&lt;p&gt;Your about me needs to be a little bit spicy, it needs to show your personality and experience. Because your personality is different from other people, so your about me section should be too.&lt;/p&gt;

&lt;p&gt;Let's have a look at mine to give you an idea of what you should be shooting for. I've gotten a few compliments on it.&lt;/p&gt;

&lt;p&gt;_"I'm an ex-marketer who loves building things with code.&lt;/p&gt;

&lt;p&gt;I first became enthralled with programming in 2015. I was in San Francisco with my brother in law and he was telling me about this thing called Python and how it could automate things. As a person who looks for efficiencies, I was hooked.&lt;/p&gt;

&lt;p&gt;I jumped right into Python on my flight back to Australia. Soon, I was automating my own things. I made a bot to book classes at the gym, one to send weekly reports to my boss and I even made one to like my girlfriend's content on Instagram. Unfortunately, that is as far as it went. Shortly after, I got promoted. So, I had less time to learn and I let programming fall by the wayside.&lt;/p&gt;

&lt;p&gt;But, then Covid hit and suddenly I had more time without my commute. So, I started learning again. Specifically, I learned web development, as I had things I wanted to build for myself.&lt;/p&gt;

&lt;p&gt;After a few months of self-teaching, I knew this was what I wanted to do for my career. So, I signed up for the coder academy Bootcamp and put my heart and soul into it. I was coding every day, late into the night, and on weekends. Until I was ready to be unleashed on production code.&lt;/p&gt;

&lt;p&gt;Since the boot camp, I have grown as a developer, working alongside senior developers who have helped me raise my standards for what's expected of any web application.&lt;/p&gt;

&lt;p&gt;I'm now seeking a full-time role where I can contribute my skills both in coding and business to help a company achieve their goals."_&lt;/p&gt;

&lt;p&gt;As you can see my about me section is unique to me. I'd say there isn't another soul on the planet who could write the same about me section without telling some lies.&lt;/p&gt;

&lt;p&gt;Now, your about me section doesn't have to be zany, it can be professional. But, and this is a key point...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You need to make it interesting so the person reading it wants to continue reading it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make your about me section interesting, you can try things like stories and anecdotes. Try and weave them in with the key points you want to get across.&lt;/p&gt;

&lt;p&gt;Another way to think of it is, if you are invited in for an interview would your about me be interesting enough that the person interviewing you would say "hey, I loved that story about X on your portfolio"? If it can do that you're winning because you've opened up more dialogue.&lt;/p&gt;

&lt;p&gt;In the end, you're trying to spark interest in the person looking at your portfolio.&lt;/p&gt;

&lt;p&gt;Think about it like this. If HR has 50 applications to get through, they are only going to interview 5 of those people.&lt;/p&gt;

&lt;p&gt;If your about me section is a bland generic version like the first one, they are likely to just skim through it and onto your next section. If nothing else on your portfolio stands out, then they'll move on to the next application until something does jump out at them. You want to grab their attention and make them shift you to the interview pile.&lt;/p&gt;

&lt;p&gt;Since most portfolios are generic, it doesn't take much to stand out. If you have less experience than someone else but their portfolio is generic and yours isn't, I'd argue you are more likely to get picked for an interview.&lt;/p&gt;

&lt;p&gt;Why? Because we like to work with people we like, and if you show that you're an interesting unique person, I'd probably like to at least find out more about you.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Throw some Sprinkles on it
&lt;/h2&gt;

&lt;p&gt;One of the most important lessons I was taught early on in my coding Bootcamp was that you need the doughnut before the sprinkles.&lt;/p&gt;

&lt;p&gt;Looking at this analogy in regards to your portfolio, the doughnut is all the other things I have listed above. You need the baseline requirements of a portfolio like solid projects, an interesting about me section, and responsive design.&lt;/p&gt;

&lt;p&gt;The sprinkles should come after you have all the basics. So, if you followed the tips above you have the doughnut. Now, you can start to make your portfolio shine.&lt;/p&gt;

&lt;p&gt;Add things that make a prospective employer go wow! You can add amazing animations like &lt;a href="https://cherupil.com/"&gt;Christopher Cherupil&lt;/a&gt;, cool transition effects like &lt;a href="https://philippeneveu.com/"&gt;Philippe Neveu&lt;/a&gt;, or dark mode like &lt;a href="https://jhey.dev/"&gt;Jhey Tompkins&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I added a &lt;a href="https://www.peterlunch.com/blog/javascript-exit-intent-modal"&gt;Zelda-themed modal&lt;/a&gt; to make sure a prospective employer grabbed my résumé before they left my old portfolio site. I just made sure I had the basics first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9_KRr-Ma--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdxlxg7t2egdpihz4vmc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9_KRr-Ma--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdxlxg7t2egdpihz4vmc.png" alt="Contents of the Zelda exit intent modal I built for my resume." width="880" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also go wild with your ideas, just make sure you execute them. You don't want unpolished sprinkles that could take away from your doughnut's main elements.&lt;/p&gt;

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

&lt;p&gt;If you read this post and thought, oh man my portfolio is quite generic – don't fret. You now have 5 things you can do to level up your portfolio so that it moves from the "forgotten" pile to the "give this person an interview" pile.&lt;/p&gt;

&lt;p&gt;I can frequently be found in portfolio advice threads on Reddit and Twitter trying to offer advice to people trying to break into the industry.&lt;/p&gt;

&lt;p&gt;When you're done leveling up your portfolio, and you're looking for some feedback on it, make sure to Tweet it to me with a link to your site.&lt;/p&gt;

&lt;p&gt;If you have a portfolio you're proud of or you're looking for feedback on it, &lt;a href="https://twitter.com/thelynchpinau"&gt;follow me on twitter&lt;/a&gt; and tweet the link to me so I can look over it and give you some feedback.&lt;/p&gt;

&lt;p&gt;If you have an awesome one I might even add it to my &lt;a href="https://github.com/pin0S/portfolios-that-pop"&gt;portfolios that pop list&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>portfolio</category>
      <category>beginners</category>
      <category>career</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Should You do a Bootcamp in 2022?</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 01 Feb 2022 09:36:31 +0000</pubDate>
      <link>https://dev.to/peterlunch/should-you-do-a-bootcamp-in-2022-3dan</link>
      <guid>https://dev.to/peterlunch/should-you-do-a-bootcamp-in-2022-3dan</guid>
      <description>&lt;p&gt;Coding bootcamps were popping off in the early 2010s. Bootcamp graduates were landing jobs with fat $100K salaries. And many were doing this in 12 weeks or less. It seems like every bootcamp graduate you talked to was working at places with ping pong tables and free food.&lt;/p&gt;

&lt;p&gt;It’s now the 2020’s and you want to be a big-time developer who makes a fat salary. You want to get paid to do something you love. So you think you’ll do a bootcamp. But, then you peep the $14K price tag. You start wondering - are bootcamps still good? Can you still make a big-time salary? Are all the things that were true a few years ago still true in 2022? And, if they are should you do a bootcamp in 2022.&lt;/p&gt;

&lt;p&gt;The answer is...&lt;strong&gt;it depends&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Lame, I know. But, it really does depend on a few factors. This post is going to tell you what those factors are, to help you decide if you should still do a bootcamp in 2022.&lt;/p&gt;

&lt;p&gt;Treat the post like a choose your own adventure. Skim the headings and read the sections that are relevant to you. If you read the whole thing it will tell you what a bootcamp is, how to decide if a bootcamp is right for you, the bad parts of a bootcamp, the good parts, and the alternatives.&lt;/p&gt;

&lt;p&gt;Alright, let’s get into it. If you are a person who thinks a bootcamp is doing exercise in a park with a bunch of strangers, read on to find out what a coding bootcamp is and why you might want to do one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Coding Bootcamp
&lt;/h2&gt;

&lt;p&gt;A coding bootcamp is a short intensive course that aims to teach you the bare minimum you need to find your first developer job. This is an important point to take note of. Why? Because coding bootcamps won’t teach you everything you need to know. Some of it you are going to have to learn yourself and some of it you are going to have to learn on the job. This important factor to acknowledge and we’ll go into it more later. For now, just know bootcamps aim to teach you to code quickly.&lt;/p&gt;

&lt;p&gt;These coding bootcamps can also be online only, in person, or a mix of the two. All of them should offer live teaching, instructors, and a structured program. They are not pre-recorded video courses you might buy off Udemy where you have no access to the instructor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Bootcamps
&lt;/h3&gt;

&lt;p&gt;There are many types of coding bootcamps and they can focus on a range of different technologies. It could be a data science bootcamp or maybe a web development bootcamp. What interests you, will determine what type of bootcamp to do.&lt;/p&gt;

&lt;p&gt;When looking at the types of bootcamps, I think the best way to look at them is cost and ownership structure. Here are the types to help you search:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Privately owned local bootcamps - think your little hometown bootcamp put together by local people.&lt;/li&gt;
&lt;li&gt;University Bootcamps - often these aren’t run by the University but are actually run by private for-profit companies who want to leverage the Universities brand.&lt;/li&gt;
&lt;li&gt;Non-for-profit - bootcamps run for free (very rare). &lt;a href="https://www.reddit.com/r/learnprogramming/comments/rlmulr/i_ran_a_100_free_full_stack_web_development/"&gt;But Leon Noel is running one now.&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Privately owned bootcamp chains like Generally Assembly, Le Wagon, or Lambda School.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you know what coding bootcamps are and aren’t, let’s look at the factors you should consider before deciding if you should do a bootcamp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factors to Consider
&lt;/h2&gt;

&lt;p&gt;Ideally, you want to give a bootcamp everything you have. You want to be able to dedicate your time and energy towards learning to code. Doing this will mean you can get the most out of the bootcamp. It will also give you a higher likelihood of being successful in finding a job.&lt;/p&gt;

&lt;p&gt;Bootcamps are not easy. They will challenge you and ask a lot of you. Just having a teacher and structure won’t make things easy. A lot of people think they can just sign up, half-ass it and get a job in the end. Unfortunately, it doesn’t work like that.&lt;/p&gt;

&lt;p&gt;This next section looks at some factors you should consider if you’re not sure if you should do a bootcamp. You want to consider these. Because, if you acknowledge these factors then you are more likely to be able to immerse yourself and be successful during your time in the bootcamp.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do You Know if You Enjoy Coding?
&lt;/h3&gt;

&lt;p&gt;Have you tried to code? Do you even like it? If you answered no to either of these. &lt;strong&gt;Do not do a bootcamp.&lt;/strong&gt; You can stop reading here. Why?&lt;/p&gt;

&lt;p&gt;Because bootcamps are tough. You will be battling to keep up with the material covered. Most likely, you are going to have to work a lot of hours, on nights and weekends. I probably averaged 10-12 hours a day on weekdays and 4-8 hours on weekends. This is how they squeeze 1 year's worth of material into 12 weeks because they force you to do a lot of work outside of class. Ouch. So, if you don’t want your money to go to waste, you need to work your ass off.&lt;/p&gt;

&lt;p&gt;Therefore, if start the bootcamp without having ever written one line of code you’re going to be in real trouble. There are two reasons for this.&lt;/p&gt;

&lt;p&gt;First, if you haven’t ever coded how do you know you’ll enjoy it. If you don’t enjoy it your probably not going to get through the bootcamp or you might not get through your first year in the industry. To use an analogy, let’s say you don’t enjoy exercise. Now say you sign up for a marathon, where you had to run it in 3 hours. How likely are you to train to do that marathon? And even if you run it, how likely are you to finish in under 3 hours? I’d say it is a low likelihood for most people. The same applies to bootcamps, trust me I’ve seen it.&lt;/p&gt;

&lt;p&gt;Now, I’m not saying you have to like what you do. Plenty of people I’ve worked within the past hated what they did, they suffered through it because they had mouths to feed. But, unless you’re incredibly driven it’s going to be hard to do those 12+ hour days for 12 weeks. Hard, but not impossible. You need to decide.&lt;/p&gt;

&lt;p&gt;The next reason you should try coding before you start a bootcamp is, a lot of bootcamps have pre-work for you to do. Anyone in my bootcamp who didn’t do the pre-work was toast. They either dropped out or struggled through the bootcamp and are now not working in tech. This is a dirty little secret of bootcamps where you need to know a bit about coding before you start otherwise you won’t survive. You’ll always be behind.&lt;/p&gt;

&lt;p&gt;Now, if you’re always behind that means your peers who you are competing with for jobs will be ahead of you technically. Meaning finding that first job just got harder.&lt;/p&gt;

&lt;p&gt;So I’d recommend you try some free resources I’ve linked below to find out if you actually enjoy coding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can You Commit Financially?
&lt;/h3&gt;

&lt;p&gt;Damn, money was tight during my bootcamp and I’m saying this as someone who was a tight-arse during the bootcamp. I was rolling into class with packed peanut butter and jelly sandwiches, something I hadn’t done for years. Despite this, I still nearly ran out of money before I landed my first job. So you need to ask yourself can you commit financially.&lt;/p&gt;

&lt;p&gt;When you sign up to do a bootcamp, unless it’s part-time you’re probably not going to be working. So that $14K you are investing is actually the cost of the bootcamp plus the opportunity cost of the money you could be earning. In my case, my bootcamp actually cost me $80K because I was giving up $66K in money I could have earned in my job. Now, I’m betting that I will make it back over my career. But, it is definitely something to consider. Especially if you think you can learn and find a job in your spare time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**Real Cost of Bootcamp**

-Bootcamp: $14K
-Loss income: $66K
-Cost of living: $1500 per month

Total Cost = 14K + 66K + (1500 x 3 (per month)) = 84.5K

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

&lt;/div&gt;



&lt;p&gt;You also need to consider how you will pay your bills? The bootcamp cost $14K. What about all your other expenses that still exist while you’re doing the bootcamp, I mean a man’s gotta eat. There were a few people in my bootcamp who didn’t really factor this in and it added further stress to an already stressful time.&lt;/p&gt;

&lt;p&gt;Another thing to consider is that you might not get a job right away. I know it took me about 3 months until after my bootcamp to land a job (I moved cities at that time which complicated things). This was pretty common for about 2 thirds of my cohort who even got jobs. So your calculations should also factor in some post bootcamp buffer, you need a strategy for how you are going to survive a bit longer while you job hunt.&lt;/p&gt;

&lt;p&gt;So make sure you have those dollars in the bank to handle your bills before you sign up to do a bootcamp, otherwise, you’re going to have a bad time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mTT16XJ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/run529ud45n0jbhmtaqg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mTT16XJ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/run529ud45n0jbhmtaqg.jpeg" alt="south park badtime meme with text - if you do a bootcamp without enough savings you're gonna have a bad time" width="500" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you Have Time?
&lt;/h3&gt;

&lt;p&gt;This section might be better worded as do you have time and are you willing to put in the time.&lt;/p&gt;

&lt;p&gt;Like I’ve mentioned bootcamps are massive time investments, they aren’t just the 8 hours of lessons you have. They are all the other hours at night and on weekends that you need to be spending on getting yourself job-ready.&lt;/p&gt;

&lt;p&gt;So you need to consider this two ways.&lt;/p&gt;

&lt;p&gt;The first is do you actually have time. Do you have a partner like me who was understanding and knew that I would be fully immersed in this thing 90% of my waking time for the next 12 weeks? Do you have other commitments that you can’t ignore? Then you need to ask yourself. Honestly ask yourself, if you can give the time needed to be successful at your bootcamp. It takes a lot of sacrifice.&lt;/p&gt;

&lt;p&gt;The other way to consider this is are you willing to work 12+ hours a day and work on your weekends? I love my weekends, those mothers are sacred. But, during my bootcamp I knew I’d have to give them up. I was willing to get up bleary-eyed on a Saturday morning after a night crying over bugs in my code to do it all again. You have to ask yourself are you willing to do that also. Because during my bootcamp there was very little time for the things I liked. I didn’t play video games, I didn’t read non-coding-related things, I only managed 1-2 episodes of the Office a night. It was tough. Worth it, but tough.&lt;/p&gt;

&lt;p&gt;Now, not everyone will have to do what I did. Some of you will be able to get by on 8 hours, some on 10. But, even if the lessons click quickly for you, I’d still argue you need to be ready to dedicate a lot more time than you think to the bootcamp, because I’d argue (and from experience I know) 12 weeks just isn’t enough to make you a good developer. Therefore, the more work you put in the easier it will be to transition.&lt;/p&gt;

&lt;p&gt;Bootcamps are a sacrifice of your time, consider if your life will allow you to do that. If not, that is okay, there are other avenues for you to achieve your dream.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Jobs are Available in Your Local Area?
&lt;/h3&gt;

&lt;p&gt;This is probably less relevant in a remote post-covid world. But, it is still worth mentioning because I think some businesses are still hesitant to hire people outside of their local area. So the more businesses that could potentially hire you means more chance of getting hired.&lt;/p&gt;

&lt;p&gt;Therefore, you need to do some research into what jobs in software development are being advertised in your local area.&lt;/p&gt;

&lt;p&gt;Do some research by searching sites like Indeed and LinkedIn for jobs in your area. Use terms like ‘junior developer’, ‘entry-level developer’, and ‘associate developer’ to see how many results are in your area.&lt;/p&gt;

&lt;p&gt;When you’re looking at jobs, have a look at the languages they are using. If the languages are mostly in something you won’t be learning then consider if that will prevent you from finding work. Because, if your bootcamp teaches Ruby and Vue and there are only React and Python jobs in your area you might struggle to find a job.&lt;/p&gt;

&lt;p&gt;Think of it this way, if you were hiring someone who you know you’re going to have to train anyway, wouldn’t you want to make life easier by ensuring they have experience with the languages you use? It’s kind of like an electrician trying to get a job as a plumber. Yeah, they are in similar areas but they have a lot longer to go than another plumber.&lt;/p&gt;

&lt;p&gt;You also need to remember you won’t just be competing with people in your bootcamp, you’ll be up against community learners (I always thought the term self-learner is dumb, you didn’t just start teaching yourself. You used resources someone else made to learn...rant over) people with some experience and university graduates. So not many jobs might mean you’re going to have a harder time finding one.&lt;/p&gt;

&lt;p&gt;It’s not impossible to get a job in another tech stack, but your chances of finding a job will probably increase if you know at least some of the potential employers' programming languages. So research what is available locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are Your Skills Already too Advanced for a Bootcamp?
&lt;/h3&gt;

&lt;p&gt;If you’ve been coding for a while. Especially if you have been coding with the tech stack that you’re going to be learning in the bootcamp. You might already be too advanced for the bootcamp.&lt;/p&gt;

&lt;p&gt;The quickest way to find this out is to apply for some developer jobs. You’ll need to know  &lt;a href="https://www.reddit.com/r/cscareerquestions/comments/1hyd2p/how_to_get_resume_past_automated_screening_process/"&gt;how to get past the automated resume readers&lt;/a&gt;. But, once people start looking at your resume the market will give you some indication of if you’re employable or not.&lt;/p&gt;

&lt;p&gt;If you find that you’re getting calls for interviews, and you’re passing the tech tests. Then you probably don’t need to spend the money for a bootcamp. You just need to work on interviewing and solving tech tests until someone gives you your first break.&lt;/p&gt;

&lt;h3&gt;
  
  
  Considering all the Factors
&lt;/h3&gt;

&lt;p&gt;So those are the factors to consider when thinking if you should do a bootcamp. If I had to answer every single Reddit thread asking whether they should do I bootcamp with one answer I would say this.&lt;/p&gt;

&lt;p&gt;“If you enjoy coding, have enough money squirreled away, enough time, and feasible opportunities to find work then I’d 100% recommend you do a bootcamp.” If this sounds like you then read on to see my methods for determining if a bootcamp is any good.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Tell if a Bootcamp is Actually Good
&lt;/h2&gt;

&lt;p&gt;Alright, so you’ve decided a bootcamp is for you. Yay. That is great, you can stop asking Reddit if you should do one. Now, you need to figure out if the bootcamps you’re interested in are actually good.&lt;/p&gt;

&lt;p&gt;But, how do you do that?&lt;/p&gt;

&lt;p&gt;Well, below are some tips to help you do just that. Use these to get a feeling for if the bootcamp can actually deliver what they are promising on their landing page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t Read Reviews
&lt;/h3&gt;

&lt;p&gt;You’ve probably already read some reviews for the bootcamps in your area. But, the thing to remember with reviews is that they tend to be biased either to really positive or really negative takes. I don’t know about you but I’ve never left a review for a product in my life, especially not a product I was just satisfied with.&lt;/p&gt;

&lt;p&gt;In fact, I’d heard from other bootcamp alumni that some bootcamps make writing reviews a mandatory in-class exercise, which is very suss.&lt;/p&gt;

&lt;p&gt;So my advice would be to ditch reading reviews. Instead, follow the steps below.&lt;/p&gt;

&lt;p&gt;However, if reading reviews is your only option (it’s not) there is one trick I have up my sleeve and that is to search two other places.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Type into Google - site:reddit.com [bootcamp name], then read peoples threads.&lt;/li&gt;
&lt;li&gt;Go to &lt;a href="https://twitter.com/search-advanced"&gt;Twitter's advance search&lt;/a&gt; - then enter the bootcamp name in the “Words” sections “exact phrase” box and down under the engagement section in the “minimum replies” box enter “1”.Then hit the “Latest” tab'&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will help you get a sense of what people are saying about the Bootcamp and it is less likely to be coerced.&lt;/p&gt;

&lt;p&gt;However, scrape reviews and follow the steps below to find out if the bootcamp is actually worth the money.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Do Some LinkedIn Research
&lt;/h3&gt;

&lt;p&gt;LinkedIn is such a great place to learn more about the bootcamps you are considering. You can see all kinds of things, things that the bootcamp might not tell you or that they want to hide with clever statistics (we’ll look at this in a little bit).&lt;/p&gt;

&lt;p&gt;Here are some things you should be researching on LinkedIn before you get going.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How many past alumni are actually working in the field the bootcamp was preparing them for.

&lt;ul&gt;
&lt;li&gt;You can do this by typing &lt;code&gt;“ ”&lt;/code&gt; into the search bar → clicking the people filter → all filters → school → typing the school you are interested in → then filter for your area.&lt;/li&gt;
&lt;li&gt;You can then click into people's profiles and see where they are actually working.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How many past alumni are hired as mentors/students.&lt;/li&gt;
&lt;li&gt;Where alumni tend to get work after the bootcamp.&lt;/li&gt;
&lt;li&gt;How long it took them to get the job.

&lt;ul&gt;
&lt;li&gt;Check this against the time the bootcamp finished and the time they listed as when they started their job.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will give you a good indication of what is actually happening with past students and not what the bootcamp is telling you happens. However, the next step is the most important one you can take to help you determine if the bootcamp is actually good.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Reach out to past alumni
&lt;/h3&gt;

&lt;p&gt;This is the single best thing you can do to find out if a bootcamp is good. Now, that you’ve done some LinkedIn research it’s time to reach out to some of the alumni. Preferably you want to speak to recent graduates.&lt;/p&gt;

&lt;p&gt;Why is this the best thing you can do? Because those alumni are the best way to find out what to expect from the bootcamp. You get to ask them questions that let you dig deeper than reviews and LinkedIn research.&lt;/p&gt;

&lt;p&gt;Now, you might be saying why would they respond to you? They will respond because they’ve been in your shoes and most people want to help. Not everyone will reply but if you follow the steps below you’ll have a good chance of getting some replies.&lt;/p&gt;

&lt;p&gt;To reach out to alumni, you can message them on LinkedIn and ask if they have time to chat about their experience at the bootcamp.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro-Tip:&lt;/strong&gt;&lt;br&gt;
Go to their portfolio website since most bootcamps make you make one, once there just grab their email or use their contact form to reach out to them. You're more likely to get a reply this way.&lt;/p&gt;

&lt;p&gt;Here is the template I used to reach out to them. Using this I got about an 80% reply rate to all the emails I sent out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hi X,

I found your details from your website after I saw
you were an alumni of [bootcamp_name]. I really
liked [say something nice about their portfolio
they worked hard on it].

I was wondering if I could ask you a few questions
about your experience with the bootcamp? As I am
considering it, but I wanted to speak to a few
alumni before I commit.

I can shoot the questions to you over email if
that is easiest.

Let me know if you have time and I can send 2-3
questions your way, or book a quick 15 minute chat.

Cheers,

[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If they agree to a face-to-face chat, make sure in your follow-up email you make it as easy as possible for them to chat with you. What I mean by this is offer them a few options for times to meet, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;That is amazing I really appreciate it.

Are you free on these days Wednesday between 5pm-8pm
and Thursday Between 10am-8pm.

If you are just let me know the time and send you a
calendar invite for a quick 15 minute Zoom call.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then all you need to do is actually ask them for their opinions of the bootcamp. Here are the questions I asked.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What did you enjoy about the bootcamp?&lt;/li&gt;
&lt;li&gt;Were there any students you know that didn't enjoy it, why do you think they didn't enjoy it?&lt;/li&gt;
&lt;li&gt;Were the teachers what you expected?&lt;/li&gt;
&lt;li&gt;Knowing what you know now about the bootcamp, would you do it again?&lt;/li&gt;
&lt;li&gt;How hard was it to find a job after the bootcamp? How many people in your cohort didn’t find jobs?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feel free to ask other questions, the point is you are trying to get real authentic answers where the person isn’t incentivized by sales to give you only positive answers.&lt;/p&gt;

&lt;p&gt;Also, try to keep in touch with this person if you decide to do the bootcamp. Update them on your progress, who knows they might be able to help you get a job at the end if you show initiative.&lt;/p&gt;

&lt;p&gt;If you’re still not sure after you’ve reached out to alumni, there are a few other things you can check to help you decide if you should do a bootcamp.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Check How Old the Bootcamp is
&lt;/h3&gt;

&lt;p&gt;I don’t think the age of a bootcamp is necessarily an indicator as to whether a bootcamp is good or not. Bootcamps are essentially the people teaching it. If a teacher leaves, then you’re going to have a very different experience from the last cohort.&lt;/p&gt;

&lt;p&gt;However, there are a few things that age can help you understand when trying to determine whether the bootcamp is good or bad.&lt;/p&gt;

&lt;p&gt;Older bootcamps will have employment statistics, most advertise them but others will provide them if you ask for them. If they don’t provide them this is a red flag.&lt;/p&gt;

&lt;p&gt;You can also check these statistics against some of the LinkedIn research you did, just a quick eye test will do the trick.&lt;/p&gt;

&lt;p&gt;Older bootcamps will also have alumni, so make sure you take advantage of the step above.&lt;/p&gt;

&lt;p&gt;For newer bootcamps, you are going to be taking a risk if this is their first run.&lt;/p&gt;

&lt;p&gt;A few things you can do to reduce that risk are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Look up the teachers on LinkedIn and Twitter and have a look at their experience and what they tweet about.&lt;/li&gt;
&lt;li&gt;Ask the bootcamp a lot of questions, things like how they plan to support you post-study, the structure of the course, etc. If they struggle to give answers this could show they aren’t prepared.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Don’t write off newer bootcamps, they all had to start at cohort 1. Sometimes it’s an advantage as their best marketing tool is you, so they will want to make your experience as good as possible so they can attract future students.&lt;/p&gt;

&lt;p&gt;Just recognize the risk and decide if you are willing to take that risk. It’s not for everyone.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Talk to the Bootcamp
&lt;/h3&gt;

&lt;p&gt;The last step and one you should 100% do is to talk to the bootcamp.&lt;/p&gt;

&lt;p&gt;If Coivd permits go talk to them on campus and meet them face to face. I find face to face I get a better gut feel for if something is right for me.&lt;/p&gt;

&lt;p&gt;When you meet them, ask them all the questions you have following on from your meetings with alumni. It is okay to say things like “past alumni I spoke to said (don’t give them their name), they didn’t think you did x &amp;amp; y well. How are you planning on fixing it?”.&lt;/p&gt;

&lt;p&gt;This step is about clarifying things and feeling out the place. You want to suss out if you like the vibe, are these people you want to spend the next 12 weeks with. Because you’ll be spending a lot of time with them and personally I like to spend my time with people I like.&lt;/p&gt;

&lt;p&gt;I sort of used this step to get a feel for fluffy things like the vibe and culture. It was so I could get a gut feel if it felt right.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do Your Research
&lt;/h3&gt;

&lt;p&gt;At the end of the day, the best way to decide if a bootcamp is worth your money is to do the research. You have to go beyond the reviews and try and speak to real people.&lt;/p&gt;

&lt;p&gt;There is no full-proof way to ensure that the bootcamp will deliver what it says on the box. As I mentioned so much depends on the teaching staff. However, if you do the research you’ll empower yourself to make the best decision from the options you have.&lt;/p&gt;

&lt;p&gt;If you take one thing away from this section, please make it the part where you reach out to alumni. I spoke to multiple alumni at 3 different bootcamps and it made my decision so much easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Bootcamps Won’t Tell You the Full Truth About
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Student Employment Rates
&lt;/h3&gt;

&lt;p&gt;Bootcamps manipulate these and boost them in sneaky ways. So, make sure you read the fine print. Here are some ways they do it, you should watch out for these.&lt;/p&gt;

&lt;p&gt;Some bootcamps will have fine print that shows the employment rate of employees who found a job within 12 months. 12 months is a long time, can you be jobless for 12 months, or are you dedicated enough to learn for 12 months?&lt;/p&gt;

&lt;p&gt;Another misleading way a bootcamp might manipulate these figures is they hire their former students. They hire them to be mentors or teachers assistants and pay them minimum wage. This way they can include them in the employed column.&lt;/p&gt;

&lt;p&gt;Also watch out for bootcamps that classify students that got jobs in non-course related fields, or doing very low-level tech things like tech support, “have you tried turning it off and on again” type stuff.&lt;/p&gt;

&lt;p&gt;So make sure you don’t just look at the big number. Dig into those numbers and check the fine print. Bootcamps can be really sneaky.&lt;/p&gt;

&lt;h3&gt;
  
  
  Employers Don’t Really Care if you Went to a Bootcamp
&lt;/h3&gt;

&lt;p&gt;Yep, you read that right. The fact that you went to a bootcamp doesn’t really carry much weight.&lt;/p&gt;

&lt;p&gt;What employers actually want are tangible skills. Skills like, can you really code in the languages your resumes say you can. They’ll determine this from your projects and things like coding tests.&lt;/p&gt;

&lt;p&gt;The bootcamp helps you actually get better at those languages and pushes you to make projects. But, it won’t mean much at the end of the day.&lt;/p&gt;

&lt;p&gt;So if you are going to a bootcamp because you think their cute little certificate will get you a job, you’re going to have a bad time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TqyhL6ey--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbpvbi0lye7p29cxd9xx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TqyhL6ey--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbpvbi0lye7p29cxd9xx.jpeg" alt="condescending wonka meme with text - oh you have a bootcamp certificate no need to do the coding test then" width="666" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Time it Takes to get a Job and Salary Expectations
&lt;/h3&gt;

&lt;p&gt;Most people don’t just go from the bootcamp straight into a job. Many will finish the bootcamp and then look for jobs.&lt;/p&gt;

&lt;p&gt;So, don’t get swept up in the claims a bootcamp makes. We talked about bootcamp hiring stats, so recognize it can take time to find a job. It can take people anywhere from 0-12 months post the bootcamp to find their first developer job. Some may never find a job.&lt;/p&gt;

&lt;p&gt;Also, temper your salary expectations. Lot’s has changed since bootcamps started and people were getting paid $100K straight out of a bootcamp. Bootcamps like to show off the big salaries people get, but they might have been from years ago. Check the data on that.&lt;/p&gt;

&lt;p&gt;I’d argue the average salaries are even bogus. Be skeptical, are you going to share you got $50K after you finished your bootcamp if someone else got $100K. Would you share it at all? If the sample is 1, it’s not worth much.&lt;/p&gt;

&lt;p&gt;Salary can be really dependent on the location of the bootcamp and therefore the cost of living. If the Bootcamp is in San Fransisco grads will earn more but their cost of living is higher than say someone living in Ohio.&lt;/p&gt;

&lt;p&gt;I think in this situation it is better to be pessimistic, rather than optimistic. It is also why it is really important to speak to alumni of bootcamps, they can give you some hard truths.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning is Surface Level
&lt;/h3&gt;

&lt;p&gt;A bootcamp is too short of a time frame for you to truly understand the concepts. It is going to take you a while to understand how things really work.&lt;/p&gt;

&lt;p&gt;A bootcamp will pitch to you that you will know x, y, and z technologies by the end of the bootcamp. But, in reality, you’ll know just enough to be employed. You’re going to have to work on the rest when you start working. This can feel really uncomfortable, you’ll probably feel like an imposter.&lt;/p&gt;

&lt;p&gt;However, coding is almost a never-ending pursuit of learning. Even the Seniors in my team are constantly remarking how they learned something new. So it’s okay that the learning is just surface level, you just have to be prepared to keep learning after the bootcamp is finished.&lt;/p&gt;

&lt;p&gt;Are you okay with learning continually because if not the bootcamp is not like an accounting degree where you’ll have most of your learning done in the degree. You need to be ready to continue learning at a rapid pace when you first start your new job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment Structure
&lt;/h3&gt;

&lt;p&gt;It’s important to know that not all bootcamps have the same payment structure. The payment structure I want to point out is “Income Share Agreements” or ISAs, which let you attend a bootcamp for low upfront costs.&lt;/p&gt;

&lt;p&gt;Now, I think ISAs get a pretty harsh wrap. At the end of the day, an ISA is an agreement between two adults. It’s up to the individual to read the fine print. And, for some, it is their only option.&lt;/p&gt;

&lt;p&gt;That said, they can still be pretty confusing so let’s go through them.&lt;/p&gt;

&lt;p&gt;ISA’s are in most cases agreements that don’t require you to pay much upfront. Instead, you pay it back once you have a job and that money is automatically taken from your paycheck. The amount taken is a percentage of your salary and it comes out every month for a set period.&lt;/p&gt;

&lt;p&gt;This is an important point to note. The amount is over a set period, usually years. It doesn’t stop once you hit a certain amount.&lt;/p&gt;

&lt;p&gt;So say your agreement is over 3 years at 14% and your first job is $60,000 per year. It would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;($60,000 * 14% = $8400) * 3 years = $25,200 total paid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a lot of money you are paying. Double. And some, compared to a $14K bootcamp. Also, if your pay goes up during that time, it will cost you more.&lt;/p&gt;

&lt;p&gt;Now some ISA’s have a cap. A max amount you can pay.&lt;/p&gt;

&lt;p&gt;At the end of the day, it’s up to you to do your research on potential ISAs. You need to factor in if you can live on your salary, minus the percentage from the ISA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Doing a Bootcamp
&lt;/h2&gt;

&lt;p&gt;There are a lot of benefits to doing a bootcamp aside from learning how to code with a teacher. I wanted to detail these because I think sometimes the “yOu can lEarN It fOr fReE” crowd can neglect these intangibles. After all, we’re not all superhuman discipline machines like them.&lt;/p&gt;

&lt;h3&gt;
  
  
  You Put Your Money Where Your Mouth is
&lt;/h3&gt;

&lt;p&gt;You spent $14K on the program, I don’t know about you but if I spend that sort of money I’m damn well going to show up every day.&lt;/p&gt;

&lt;p&gt;When you do a bootcamp you have in-person hours, where you come in and learn and work. Even if you just do the 8 hours of class time, that is 40 hours per week that you are dedicating to learning to code.&lt;/p&gt;

&lt;p&gt;I found it very difficult to find 10-15 hours a week &lt;a href="https://www.peterlunch.com/blog/why-im-learning-to-code-and-maybe-you-should-too"&gt;when I was learning from home.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think this happens for a few reasons.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Friends &amp;amp; Family understand that you are all in and that this is a temporary change for you. Therefore, they are more likely to be less demanding of your time.&lt;/li&gt;
&lt;li&gt;You won’t have unexpected things at work come up that disrupt your time and force you to miss hours you could be coding.&lt;/li&gt;
&lt;li&gt;You have peer pressure to do that work and show out.&lt;/li&gt;
&lt;li&gt;You paid all that money, you’re less likely to say you’re too tired to code or that you’ll do double time on the weekends.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Money is a great motivator. It can really light a fire under you, I know it certainly did for me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accelerates Career Change
&lt;/h3&gt;

&lt;p&gt;Bootcamps will speed up the process of changing careers. They have to by the very nature of you being all in.&lt;/p&gt;

&lt;p&gt;When you’re in a bootcamp, you are coding every day and flying through topics. Even though the learning is surface level, it is very unlikely you would achieve the same results over the same period if you were learning part-time.&lt;/p&gt;

&lt;p&gt;Bootcamps are also structured. This means you don’t waste time thinking about what project you should build and what technologies you should use you are told all of this. Not having to spend energy on this stuff, means you get to spend all your energy on learning.&lt;/p&gt;

&lt;p&gt;You won’t get that feeling of okay I finished this thing, what should I do next. You finish one thing and then are pushed right into the next thing during your bootcamp.&lt;/p&gt;

&lt;p&gt;This acceleration will also force you to learn how you learn best. This skill will be very valuable when you get into your first job. You’re going to need to use it time and time again, as you face new challenges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access To People Who Code Better Than You
&lt;/h3&gt;

&lt;p&gt;You’ll get stuck all the time when you are learning to code. I still get stuck at work and need to ask my senior for help, even my seniors get stuck and need to ask for help. It’s all part of the game.&lt;/p&gt;

&lt;p&gt;Previously when I was learning on my own. I would post in forums for help. When I did this I might get an answer, I might not. But, even when I got an answer, it sometimes would unstick that problem only for me to find another problem straight away. This, often led to frustration which would lead to me putting the keyboard away.&lt;/p&gt;

&lt;p&gt;A bootcamp gives you near-instant access to someone more experienced than yourself who can help you get unstuck. The same is not often true for other forms of learning.&lt;/p&gt;

&lt;p&gt;I can’t tell you how beneficial it is to actually see someone debug your code. Watching the process someone goes through and learning to imitate that skill is immensely valuable. I’d read about how to debug and solve problems, but it never really hit home until I saw someone do it. Maybe you can learn that async or by yourself but it’s nice to be able to do it super quickly, to save that time for learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make Friends To Share the Journey
&lt;/h3&gt;

&lt;p&gt;The best part of my bootcamp was the people I met and struggled with every day on our way to changing our lives. It is actually the biggest reason I would recommend you do a bootcamp if you want to learn to code.&lt;/p&gt;

&lt;p&gt;You can learn to code for free, by yourself, or by being part of communities. But, I’d tried that and it is just not the same. You will be on different schedules and different stages of your journey. In a bootcamp you’re all essentially at the same point, learning the same stuff and solving the same challenges at the same time.&lt;/p&gt;

&lt;p&gt;I can’t tell you how good it feels to turn to your classmate and ask them how they are going, only to hear that they are struggling with the exact same thing you’re struggling with. Not just so I can feel better about myself but, so you can team up and figure out how to solve it together.&lt;/p&gt;

&lt;p&gt;During the bootcamp you’re like this little army, fighting against the tide of information coming your way. You build super-strong connections from showing up and fighting side by side every day.&lt;/p&gt;

&lt;p&gt;Post bootcamp, the battle isn’t over, and while you all compete for jobs. There is a lot of camaraderie, helping each other through the process.&lt;/p&gt;

&lt;p&gt;Once you’ve landed that first job, you already have a network of developers that are not just within your own company. This means down the track if you want to move jobs or lose your job, you have access to people who know that you fought beside them in the bootcamp and that you could do it again in their organization.&lt;/p&gt;

&lt;p&gt;I tried the learn at home, community taught path and I just couldn’t do it. A big part looking back is that I didn’t have people I could lean on, who could understand what I was going through and I didn’t have any friends who were developers who could help me learn when I got stuck.&lt;/p&gt;

&lt;p&gt;The friendships I made are for life, and I look back fondly on those amazing relationships I built. That is the best part of a bootcamp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You do A Bootcamp in 2022
&lt;/h2&gt;

&lt;p&gt;Now, with all of that information out of the way it is time for my recommendation as to whether you should do a bootcamp in 2022.&lt;/p&gt;

&lt;p&gt;The answer is...&lt;strong&gt;it depends.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know you’re saying WTF! Just tell me. I need someone to make the decision for me. But, it really does just depend on you, the individual.&lt;/p&gt;

&lt;p&gt;Are you the type of person who can dedicate 15 hours of your personal time to learning to code and you have the discipline to stick to it and no potential hurdles? Then you can probably get a job without attending a bootcamp.&lt;/p&gt;

&lt;p&gt;However, if you’re like me and had a highly demanding job and can’t commit to learning with good repetition each week then you might want to consider a bootcamp. If, you can afford it and actually like coding.&lt;/p&gt;

&lt;p&gt;Just make sure you do your research and if I can recommend one thing in particular it is that you speak to past alumni of your bootcamp. It made my decision a lot easier by speaking to real people and getting their private opinions.&lt;/p&gt;

&lt;p&gt;Personally, if you can afford it, know you like coding, and can see yourself doing it for a long time then I’d go for it.&lt;/p&gt;

&lt;p&gt;I constantly think back fondly on my time in my bootcamp. I’ve made amazing friends for life who I still keep in regular contact with even though I’ve moved cities. The bootcamp was such an intense experience and going through that struggle with others really helps you become quite connected. That human connection was enough to justify the expense to me as those experiences were priceless.&lt;/p&gt;

&lt;p&gt;If you made it all the way to the end. Thank you so much, receive some hot takes by following me on &lt;a href="https://twitter.com/thelynchpinau"&gt;Twitter&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>career</category>
    </item>
    <item>
      <title>Beginners Guide to Using mdx-bundler With Your Next.js Blog</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Wed, 15 Dec 2021 02:50:37 +0000</pubDate>
      <link>https://dev.to/peterlunch/beginners-guide-to-using-mdx-bundler-with-your-nextjs-blog-9k2</link>
      <guid>https://dev.to/peterlunch/beginners-guide-to-using-mdx-bundler-with-your-nextjs-blog-9k2</guid>
      <description>&lt;p&gt;When I was building this blog, I knew I wanted a lot of customization (I'm a junior dev who loves customization). In order to get maximum customization I found out I could use &lt;a href="https://mdxjs.com/"&gt;MDX&lt;/a&gt; for my blog posts.&lt;/p&gt;

&lt;p&gt;MDX is an extension on Markdown which, lets you import custom React components into your blog posts. To use MDX with Next.js you need to use a separate package. There are a few choices with &lt;a href="https://github.com/hashicorp/next-mdx-remote"&gt;MDX-remote&lt;/a&gt; being a popular one, but it has some drawbacks. For that reason, I chose to use mdx-bundler.&lt;/p&gt;

&lt;p&gt;What mdx-bundler allows you to do is bundle React components into your blog posts. I use it for reusable custom components, things like &lt;a href="https://www.peterlunch.com/snippets/next-image-styling"&gt;image styling&lt;/a&gt;, the code blocks you see in my posts and, the anchor tags.&lt;/p&gt;

&lt;p&gt;When I was setting mdx-bundler up I had just finished my Bootcamp and I didn't know what I was doing (I still don't ha). Meaning I ran into a lot of hurdles and got quite frustrated. So, now that I have it "working" I want to help others get it working on their Next.js blogs because it really is a joy to work with.&lt;/p&gt;

&lt;p&gt;This post aims to do just that by breaking down how to use mdx-bundler with Next.js. So let's get into it, starting at step 1, installation.&lt;/p&gt;

&lt;p&gt;This post aims to do just that by breaking down how to use mdx-bundler with Next.js, if you want to know how to style your MDX codeblocks you can &lt;a href="https://www.peterlunch.com/blog/prism-react-render-nextjs"&gt;see my post here&lt;/a&gt;. So let's get into it, starting at step 1, installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Installation is pretty straight forward and to be honest you can follow the instructions at the official &lt;a href="https://github.com/kentcdodds/mdx-bundler#installation"&gt;GitHub repo&lt;/a&gt;. But, for the sake of not forcing you to switch tabs let's go through it below.&lt;br&gt;
&lt;/p&gt;

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

// OR

yarn add mdx-bundler esbuild
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep, it is that simple. Now with that out of the way, it's time to unleash the power of mdx-bundler on your Next.js project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Mdx-Bundler to Your Data Fetching Functions
&lt;/h2&gt;

&lt;p&gt;Alright, you have mdx-bundler in your blogs packages. Now, we need to integrate it into our data fetching functions. This post assumes you already have a data fetching utility function added to your Next.js project. If you don't, not to worry you can follow the &lt;a href="url="&gt;helpful tutorial&lt;/a&gt; from Next.js that will help you get it set up. I followed this guide when setting my blog up so the code below should be mostly the same, except for a few different function names.&lt;/p&gt;

&lt;p&gt;If you followed the Next.js guide then you should have a utility that finds your blog posts and the metadata (frontmatter) that comes with it. Below is what this utility might look like (the functions have been shortened as they match the Next.js tutorial).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;matter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray-matter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bundleMDX&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mdx-bundler&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;blogDirectory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getBlogPostData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// same as nextjs tutorial&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getAllPostSlugs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// same as nextjs tutorial&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getPostData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&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;fullPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blogDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.mdx`&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;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;frontmatter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bundleMDX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;xdmOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remarkPlugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;remarkPlugins&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]),&lt;/span&gt; &lt;span class="nx"&gt;remarkGfm&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rehypePlugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;rehypePlugins&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]),&lt;/span&gt; &lt;span class="nx"&gt;rehypePrism&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;options&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;code&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above snippet, the magic happens in the &lt;code&gt;getPostData&lt;/code&gt; function. Here is where we utilize the &lt;code&gt;mdx-bundler&lt;/code&gt; package. There are a few things going on in this function and we are going to look into what is happening with the &lt;code&gt;mdx-bundler&lt;/code&gt; part.&lt;/p&gt;

&lt;p&gt;First, we import the &lt;code&gt;bundleMDX&lt;/code&gt; into the file, so that we can use it in the &lt;code&gt;getPostData&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Within the function, we are  each of your mdx files in the &lt;code&gt;blogDirectory&lt;/code&gt; using the &lt;code&gt;bundleMDX&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The destructured &lt;code&gt;code&lt;/code&gt; variable contains the contents of the mdx file things like your headings, images, links and, paragraphs. Importantly it also contains all the React components you have in the file.&lt;/p&gt;

&lt;p&gt;Finally, the destructured &lt;code&gt;frontmatter&lt;/code&gt; variable is the metadata for your post. It is the stuff at the top of a post that looks like the below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MDX"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2021-10-23T09:15:00-0400"&lt;/span&gt;
&lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MDX&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;beginners&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;guide"&lt;/span&gt;
&lt;span class="na"&gt;excerpt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;look&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;at&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;how&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;make&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;most&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;MDX&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;your&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;blog"&lt;/span&gt;
&lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coding"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to know more about metadata and why it is important for any developer's blog SEO check out this guide &lt;a href="https://ahrefs.com/blog/seo-meta-tags/"&gt;here&lt;/a&gt;. (I'm thinking about making a post on SEO for developers, &lt;a href="https://twitter.com/thelynchpinau"&gt;reach out to me&lt;/a&gt; if that is something you'd be interested in)&lt;/p&gt;

&lt;p&gt;The next part to note is where we are using the built-in xdm configuration, this allows you to add remark and rehype plugins. This can be really useful to style your code snippets or images. If you're interested you can see a list of available plugins &lt;a href="https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins"&gt;remark here&lt;/a&gt; and &lt;a href="https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins"&gt;rehype here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lastly, we return all the data we need to render our posts in a nice little object. Now, let's look at how to render our post and how to get the most of mdx-bundler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Mdx-bundler in Next.js Blog Posts
&lt;/h2&gt;

&lt;p&gt;Alright, so the first step we need in order to use mdx-bundler with our Next.js blog is done. Now let's see how to use it with our blog posts component so we can render them to the screen.&lt;/p&gt;

&lt;p&gt;If you followed the Next.js tutorial then you should have a file in your &lt;code&gt;posts&lt;/code&gt; directory called something like &lt;code&gt;[id]&lt;/code&gt; or &lt;code&gt;[slug]&lt;/code&gt; where you utilize the &lt;code&gt;getStaticPaths&lt;/code&gt; and &lt;code&gt;getStaticProps&lt;/code&gt; functions. On my blog I have called it &lt;code&gt;[slug].js&lt;/code&gt; since it makes semantic sense to me.&lt;/p&gt;

&lt;p&gt;In the&lt;code&gt;[slug].js&lt;/code&gt; file, we need to import a few things. The first is the &lt;code&gt;useMemo&lt;/code&gt; hook from the Reacts standard library. The second is &lt;code&gt;getMDXComponent&lt;/code&gt; from the mdx-bundler package. Now your &lt;code&gt;blogPost&lt;/code&gt; component should look similar to the below. We also need to import our data fetching functions, the ones you set up when following the Next.js tutorial.&lt;/p&gt;

&lt;p&gt;Next, we are going to send the &lt;code&gt;code&lt;/code&gt; data from our &lt;code&gt;getPostData&lt;/code&gt; function to our client so that we can render our mdx files. We do this by first passing the &lt;code&gt;code&lt;/code&gt; and &lt;code&gt;frontmatter&lt;/code&gt; props to our &lt;code&gt;BlogPost&lt;/code&gt; component (below).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;frontmatter&lt;/code&gt; prop will let us access our metadata by calling them like objects &lt;code&gt;frontmatter.title&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, we use the &lt;code&gt;code&lt;/code&gt; prop with the &lt;code&gt;getMDXComponent&lt;/code&gt; function. Here we use the &lt;code&gt;useMemo&lt;/code&gt; hook to prevent the component being created every time we render it which, really helps with performance. Now, our &lt;code&gt;BlogPost&lt;/code&gt; component should look like the below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;frontmatter&lt;/span&gt; &lt;span class="p"&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;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getMDXComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Component&lt;/code&gt; variable holds all the content of our blog post. We could finish here and render the post by calling &lt;code&gt;&amp;lt;Component /&amp;gt;&lt;/code&gt; within our &lt;code&gt;BlogPost&lt;/code&gt; component. Try it out to see how it renders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getMDXComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mdx-bundler/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getAllPostSlugs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPostData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../lib/utils/blogPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getPostData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&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="nx"&gt;postData&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="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&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;paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getAllPostSlugs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;frontmatter&lt;/span&gt; &lt;span class="p"&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;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getMDXComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&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;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you view the post with the correct slug, it will now render all the elements within the mdx file to the screen. That is all you need to get your Next.js project to work with &lt;code&gt;mdx-bundler&lt;/code&gt;. However, there is one more thing you can do that unleashes the full power of &lt;code&gt;mdx-bundler&lt;/code&gt;. Let's see what that is now.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Bundle Up Your Components With Mdx-Bundler and Next.js
&lt;/h2&gt;

&lt;p&gt;The absolute cherry on top of mdx-bundler that makes it a joy to work with is that you can "bundle" all of your reuseable components up to save you importing them in every mdx file.&lt;/p&gt;

&lt;p&gt;On my blog I have a few components that get used in every post, things like a &lt;a href="https://www.peterlunch.com/snippets/next-image-styling"&gt;custom styled next/image component&lt;/a&gt; or customer link components. It would be annoying and prone to human error for me to import them into every blog post. Thankfully mdx-bundler is here to save that day.&lt;/p&gt;

&lt;p&gt;To bundle up reusable components we can import them into our &lt;code&gt;[slug].js&lt;/code&gt;. Once we have those files imported, we can pass them as props to our Component element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PostImage&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components/PostImage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;InternalAnchor&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components/InternalAnchor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PostRecommender&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components/PostRecommender&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;frontmatter&lt;/span&gt; &lt;span class="p"&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;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getMDXComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&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;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;
              &lt;span class="nx"&gt;componets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
                &lt;span class="nx"&gt;PostImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;InternalAnchor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;PostRecommender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;}}&lt;/span&gt;
            &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can use these components when writing a post without even having to think about importing them.&lt;/p&gt;

&lt;p&gt;If you're still having trouble getting it working with Next.js you can reach out to me and I'll see how I can help.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>mdx</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Add Active Link Styles with Nextjs</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 14 Dec 2021 01:21:35 +0000</pubDate>
      <link>https://dev.to/peterlunch/how-to-add-active-link-styles-with-nextjs-50md</link>
      <guid>https://dev.to/peterlunch/how-to-add-active-link-styles-with-nextjs-50md</guid>
      <description>&lt;p&gt;As a frontend developer, I love to make things that are a delight to the user. Subtle little details that make the page pop or give the webpage personality, things that make other developers go "nice".&lt;/p&gt;

&lt;p&gt;So, I knew for my blog I wanted to have some active link styling on my navigation bar. The styling would not only give the page some character but would also improve the user experience.&lt;/p&gt;

&lt;p&gt;My blog is built using Nextjs and styled-component at the time of writing this. Which meant that it wasnt as simple as using the &lt;a href="https://www.peterlunch.com/blog/css-pseudo-elements"&gt;pseudo-class&lt;/a&gt; &lt;a href="https://www.peterlunch.com/snippets/remove-underline-from-link"&gt;:active&lt;/a&gt; and applying styles to it when the link was in the &lt;code&gt;:active&lt;/code&gt; state.&lt;/p&gt;

&lt;p&gt;The reason it wasn't straightforward is the Nextjs &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt; component doesn't know what the current route is, so it can never hold an active state.&lt;/p&gt;

&lt;p&gt;We can use the &lt;code&gt;next/router&lt;/code&gt; to solve this problem and that is how I made the links below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j_A9n5bu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13gvkmm5lhm8a3u5ok3k.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j_A9n5bu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13gvkmm5lhm8a3u5ok3k.gif" alt="svg animation styles of links on my blog" width="768" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to see how you give you links in Nextjs active styles then read on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Active Links with Nextjs
&lt;/h2&gt;

&lt;p&gt;Unfortunately, you cannot use the &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt; component from Nextjs by itself to add active styling. Therefore, you need to use the &lt;code&gt;useRouter&lt;/code&gt; hook which is part of the &lt;code&gt;next/router&lt;/code&gt; component. The &lt;code&gt;useRouter&lt;/code&gt; hook allows magically lets you access the &lt;code&gt;router&lt;/code&gt; object inside any component. This is how we are going to tell our application which page (route) the user is on, so we can then tell the link to apply active styles.&lt;/p&gt;

&lt;p&gt;The best solution in my opinion is to create a custom &lt;code&gt;&amp;lt;ActiveLink&amp;gt;&lt;/code&gt; component, link the one below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StyledLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
  color: &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&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;href&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ActiveLink&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="p"&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRouter&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;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StyledLink&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;currentPath&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asPath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;StyledLink&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;I like this solution for a few reasons, so let's go through it step by step.&lt;/p&gt;

&lt;p&gt;The first thing is we don't lose the benefits that come from the &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt; component because we use the &lt;code&gt;push&lt;/code&gt; method. This method handles the client-side transitions, meaning it is faster and doesn't trigger a full refresh. Which results in better performance and experience for the user. It also improves those tasty lighthouse scores.&lt;/p&gt;

&lt;p&gt;Next, we use the &lt;code&gt;asPath&lt;/code&gt; method. This method returns the path (or route) as shown in the browser address bar meaning we can conditionally check this against the href we pass as an argument to the &lt;code&gt;&amp;lt;ActiveLink&amp;gt;&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;The result is it prevents us from needing to hardcode the paths on a parent element and we can handle the active state at the link level. This allows you to use the &lt;code&gt;ActiveLink&lt;/code&gt; component in other components when every you want to apply &lt;code&gt;:active&lt;/code&gt; styling.&lt;/p&gt;

&lt;p&gt;To actually apply the active link styles, we pass the &lt;code&gt;StyledLink&lt;/code&gt; two key props. The first is the &lt;code&gt;href&lt;/code&gt;, the actual link we want next to route to. The second is &lt;code&gt;currentPath&lt;/code&gt;, which is the route that is currently in the browser.&lt;/p&gt;

&lt;p&gt;Now, using styled-components we can check if the &lt;code&gt;href&lt;/code&gt; and the &lt;code&gt;currentPath&lt;/code&gt; components match using a ternary. If they match we apply the active styles in this case &lt;code&gt;red&lt;/code&gt; font otherwise we apply &lt;code&gt;black&lt;/code&gt; font.&lt;/p&gt;

&lt;p&gt;Now you can detect if a link is active using Nextjs, you can start making your links delight users. If you're interested in how I made the links in my blog, sign up to my &lt;a href="https://www.peterlunch.com/newsletter"&gt;newsletter&lt;/a&gt; to be one of the first to get access to my article on SVG styling.&lt;/p&gt;

&lt;p&gt;If you're set on using the &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt; component &lt;a href="https://flaviocopes.com/nextjs-active-link/"&gt;Flavio has some solutions here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Make Better Blog Posts with Beautiful Syntax Highlighting in Nextjs with React-Prism-Render</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 30 Nov 2021 05:17:41 +0000</pubDate>
      <link>https://dev.to/peterlunch/make-your-nextjs-blogs-syntax-highlights-beautiful-53go</link>
      <guid>https://dev.to/peterlunch/make-your-nextjs-blogs-syntax-highlights-beautiful-53go</guid>
      <description>&lt;p&gt;As I was creating &lt;a href="https://peterlunch.com/" rel="noopener noreferrer"&gt;my blog&lt;/a&gt; with Next.js, I knew that I wanted to custom style my code blocks as coding was a large part of this blog, &lt;a href="https://www.peterlunch.com/notes" rel="noopener noreferrer"&gt;among other things&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have a Nextjs blog (or any React Framework blog) and want to create beautiful code blocks out of your MDX posts, then this post will show you how to do that using &lt;a href="https://github.com/FormidableLabs/prism-react-renderer" rel="noopener noreferrer"&gt;prism-react-renderer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, we will see how to convert plain MDX code blocks into stylish ones you'd see in a code editor like VSCode or atom. We are going to see how to do it using &lt;a href="https://styled-components.com" rel="noopener noreferrer"&gt;Styled Components&lt;/a&gt;, but it is also possible to do it with vanilla CSS.&lt;/p&gt;

&lt;p&gt;With that in mind, we need to first understand how MDX handles our code blocks, so we can then take that and make it stylish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding MDX code blocks
&lt;/h2&gt;

&lt;p&gt;Before we look at how to style our code blocks it is helpful to know how MDX formats them.&lt;/p&gt;

&lt;p&gt;When I talk about a code block in MDX, what I am talking about is the code you put between the triple back-ticks. &lt;/p&gt;

&lt;p&gt;The way MDX code blocks are formatted by the browser is they are wrapped in a &lt;code&gt;pre&lt;/code&gt; block and then each line is split into a &lt;code&gt;div&lt;/code&gt;. Then, each word or symbol is split into &lt;code&gt;spans&lt;/code&gt;. This is how the styler will apply individual styles to each word or symbol. It is important to understand this, because we will need to know which HTML elements to target if we want to style our code blocks with the correct syntax highlighting.&lt;/p&gt;

&lt;p&gt;Now, we understand how code is converted from markdown to HTML we are ready to create our component that will make our code blocks more stylish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the prism react render Syntax Highlighter Component
&lt;/h2&gt;

&lt;p&gt;The first step towards making our Nextjs blogs syntax highlights prettier is by utilizing the prism-react-render package.&lt;/p&gt;

&lt;p&gt;The first thing you need to do is install the package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; prism-react-renderer

&lt;span class="c"&gt;# yarn&lt;/span&gt;
yarn add prism-react-renderer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that out of the way, we can now build our syntax highlighting component &lt;code&gt;SyntaxHighlighter&lt;/code&gt;. The below code is a basic version of the component, copy the code below and we can go through what it is doing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Highlight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prism-react-renderer&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;SyntaxHighlighter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Highlight&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;code&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;className&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getLineProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTokenProps&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;style&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;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&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="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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nf"&gt;getLineProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&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;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nf"&gt;getTokenProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;})}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="p"&gt;))}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;))}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/pre&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Highlight&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Above, we start by importing two things from prism-react-renderer. The first is the &lt;code&gt;&amp;lt;Highlight /&amp;gt;&lt;/code&gt; component, it styles our code blocks in our MDX files. The second is the &lt;code&gt;{ defaultProps }&lt;/code&gt; object, this gets spread into the &lt;code&gt;Highlight&lt;/code&gt; component and will provide us with some default theming.&lt;/p&gt;

&lt;p&gt;Next, we create our &lt;code&gt;SyntaxHighlighter&lt;/code&gt; component and pass it a &lt;code&gt;children&lt;/code&gt; prop.&lt;/p&gt;

&lt;p&gt;Then, we declare the const &lt;code&gt;code&lt;/code&gt; and access the mdx code through our &lt;code&gt;children&lt;/code&gt; prop. It stores the MDX code block so we can then pass it into the &lt;code&gt;&amp;lt;Highlight /&amp;gt;&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Inside our &lt;code&gt;Highlight&lt;/code&gt; component we create an anonymous function with the props &lt;code&gt;className, style, tokens, getLineProps, getTokenProps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Within this function we target the &lt;code&gt;pre&lt;/code&gt; block. First, we &lt;code&gt;slice&lt;/code&gt; all lines and pass them into a &lt;code&gt;div&lt;/code&gt; element. Within the &lt;code&gt;div&lt;/code&gt; we are going to put each word and token into &lt;code&gt;span&lt;/code&gt; elements. Essentially, what happens here is the &lt;code&gt;getLineProps&lt;/code&gt; &amp;amp; &lt;code&gt;getTokenProps&lt;/code&gt; apply things like the styling to your syntax.&lt;/p&gt;

&lt;p&gt;If this was all we did our syntax highlights would now look like the below.&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%2Fuploads%2Farticles%2Fx22ps1vsv1dwidh6p2lg.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%2Fuploads%2Farticles%2Fx22ps1vsv1dwidh6p2lg.png" alt="unstyled code block"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason it looks this way is because &lt;code&gt;defaultProps&lt;/code&gt; uses the &lt;code&gt;duotoneDark&lt;/code&gt; theme as a default. We will see how to customize themes later.&lt;/p&gt;

&lt;p&gt;In the meantime, we can make it look much more stylish by picking out one of the &lt;a href="https://github.com/FormidableLabs/prism-react-renderer/tree/master/src/themes" rel="noopener noreferrer"&gt;many available themes&lt;/a&gt; react-prism-render has built in.&lt;/p&gt;

&lt;p&gt;As soon as you have a theme picked out, we can add it to our syntax highlights by importing the theme from &lt;code&gt;import theme from "prism-react-renderer/themes/themeName";&lt;/code&gt; and adding the theme prop to our &lt;code&gt;Highlight&lt;/code&gt; component's props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Highlight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prism-react-renderer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prism-react-renderer/themes/nightOwlLight&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;SyntaxHighlighter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Highlight&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now your syntax highlights are looking great. But, what if you want to style how the actual code block looks. What if you want to add things like the language or &lt;code&gt;border-radius&lt;/code&gt;? Well, let's see how to do that now with styled-components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling prism-react-render Code Blocks With Styled Components
&lt;/h3&gt;

&lt;p&gt;I'm going to use &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled-components&lt;/a&gt; to show you how to style your syntax highlights. This method can transfer to any other framework of styling, I just love using styled-components with Nextjs.&lt;/p&gt;

&lt;p&gt;To style the block surrounding the code, we need to target the &lt;code&gt;pre&lt;/code&gt; block which, we will call &lt;code&gt;PreBlock&lt;/code&gt;. Before we do that, we need to wrap the &lt;code&gt;pre&lt;/code&gt; block in a &lt;code&gt;div&lt;/code&gt; called &lt;code&gt;CodeBlockContainer&lt;/code&gt;. The &lt;code&gt;SyntaxHighlighter&lt;/code&gt; should now look like the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SyntaxHighlighter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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;//...&lt;/span&gt;

  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CodeBlockContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PreBlock&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&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="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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;getLineProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;getTokenProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PreBlock&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;CodeBlockContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;;

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

&lt;/div&gt;



&lt;p&gt;Looking at the changes above, we have renamed the &lt;code&gt;pre&lt;/code&gt; block and wrapped it in a &lt;code&gt;CodeBlockContainer&lt;/code&gt;, this allows us to add some styling to the code blocks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CodeBlockContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  position: relative;
  margin-top: 48px;
  margin-bottom: 60px;
  transition: all 200ms ease-in 0s;
`&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;PreBlock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="s2"&gt;`
  font-family: Arial, Helvetica, sans-serif;
  font-size: 18px;
  outline-offset: 2px;
  overflow-x: auto;
  margin-left: -32px;
  margin-right: -32px;
  padding: 32px;
  min-height: 50px;
  border: 1px solid rgba(230, 230, 230, 1);
  border-bottom-left-radius: 6px;
  border-bottom-right-radius: 6px;
  max-width: calc(100% + 64px);
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make your code snippets look like the below.&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%2Fuploads%2Farticles%2F1ui19qetgd6hkp86suh9.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%2Fuploads%2Farticles%2F1ui19qetgd6hkp86suh9.png" alt="semi formatted codeblock"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is all there is to styling your code block containers. The key is to target the &lt;code&gt;pre&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;On the whole, your syntax highlighting for your blog would already be looking great with just the above. But, we can take it up a level by adding things like the language or line highlights.&lt;/p&gt;

&lt;p&gt;So let's look at how to add the language to your react-prism-render syntax highlights.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Language to prism-react-render
&lt;/h3&gt;

&lt;p&gt;If you look back up at how code is written in markdown you will see a little &lt;code&gt;js&lt;/code&gt; next to the three backticks. That tells markdown that the language is JavaScript, you could use CSS or HTML if the code was written in those languages. In fact there is a &lt;a href="https://rdmd.readme.io/docs/code-blocks" rel="noopener noreferrer"&gt;whole list of languages&lt;/a&gt; you can use.&lt;/p&gt;

&lt;p&gt;To add language, we need to get the language value you have in your markdown and save it as a variable. Thankfully prism-react-render adds the language as a class name.&lt;/p&gt;

&lt;p&gt;Therefore we can access it through the children prop we pass our &lt;code&gt;SyntaxHighlighter&lt;/code&gt; component like so &lt;code&gt;children_.props.className?.replace("language-", "").trim();&lt;/code&gt;. You will need to save the value of this expression in a &lt;code&gt;const&lt;/code&gt; and then pass the &lt;code&gt;Highlighter&lt;/code&gt; a language prop.&lt;/p&gt;

&lt;p&gt;The prism-react-render syntax highlighter should now look like the below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SyntaxHighlighter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&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;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;language-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Highlight&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getLineProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTokenProps&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CodeSnippetContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PreBlock&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&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="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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;getLineProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;getTokenProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PreBlock&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CodeSnippetContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Highlight&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The last thing we need to do is render the &lt;code&gt;language&lt;/code&gt; variable. To do this we add a &lt;code&gt;LanguageHeadingContainer&lt;/code&gt; inside of the &lt;code&gt;CodeSnippetContainer&lt;/code&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;const&lt;/span&gt; &lt;span class="nx"&gt;Syntaxhighligher&lt;/span&gt; &lt;span class="c1"&gt;//...&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CodeSnippetContainer&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;language&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LanguageHeadingContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;LanguageHeadingContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PreBlock&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; //...

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

&lt;/div&gt;



&lt;p&gt;Above, we use short circuit logic to only render the &lt;code&gt;LanguageHeadingContainer&lt;/code&gt; if language is present in our markdown. Next, we need to add the styling for the &lt;code&gt;LanguageHeadingContainer&lt;/code&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;const&lt;/span&gt; &lt;span class="nx"&gt;CodeBlockWrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  border-top-left-radius: 0.25rem;
  border-top-right-radius: 0.25rem;
  border-width: 1px 1px 0px;
  border-style: solid;
  border-color: rgba(230, 230, 230, 1);
  background-color: rgb(231, 232, 235);
  padding: 0.75rem 1.25rem;
  margin-left: -32px;
  margin-right: -32px;
  font-family: font-family: Arial, Helvetica, sans-serif;;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 700;
  color: hsl(220deg, 23%, 5%);
  text-align: right;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, your syntax highlights should look like the below.&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%2Fuploads%2Farticles%2F1ll9y2ixz7nuu9zg15kk.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%2Fuploads%2Farticles%2F1ll9y2ixz7nuu9zg15kk.png" alt="fully formatted and styled code block"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to ensure we can use our &lt;code&gt;SyntaxHighlighter&lt;/code&gt; component with our blog. This component will work with other popular &lt;code&gt;MDX&lt;/code&gt; libraries but, I am going to show you how we do it with mdx-bundler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using prism-react-render With Mdx-bundler and Nextjs
&lt;/h2&gt;

&lt;p&gt;The next step is to ensure that MDX knows to render the component. This ensures you don't have to do something like the below every time you have some code in your MDX file you want to render.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SyntaxHighlight&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;components/syntaxHighlighter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SyntaxHighlighter&lt;/span&gt;
  &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;```

js
const codeBlock = () =&amp;gt; {
    // does something
}


```&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To manually avoid having to wrap each of your code blocks with the &lt;code&gt;SyntaxHighlighter&lt;/code&gt; we will automatically convert them using mdx-bundler.&lt;/p&gt;

&lt;p&gt;If you're not familiar with mdx-bundler I have a &lt;a href="https://www.peterlunch.com/blog/mdx-bundler-beginners" rel="noopener noreferrer"&gt;beginners guide to get you set up&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have MDX bundler set up with Nextjs all we need to do is add the &lt;code&gt;SyntaxHighlighter&lt;/code&gt; component to the mdx-bundler &lt;code&gt;&amp;lt;Component /&amp;gt;&lt;/code&gt; arguments. You will need to import the &lt;code&gt;SyntaxHighlighter&lt;/code&gt; component into your &lt;code&gt;[slug].js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// [slug].js&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SyntaxHighlighter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above, we have told mdx-bundler to use our &lt;code&gt;SyntaxHighligther&lt;/code&gt; component whenever it sees a &lt;code&gt;pre&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;That is all there is to using mdx-bundler with your prism-react-render syntax highlighter component. As a result, you now have stylish syntax highlighting for your code blocks. But, before you go there are two more awesome things I want to show you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Custom prism-react-render Themes
&lt;/h2&gt;

&lt;p&gt;One of the best parts about using prism-react-render is you can create your own themes. The benefit is you can have a theme that matches your website's design. Let's look at how to create prism-react-render themes now.&lt;/p&gt;

&lt;p&gt;Making your own custom theme is similar to how you would make a VSCode theme. So to build your own theme you need to follow a JSON-based format like the below.&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;var&lt;/span&gt; &lt;span class="nx"&gt;myCustomTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#d6deeb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#011627&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;var(--font-family-syntax)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;16px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;styles&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="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;changed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(162, 191, 252)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;italic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deleted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgba(239, 83, 80, 0.56)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;italic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inserted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;attr-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(173, 219, 103)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;italic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;comment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(99, 119, 119)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;italic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(173, 219, 103)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;variable&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(214, 222, 235)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(247, 140, 108)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;builtin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;char&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;constant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(130, 170, 255)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// This was manually added after the auto-generation&lt;/span&gt;
      &lt;span class="c1"&gt;// so that punctuations are not italicised&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;punctuation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(199, 146, 234)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doctype&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(199, 146, 234)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fontStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;italic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(255, 203, 139)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;operator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keyword&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(127, 219, 202)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(255, 88, 116)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;property&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(128, 203, 196)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;namespace&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(178, 204, 214)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;myCustomTheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All you need to do is copy the above code template and paste it into a &lt;code&gt;mycustomTheme.js&lt;/code&gt; file that you can then import into the &lt;code&gt;SyntaxHighlighter&lt;/code&gt; component. Once you've imported it, you just need to pass &lt;code&gt;myCustomTheme&lt;/code&gt; as an argument in the &lt;code&gt;Highligther's&lt;/code&gt; theme prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Highlight&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;myCustomTheme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all there is to it. You can change the colors and other values as you want to make your many prism-react-render themes.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to build an effective popup that will help get you hired</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 25 May 2021 20:46:17 +0000</pubDate>
      <link>https://dev.to/peterlunch/how-to-build-an-effective-popup-that-will-help-get-you-hired-59p8</link>
      <guid>https://dev.to/peterlunch/how-to-build-an-effective-popup-that-will-help-get-you-hired-59p8</guid>
      <description>&lt;p&gt;As users, popups suck. Most of us never click on them and likely leave the page when we see them. &lt;/p&gt;

&lt;p&gt;But, they work. They convert users to your goal better than most other techniques. In fact on my &lt;a href="https://www.peterlynch.dev/" rel="noopener noreferrer"&gt;developer portfolio&lt;/a&gt;, resume downloads went from 0 to 10 within the first week of implementing an exit intent modal. &lt;/p&gt;

&lt;p&gt;As you know, the job market is competitive. I've recently &lt;a href="https://peterlunch.com/why-im-learning-to-code-and-maybe-you-should-too/" rel="noopener noreferrer"&gt;just transitioned careers&lt;/a&gt; and I know it can feel like no one is even looking at your resume. That's why I've created this tutorial, to help you get your resume into the hands of a real person. It also has the added bonus of showing the person that you know how to make popups that convert.&lt;/p&gt;

&lt;p&gt;In this post we will learn how to build an on exit intent JavaScript modal just like the one below. If you've been following me you might notice I like to make gaming inspired web elements &lt;a href="https://peterlunch.com/how-to-create-responsive-gaming-style-navbar/" rel="noopener noreferrer"&gt;like my SNES controller nav bar&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;But first let's quickly understand what an exit intent modal is. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are exit intent modals (popups)?
&lt;/h2&gt;

&lt;p&gt;An exit intent modal is a type of popup, that detects through JavaScript when a user is about to leave the webpage. It then displays a popup box. Normally, this popup is triggered by a JavaScript event like the users mouse moving off the document or window onto the address bar or off the browser entirely. &lt;/p&gt;

&lt;p&gt;Generally exit intent modals are in your face and can be quite annoying. We will make sure ours is less disruptive to the user and more of a delight for the user to stumble upon. We are also going to make sure they only see it once. Because, there is nothing more annoying than seeing the same modal 10 times. &lt;/p&gt;

&lt;p&gt;So let's get into the step by step tutorial for making this exit intent modal with HTML, CSS and JavaScript.  &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Project Setup
&lt;/h2&gt;

&lt;p&gt;I have setup a GitHub repo with all the start files you are going to need to get this project up and running, fork the project &lt;a href="https://github.com/pin0S/zelda-meme-modal" rel="noopener noreferrer"&gt;here&lt;/a&gt; to get started.&lt;/p&gt;

&lt;p&gt;To begin with let’s understand what is happening with the HTML for this project.&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;body&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!--modal--&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"onExitModal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Modal content --&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;"modalContent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &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;"close"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;times;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/span&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;"messageContainer fade-in"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modalMessage"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;it's &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;dangerous &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;to &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;go &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;alone! &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;take &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;this.&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"iconContainer"&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;"/assets/flame.png"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flame image"&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;"/assets/oldman.svg"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"image"&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;"/assets/flame.png"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flame 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;"resumeContainer"&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;id=&lt;/span&gt;&lt;span class="s"&gt;"sword"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/assets/sword.jpg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"resume"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;My Resume&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;On line 3 we have created the container for our modal and given it the &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;onExitModal&lt;/code&gt;, this is important as we are going to target it with JavaScript later on.&lt;/p&gt;

&lt;p&gt;Next we then create a container for our modal content. The modal &lt;br&gt;
content container is separated into three child containers for our &lt;br&gt;
message, icons and then for our resume. The key thing to note here is &lt;br&gt;
the message is split word by word using &lt;code&gt;span&lt;/code&gt; elements. This will allow us to animate each word individually with CSS.&lt;/p&gt;

&lt;p&gt;Finally, the first &lt;code&gt;span&lt;/code&gt; element is using an &lt;code&gt;x&lt;/code&gt; symbol so that the user can easily and intuitively close the modal, implementing this will require some JavaScript.&lt;/p&gt;

&lt;p&gt;With just the HTML your modal should look something like the below.&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%2Fuploads%2Farticles%2Fd8numzmjino0797cdo7z.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%2Fuploads%2Farticles%2Fd8numzmjino0797cdo7z.png" alt="all images and text for modal in html"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s not pretty, and it is not what we want. As you know, we want the modal hidden on the page until the user performed the exit intent action. Therefore, we need to implement some CSS to hide the modal. Let’s look at how to do that now.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Adding the CSS
&lt;/h2&gt;

&lt;p&gt;The CSS for this project is split into three key parts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The functional CSS&lt;/li&gt;
&lt;li&gt;The Styling CSS&lt;/li&gt;
&lt;li&gt;Animations &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The functional CSS is making the modal hidden and positioning it on the page so it can appear when you implement the exit intent modals JavaScript. The styling is making it look pretty and the animation is to make the popup pop (pun intended) and to give it a video game feel.&lt;/p&gt;
&lt;h3&gt;
  
  
  The functional CSS
&lt;/h3&gt;

&lt;p&gt;The first thing we need to do is ensure the modal is hidden from the user. Let’s implement the styling for the onExitModal now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#onExitModal&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="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Hide the modal */&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Keep the modal in place */&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Sit on top of the page */&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;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Make the modal full width */&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Make the modal full height */&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Enable scroll if needed for different device sizes */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* Fallback color */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go through the code line by line to understand what is happening.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;display: none&lt;/code&gt; is ensuring that the modal is hidden by default from the user. Next, we set the position of the modal to fixed (&lt;a href="https://peterlunch.com/understanding-the-css-position-property/" rel="noopener noreferrer"&gt;read this guide to understand positioning&lt;/a&gt;) this keeps the modal on the same place on the page even if the user scrolls up and down. The last thing to take notice of is that we set the &lt;code&gt;z-index&lt;/code&gt; to 99 this ensures that it will appear in front of all other elements on the page.&lt;/p&gt;

&lt;p&gt;The modal will now be hidden from the users view. In due time we will implement the exit intent modals JavaScript code. But, first we need to style the rest of the modal so it looks appealing we’ll start with the &lt;code&gt;modalContent&lt;/code&gt; container.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Styling CSS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modalContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15%&lt;/span&gt; &lt;span class="nb"&gt;auto&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;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#fefefe&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;80%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The styling is pretty straight forward, the main thing to take note of is the &lt;code&gt;width&lt;/code&gt;. This tutorial won’t go into media queries styling but you will need to adjust the width for different screen sizes as well as the size of the content (images, text, link).&lt;/p&gt;

&lt;p&gt;Now that the content contain is set we can style the &lt;code&gt;close&lt;/code&gt; element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.close&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fefefe&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;28px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.close&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.close&lt;/span&gt;&lt;span class="nd"&gt;:focus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d4ce46&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;x&lt;/code&gt; symbol will now appear on the right of the modal and when hovered will change color to let the user know they can close the modal.&lt;/p&gt;

&lt;p&gt;Next, we need to style the font on our message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal-message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;cursive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;32px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The font we are using is the Google ‘Press Start 2P’, you need to add the following code to your HTML header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="nt"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"preconnect"&lt;/span&gt; &lt;span class="nt"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"https://fonts.gstatic.com"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="nt"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"https://fonts.googleapis.com/css2?family=Press+Start+2P&amp;amp;display=swap"&lt;/span&gt; &lt;span class="nt"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"stylesheet"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we need to style the images in the icon container as they are too big and throw off the alignment of our exit intent modal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.image&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;120px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120px&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;20px&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flame&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;drop-shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="m"&gt;#E37D21&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We do a little magic with the flame elements here. Usually to give an element a shadow we would use the &lt;code&gt;box-shadow&lt;/code&gt; property. However, this creates an ugly box effect on our images.&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%2Fuploads%2Farticles%2Fkzq3c06ph2zjrsa5wqm9.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%2Fuploads%2Farticles%2Fkzq3c06ph2zjrsa5wqm9.png" alt="modal with box shadow styling making it look square"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a result, we can use the &lt;code&gt;filter&lt;/code&gt; property with the CSS &lt;code&gt;drop-shadow&lt;/code&gt; function to apply the effect directly to the image. It is important to note this only works with transparent images.  &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%2Fuploads%2Farticles%2Fw0k36rvpd4yakbwjfwqx.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%2Fuploads%2Farticles%2Fw0k36rvpd4yakbwjfwqx.png" alt="modal with drop-shadow on the flames giving them a glow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Obviously, this is a much better look and gives a nice effect of the flame glowing. Finally for our styling we need to style the &lt;code&gt;sword&lt;/code&gt; element and link to your resume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.resume-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;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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;30px&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#sword&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;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#resume&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&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="nb"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.7em&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;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#7C4A4A&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;4%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Press Start 2P"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;cursive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#D4A851&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have placed both elements in a flex-container so that we can position them in the center and in a column formation. &lt;/p&gt;

&lt;p&gt;That is it for our exit intent modal styling. We now need to add the JavaScript functionality to show the modal when the user is about to exit the page. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Exit intent modal JavaScript
&lt;/h2&gt;

&lt;p&gt;Now that you have the basic CSS set up to hide the modal from the users view, we need to set up some JavaScript to determine when to show the modal. Before we get into creating the desired effect you must first connect your JavaScript file to the HTML. &lt;/p&gt;

&lt;p&gt;To connect the &lt;code&gt;modal.js&lt;/code&gt; file to the HTML file. Place the below line of code within &lt;code&gt;body&lt;/code&gt; tags at the very bottom in your HTML file.&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;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"modal.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you have connected the two files we first need to ensure we are selecting the elements we want. Open the &lt;code&gt;modal.js&lt;/code&gt; file and add the two selectors below to the top.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onExitModal&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;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://peterlunch.com/javascript-exit-intent-modal/" rel="noopener noreferrer"&gt;https://peterlunch.com/javascript-exit-intent-modal/&lt;/a&gt;&lt;br&gt;
With that done, we can start writing our exit intent modal JavaScript code to make the modal appear when a user goes to exit the page. Add the below code to your &lt;code&gt;modal.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toElement&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relatedTarget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code we have added a &lt;code&gt;mouseout&lt;/code&gt; event listener to the document. This event is fired when a the users mouse is moved so that it is no longer contained within the document. The document if you are unsure is basically the webpage. &lt;/p&gt;

&lt;p&gt;Next we perform a conditional check to make sure there is no &lt;code&gt;toElement&lt;/code&gt; and &lt;code&gt;relatedTarget&lt;/code&gt;. To quickly explain these two properties the toElement property retrieves the element that the mouse pointer entered and relatedTarget property has similar functionality just with different browser support. So in plain english what that line is doing is ensuring that the mouse is no longer on any element on the page so both would be &lt;code&gt;null&lt;/code&gt;. This essentially ensures the user is trying to exit the page. &lt;/p&gt;

&lt;p&gt;Finally, we select the &lt;code&gt;modal&lt;/code&gt; and change the display property from &lt;code&gt;none&lt;/code&gt; to &lt;code&gt;block&lt;/code&gt; which will make it appear on the screen to the user. &lt;/p&gt;

&lt;p&gt;Great so now you have a working exit intent modal. However, it is not perfect as everytime a user moves the mouse from the window the modal will appear. This will get annoying. &lt;/p&gt;

&lt;p&gt;To fix this we want to add functionality so that it only shows once per session. We also want to add other functionality to improve the users experience with our modal so it is less spammy. &lt;/p&gt;

&lt;h3&gt;
  
  
  Optimizing the exit intent modals JavaScript
&lt;/h3&gt;

&lt;p&gt;The first thing we are going to do to ensure the modal is only shown to the user once per session. Currently the modal will show each time the user moves the mouse outside the window. &lt;/p&gt;

&lt;p&gt;First we are going to change the event listener to a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exitEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toElement&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relatedTarget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exitEvent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benefit of doing it this way is that we can state which function we want to remove from the DOM. On line 3 we remove the event listener after the first time the user has seen it. &lt;/p&gt;

&lt;p&gt;As a result of this change the modal will only appear once on the page. However, there is a big flaw with this. If the user leaves the page and then comes back it will appear again. &lt;/p&gt;

&lt;p&gt;Therefore the second part of this optimization is to add some cookies to the record if the user has seen the modal within the last week. As a result, the first thing we need some cookie setter and getter functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setCookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cvalue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exdays&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;expires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exdays&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exdays&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="nx"&gt;expires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`expires=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUTCString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cvalue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;expires&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;path=/`&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;getCookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cname&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ca&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for&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;cookie&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;ca&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;=&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The scope of Cookies is beyond this post. But, at a high level the two functions will be used to check if the user has seen the modal yet with the &lt;code&gt;getCookie&lt;/code&gt; function. If they have not we can use the &lt;code&gt;setCookie&lt;/code&gt; function to set them so the user won't see them for a week.&lt;/p&gt;

&lt;p&gt;With those functions written we can now update our &lt;code&gt;modal.js&lt;/code&gt; file to check for cookies and add them once the modal has been seen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;getCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resumeModalSeen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exitEvent&lt;/span&gt;&lt;span class="p"&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;exitEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toElement&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relatedTarget&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exitEvent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resumeModalSeen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above we have wrapped our event listener in a conditional statement that checks if their isn't a cookie 'resumeModalSeen' then listen for the &lt;code&gt;mouseout&lt;/code&gt; event. &lt;/p&gt;

&lt;p&gt;Then within the &lt;code&gt;exitEvent&lt;/code&gt; function we call the setCookie function once the modal has been seen. This will prevent the user from seeing the modal for one week. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is important to note their are laws around cookies, in particular the &lt;a href="https://gdpr-info.eu/" rel="noopener noreferrer"&gt;GDPR guidelines&lt;/a&gt;. The guidelines themselves are well outside the scope of this post. But, if you implement a modal like this please ensure you are being compliant.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As a result of adding cookies and converting the event listener to a function we have solved the first issue with our modal. Next we want to ensure the user has spent sometime on our page before we let the exit intent modal show. What I mean by this is we don't want the modal to appear if a user is on our page for 1 second and then goes to exit. &lt;/p&gt;

&lt;p&gt;To handle this we are going to wrap our event listener in a &lt;code&gt;setTimeout&lt;/code&gt; method, this ensures the user has spent sometime on the page before the modal will even appear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;getCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resumeModalSeen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exitEvent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;6000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above we are ensuring the event listener is only attached to the DOM after the user has been on the page for 6 seconds. Not a lot of time but enought to not make the modal annoying. &lt;/p&gt;

&lt;p&gt;Next we want to actually optimize the exit intent. Right now if a user moves their mouse anywhere other than the window like left or right our modal will display. That is not really exit behaviour. Therefore, we want to make it so that it only shows when the user moves their mouse to the top of the browser. &lt;/p&gt;

&lt;p&gt;To ensure we only show real exit intent we are going to adjust our conditional statement in our &lt;code&gt;exitEvent&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exitEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toElement&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;relatedTarget&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientY&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exitEvent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resumeModalSeen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;e.clientY &amp;lt; 5&lt;/code&gt; condition checks the value cursors position on the window. In particular it checks the vertical position of the mouse. If that position is less than 5 then we can safely assume the user has moved the mouse towards the top of the browser and not to the left, right or bottom.&lt;/p&gt;

&lt;p&gt;Our modal will now be appear as we want it to. But we need to give the user a way to close the modal. Without delay let's do that now. &lt;/p&gt;

&lt;h3&gt;
  
  
  Closing the modal
&lt;/h3&gt;

&lt;p&gt;With any modal if you want the user to be less annoyed you should provide a clear way to exit it. We are going to provide the user with two common ways to exit the modal. &lt;/p&gt;

&lt;p&gt;The first way is with a close button, which we have already added in our HTML with the &lt;code&gt;span&lt;/code&gt; element that has the class name &lt;code&gt;close&lt;/code&gt;. In the &lt;code&gt;modal.js&lt;/code&gt; file just under the span selector add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&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="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example we have added the &lt;code&gt;onclick&lt;/code&gt; global event handler. When the user now clicks on the &lt;code&gt;x&lt;/code&gt; in the modal it will display none making it appear closed. &lt;/p&gt;

&lt;p&gt;Next we want to allow the user to close the modal by clicking anywhere else on the browser window. Add the following code to the &lt;code&gt;modal.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above we have added another &lt;code&gt;onclick&lt;/code&gt; event handler. This time, we check to see if the user clicks on the modal. If the user clicks the modal content, that is anything within the grey border the modal won't close. But, if they click outside of the content and on the &lt;code&gt;onExitModal&lt;/code&gt; element the modal will exit.&lt;/p&gt;

&lt;p&gt;There you have it, that is all the JavaScript we need for our exit intent modal. Next we need to make the modal pop with some CSS animations to really grab the users attention before they leave our page without downloading our resume. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Add CSS Animations
&lt;/h2&gt;

&lt;p&gt;Animating the exit intent modal was the best part and I encourage you to experiment with different animations on yours. If you're not familiar with animating in CSS you can &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations" rel="noopener noreferrer"&gt;checkout this guide&lt;/a&gt; to get started. In this post, I will just be showing you how to implement the animations without much explaination.&lt;/p&gt;

&lt;p&gt;In this case, we are doing two different animations. In the first, we are going to make the text appear word by word like in old video games. Next we are going to display the resume and sword like they used to appear in some Zelda games. &lt;/p&gt;

&lt;p&gt;Let's get started with the first animation. &lt;/p&gt;

&lt;h3&gt;
  
  
  Animating text word by word with CSS
&lt;/h3&gt;

&lt;p&gt;The reason we set up our message to have each word in a separate &lt;code&gt;span&lt;/code&gt; was to allow us to animate them one at a time. &lt;/p&gt;

&lt;p&gt;Looking back to our HTML the &lt;code&gt;messageContainer&lt;/code&gt; &lt;code&gt;div&lt;/code&gt; has an additional class &lt;code&gt;fadeIn&lt;/code&gt;. We are going to use that class to animated each of the spans. The first thing we need to do is add the animation to the CSS style definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fadeIn&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;textFadeIn&lt;/span&gt; &lt;span class="m"&gt;0.5s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above we have used a Combination selector which is an advanced CSS selector you can &lt;a href="https://www.freecodecamp.org/news/use-css-selectors-to-style-webpage/" rel="noopener noreferrer"&gt;learn about here&lt;/a&gt;. Basically, we are telling CSS to select all spans of the parent &lt;code&gt;.fadeIn&lt;/code&gt; class. &lt;/p&gt;

&lt;p&gt;Next, we set the &lt;code&gt;opacity&lt;/code&gt; to 0 so that you cannot see the &lt;code&gt;span&lt;/code&gt; elements but they will still hold their position on the modal. &lt;/p&gt;

&lt;p&gt;Now we add the animation. The first part &lt;code&gt;textFadeIn&lt;/code&gt; is the animation name. Second is the length of the animation which is half a second. Third is the animation timing function we want a smooth linear function. Finally we want the styles updated to what we have at the end of the animation using the &lt;code&gt;animation-fill-mode&lt;/code&gt; property value of &lt;code&gt;forwards&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Finally, we give the animation a delay of 300 milliseconds so that it doesn't start as soon as the modal opens. &lt;/p&gt;

&lt;p&gt;Now that we have the animation attached to the element we need to make the actual animation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;textFadeIn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the animation starts we have the text at 10% opactity and it is -100px on the x plane. As it transitions it will go to 0px on the x plane and full opacity. It should look like the below. &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%2Fuploads%2Farticles%2Fqwlfi4u10ge96a38izfa.gif" 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%2Fuploads%2Farticles%2Fqwlfi4u10ge96a38izfa.gif" alt="text appears on modal all at once"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is not what we want, we want it word by word. To handle this we need to target each of the &lt;code&gt;span&lt;/code&gt; elements and add an &lt;code&gt;animation-delay&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fadeIn&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.7s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fadeIn&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fadeIn&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.7s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fadeIn&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fadeIn&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.7s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.fadeIn&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;7&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.9s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we start by targeting the second &lt;code&gt;span&lt;/code&gt; element. We then give each element a delay value that is 100ms before the end of the previous element's animation. This gives the text a nice flowing effect. &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%2Fuploads%2Farticles%2Fm3i678idczjs3pgv6oy8.gif" 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%2Fuploads%2Farticles%2Fm3i678idczjs3pgv6oy8.gif" alt="text appears word by word"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the text is flowing much better let's animate the &lt;code&gt;resumeContainer&lt;/code&gt; to float up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Animating a container to float up
&lt;/h3&gt;

&lt;p&gt;The first thing we need to do is add the below lines of code to the &lt;code&gt;resumeContainer&lt;/code&gt; styling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;opacity&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;resumeUp&lt;/span&gt; &lt;span class="nt"&gt;ease-out&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt; &lt;span class="nt"&gt;forwards&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-delay&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again we have set the &lt;code&gt;opacity&lt;/code&gt; to 0 so it won't appear at the start. We then add the animation like we did for the text animation. Finally we add a delay of 3.5 seconds which is about the time it takes for the text animation to finish. We do this in order to make the resume appear just after the text 'take this'. As a result the user is like "oh take this resume, sure thing!".&lt;/p&gt;

&lt;p&gt;The last thing we need to do is create the &lt;code&gt;resumeUp&lt;/code&gt; animation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;resumeUp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code like in the text animation we set the opacity to 10% and then as the animation progresses we increase it. This time we have set the Y position of the container to 100px and then move it towards 0 to create the floating up effect. &lt;/p&gt;

&lt;p&gt;And boom we have a complete exit intent modal. Well done. &lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;By and large you should now be able to create an exciting exit intent modal with HTML, CSS and JavaScript that gets your resume downloaded. &lt;/p&gt;

&lt;p&gt;As this modal is live on my portfolio, I encourage you not to copy the modal but come up with your own. Try instead to add your own flair that matches who you are. &lt;/p&gt;

&lt;p&gt;Lastly, if you thought this was awesome or you learnt something from this post then checkout the rest of my posts &lt;a href="https://peterlunch.com/?utm_source=devto&amp;amp;utm_medium=emb-link&amp;amp;utm_campaign=exit-intent-modal" rel="noopener noreferrer"&gt;here&lt;/a&gt; or &lt;a href="https://mailchi.mp/9e224d35f00e/74ugxdpuuw" rel="noopener noreferrer"&gt;sign up to my newsletter&lt;/a&gt; to access to more amazing content.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>career</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How CSS pseudo-elements work a ridiculously simple explanation for beginners</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 04 May 2021 09:58:25 +0000</pubDate>
      <link>https://dev.to/peterlunch/how-css-pseudo-elements-work-a-ridiculously-simple-explanation-for-beginners-49gk</link>
      <guid>https://dev.to/peterlunch/how-css-pseudo-elements-work-a-ridiculously-simple-explanation-for-beginners-49gk</guid>
      <description>&lt;p&gt;Pseudo-elements especially &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; are so hot right now. Amazing sites like &lt;a href="https://www.cyberpunk.net/us/en/" rel="noopener noreferrer"&gt;Cyberpunk.net&lt;/a&gt; use them to create amazing affects. However, lots of beginners don’t fully grasp their power. So, before you can harness their power you first need to understand how they work.&lt;/p&gt;

&lt;p&gt;When I first started working with pseudo-elements, I had no idea what I was doing or how they actually work. I was just copying and pasting other people's code and not really understanding why it was or wasn’t working.&lt;/p&gt;

&lt;p&gt;If you want to harness the power of CSS and get good at it then understanding pseudo-elements is a must. By the end of this post you will have a strong grasp of what pseudo-elements are and how to use them to create stylish elements yourself.&lt;/p&gt;

&lt;p&gt;But first, let’s explore what they are.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Pseudo-Elements
&lt;/h2&gt;

&lt;p&gt;In CSS pseudo-elements are a keyword that you add to &lt;a href="https://www.w3schools.com/cssref/css_selectors.asp" rel="noopener noreferrer"&gt;selectors&lt;/a&gt;. These pseudo elements let you style specific parts of the element you selected. CSS denotes them using two colons &lt;code&gt;::&lt;/code&gt; which helps you tell them apart from CSS pseudo-classes as they have only one colon &lt;code&gt;:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s look at the general syntax for CSS pseudo-elements before we get into specific pseudo-elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;selector&lt;/span&gt;&lt;span class="nd"&gt;::pseudo-element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, you put the CSS selector before the double colon. Next, inside the curly braces you write CSS property value pairs, like you would for any other element you are styling.&lt;/p&gt;

&lt;p&gt;As a real example, we could do something like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.second&lt;/span&gt;&lt;span class="nd"&gt;::selection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&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;mediumspringgreen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example uses the &lt;code&gt;::selection&lt;/code&gt; pseudo-element on the &lt;code&gt;second&lt;/code&gt; CSS class selector. Now, when you highlight the paragraph text it is a different color and background.&lt;/p&gt;

&lt;p&gt;We’ll explore the &lt;code&gt;::selection&lt;/code&gt; pseudo element some more later. For now I want you to focus on the two major pseudo-elements &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the before and after pseudo-elements?
&lt;/h2&gt;

&lt;p&gt;The before and after pseudo-elements let you insert content onto a web page. They allow you to do this without the need for it to be in the HTML. Essentially you can insert content through CSS.&lt;/p&gt;

&lt;p&gt;One important thing to note when it comes to the before and after pseudo-elements is that when they are created they are not actually on the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction" rel="noopener noreferrer"&gt;DOM&lt;/a&gt;. In other words, they are fake elements, this is why they are call &lt;em&gt;“pseudo&lt;/em&gt; elements as the word pseudo means fake. So, the name fits because these elements don’t actually change anything in the document. They are hidden elements that are only visible to the user and not the DOM.&lt;/p&gt;

&lt;p&gt;What this looks like in practice is this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;after&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result would be something like this.&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;h1&amp;gt;&lt;/span&gt;
  before
    &lt;span class="c"&gt;&amp;lt;!--actual h1 element --&amp;gt;&lt;/span&gt;
  after
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Knowing that these elements are fake it’s time to look at the first fake element you will use a lot in web development, the before pseudo-element.&lt;/p&gt;

&lt;h3&gt;
  
  
  The before pseudo-element
&lt;/h3&gt;

&lt;p&gt;In CSS, &lt;code&gt;::before&lt;/code&gt; creates a pseudo-element that is the first child of the selected element. To put it another way, it is a pseudo-element that comes before the content of the CSS selector. So if you have a paragraph element it would look like this &lt;code&gt;p::before&lt;/code&gt; with &lt;code&gt;p&lt;/code&gt; being the selector and &lt;code&gt;::before&lt;/code&gt; being the pseudo-element.&lt;/p&gt;

&lt;p&gt;With this in mind let’s look at some examples.&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;p&amp;gt;&lt;/span&gt;Mr. and Mrs. Dursley of number four, Privet Drive, were proud to say that they were perfectly normal, thank you very much.&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="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#7f0909&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffc500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"the boy who lived"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;130%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#5BC8F8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ilm1imtlvnlryw0qskp.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%2Fuploads%2Farticles%2F9ilm1imtlvnlryw0qskp.png" alt="::before pseudo-element result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the code above, we have added the content &lt;em&gt;'the boy who lived'&lt;/em&gt; before the CSS selector which in this case is the &lt;code&gt;p&lt;/code&gt; tag and its content.&lt;/p&gt;

&lt;p&gt;We were then able to style the content before the selector however we wanted.&lt;/p&gt;

&lt;p&gt;If we check the developer tools in the &lt;a href="https://codepen.io/pin0s/pen/dyNxvXZ" rel="noopener noreferrer"&gt;codepen&lt;/a&gt;, you will see that there is no element &lt;em&gt;'the boy who lived'&lt;/em&gt; There is just a pseudo-element &lt;code&gt;::before&lt;/code&gt;. As it isn't really on the DOM.&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%2Fuploads%2Farticles%2F9hghwiq4cytiba8sbh6x.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%2Fuploads%2Farticles%2F9hghwiq4cytiba8sbh6x.png" alt="pseudo-element before showing in dev tools but not on the dom"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's look at another example.&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;h1&amp;gt;&lt;/span&gt;harry potter and the sorcerer's stone&lt;span class="nt"&gt;&amp;lt;/h1&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="nt"&gt;h1&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;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;""&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="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffc500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&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;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9zwqoyqvhj1uxu5kvlz.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%2Fuploads%2Farticles%2Fc9zwqoyqvhj1uxu5kvlz.png" alt="before pseudo-element with block styling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, the before pseudo-element is using the &lt;code&gt;display&lt;/code&gt; property with the value &lt;code&gt;block&lt;/code&gt;. This then moves the background with a width of 5px above and before the &lt;code&gt;h1&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Now you know what the before pseudo-element does let's look at the after pseudo-element.&lt;/p&gt;

&lt;h3&gt;
  
  
  The After pseudo-element
&lt;/h3&gt;

&lt;p&gt;In CSS, &lt;code&gt;::after&lt;/code&gt; creates a pseudo-element this is the last child of the selected element. So much like the &lt;code&gt;::before&lt;/code&gt;, it is a pseudo-element that comes after the content of the CSS selector.&lt;/p&gt;

&lt;p&gt;Keeping that in mind let’s use the second example from the before section and add a line underneath with the after pseudo-element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;""&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="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffc500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&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;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi16jjzusd8ju3i6izei.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%2Fuploads%2Farticles%2Fbi16jjzusd8ju3i6izei.png" alt="before &amp;amp; after pseudo-element with block styling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now have a line under the &lt;code&gt;h1&lt;/code&gt;. How cool is that, we can make our own little styling elements to create great looking elements.&lt;/p&gt;

&lt;p&gt;By now, you should now have a good understanding of how the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; pseudo-elements work. To further improve our knowledge we need to understand what the &lt;code&gt;content&lt;/code&gt; property is and what it is doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content property
&lt;/h2&gt;

&lt;p&gt;Did you notice the use of the &lt;code&gt;content&lt;/code&gt; property, with the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; pseudo-elements? Objects that are inserted using the &lt;code&gt;content&lt;/code&gt; property are anonymous replaced &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element" rel="noopener noreferrer"&gt;elements&lt;/a&gt;. Put in simpler terms, it is an element whose content is not affected by the current documents styles.&lt;/p&gt;

&lt;p&gt;Thus, when using the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; pseudo-elements, you &lt;b&gt;must&lt;/b&gt; use the &lt;code&gt;content&lt;/code&gt; property to make your styles visible. Did you also notice that the content is inside the element? In spite of the fact that the naming of &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; make it feel like the content should come before or after the element. But, it is definitely before or after the content inside the element.&lt;/p&gt;

&lt;p&gt;Next, to better understand the content property let’s look at what values it takes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Property Accepted Values
&lt;/h3&gt;

&lt;p&gt;The content property takes many types of values. The default value is &lt;code&gt;normal&lt;/code&gt;. It means 'normally' nothing will be visible to the user. Thus, you give the content property one of the values below.&lt;/p&gt;

&lt;p&gt;The other values content can be are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;string&lt;/strong&gt; - this sets the content to be the string you specify.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;counter&lt;/strong&gt; - used to style lists.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;image&lt;/strong&gt; - this sets the content to be an image you specify with a &lt;code&gt;url()&lt;/code&gt; or &lt;code&gt;gradient&lt;/code&gt; data type. The image is inserted at its exact dimensions, meaning you cannot resize the image.

&lt;ul&gt;
&lt;li&gt;please note that to insert alt text you use a &lt;code&gt;/&lt;/code&gt; after the &lt;code&gt;url()&lt;/code&gt; and a string description of the image. For example: &lt;code&gt;content: url("https://www.example.com/test.png") / "This is the alt text";&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Nothing&lt;/strong&gt; - Useful for inserting images as background-images (set width and height, and can even resize with background-size), or making other cool styling features (link to dev.to post).&lt;/li&gt;

&lt;li&gt;A &lt;strong&gt;attr()&lt;/strong&gt; value - Sets the content as the string value of the selected elements attribute.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other awesome pseudo-elements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Selection
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;::selection&lt;/code&gt; - This, CSS pseudo-element applies styles to the part of a document that has been highlighted by the user. To put it another way, it makes the highlighter on your page look pretty when people highlight text to copy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nd"&gt;::selection&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;cyan&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  First-letter
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;::first-letter&lt;/code&gt; - CSS pseudo-element applies styles to the first letter of the first line of a block-level element, but only when not preceded by other content (such as images or inline tables).&lt;/p&gt;

&lt;p&gt;To rephrase the above, this pseudo-element lets you style the first letter of the first line of the element you select. This only happens on elements that are categorized as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements" rel="noopener noreferrer"&gt;block-level elements&lt;/a&gt; check that link out for a list of block level elements.&lt;/p&gt;

&lt;p&gt;As a result, we can use this pseudo-element to make awesome drop caps for our paragraphs, see the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nd"&gt;::first-letter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&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="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;117&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;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;212&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;173&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;81&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250%&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;6px&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  First-line
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;::first-line&lt;/code&gt; - CSS pseudo-element applies styles to the first line of a block-level element.&lt;/p&gt;

&lt;p&gt;In plain English the above means, this pseudo-element lets you style the the first line of the element you select. Again like with first letter this only happens to block level elements.&lt;/p&gt;

&lt;p&gt;Let's add the below code to the &lt;code&gt;first-letter&lt;/code&gt; example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nd"&gt;::first-line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvj64lldpoe8kmz176d1.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%2Fuploads%2Farticles%2Fhvj64lldpoe8kmz176d1.png" alt="first-letter and first-line pseudo-elements effects on p element"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the &lt;code&gt;p&lt;/code&gt; now has drop caps and red text for the first line. Play around with width in the pen above to see what happens as you increase and decrease the width.&lt;/p&gt;

&lt;p&gt;Did you notice how if the text moves lines the color changes? You have to be careful taking into consideration things like the width of the element and how it will respond on different screens when styling the first line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Marker
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;::marker&lt;/code&gt; CSS pseudo-element selects the marker box of a list item, which typically contains a bullet or number.&lt;/p&gt;

&lt;p&gt;The marker pseudo-element will allow you to replace the counter content value. For an example on how a counter works I encourage you to check out this &lt;a href="https://www.freecodecamp.org/news/css-before-and-after-how-to-use-the-content-property/" rel="noopener noreferrer"&gt;post&lt;/a&gt;. That said, a counter is just the bullet point of number in front of a list item (&lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;) and the &lt;code&gt;::marker&lt;/code&gt;pseudo-element lets you style them.&lt;/p&gt;

&lt;p&gt;Let's look at an example.&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;h3&amp;gt;&lt;/span&gt;Nintendo Hero's&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Mario&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Link&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Samus&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/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="nt"&gt;ul&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e4000f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The above example is pretty simple, we have just changed the bullet point color to red. But, you can do lot's of things like change the style or even use emoji's.&lt;/p&gt;

&lt;p&gt;Finally, it is important to note that the ::marker pseudo-element is not fully supported at the time of writing this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx48djtc2wfdd3ml9dsw.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%2Fuploads%2Farticles%2Fqx48djtc2wfdd3ml9dsw.png" alt="browser support for marker pseudo element"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Now you should have a good understanding of pseudo-elements. Let’s recap on a few important notes.&lt;/p&gt;

&lt;p&gt;Firstly, pseudo elements let you style specific parts of the element you selected. Pseudo-elements are denoted by double colons.&lt;/p&gt;

&lt;p&gt;Next, remember that pseudo-elements do not appear in the DOM as they are fake elements. The way you make them visible to the user is to utilize the &lt;code&gt;content&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Lastly, if you learnt something from this post then checkout the rest of my posts &lt;a href="https://bit.ly/2Re6Vdf" rel="noopener noreferrer"&gt;here&lt;/a&gt; or &lt;a href="https://mailchi.mp/4fb2a2723574/peter-lunch-link" rel="noopener noreferrer"&gt;sign up to my newsletter&lt;/a&gt; to get ridiculously good and super exclusive newbie content.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>A painless guide to understanding CSS positioning</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Mon, 26 Apr 2021 10:30:25 +0000</pubDate>
      <link>https://dev.to/peterlunch/a-painless-guide-to-understanding-css-positioning-2nbh</link>
      <guid>https://dev.to/peterlunch/a-painless-guide-to-understanding-css-positioning-2nbh</guid>
      <description>&lt;p&gt;Developing an understanding of the CSS position property is important if you want to become really good at CSS. However, it can be one of the more frustrating experiences for a beginner.&lt;/p&gt;

&lt;p&gt;In building my &lt;a href="https://www.peterlynch.dev/" rel="noopener noreferrer"&gt;Developer portfolio&lt;/a&gt; I found I didn’t really understand the CSS position property, I just randomly tried different combinations of positions together until I got something I was kind of happy with. But, most of the time it was just garbage and it had me pulling what little hair I have left out.&lt;/p&gt;

&lt;p&gt;In this article, I am going to try and save you the pain of not knowing what you are doing with the position property. You are going to learn how each of the values of the CSS position properties work, so you can get really good at CSS.&lt;/p&gt;

&lt;p&gt;To understand the position property and the values associated we first need to make sure we understand how elements are positioned on a webpage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flow Layout
&lt;/h2&gt;

&lt;p&gt;The way elements are positioned on a page is called the normal flow, or flow layout. It is the way elements are displayed on a page by default. Basically the flow is the set of all elements on your page working together and each one knows about all the others.&lt;/p&gt;

&lt;p&gt;Now, CSS treats each HTML element as its own box, you might have heard of this referred to as the box model. Block-level items (things like headings, paragraphs or divs) by default start on a new line while inline items (images or spans) sit within the surrounding content on the same line. The default layout of elements in this way is called the normal flow of a document, but CSS offers us a powerful tool in the position property to override the normal flow.&lt;/p&gt;

&lt;p&gt;Let's see what the position property does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Position Property
&lt;/h2&gt;

&lt;p&gt;The CSS position property sets how an element is positioned in a document. We can use it to determine how we want to position individual elements based on the values you give the position property.&lt;/p&gt;

&lt;p&gt;The position property takes five values.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Static
2. Relative
3. Absolute
4. Fixed
5. Sticky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We are going to cover all 5 of these values, but before we do we need to understand the placement properties and how they affect positioning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Placement Properties
&lt;/h2&gt;

&lt;p&gt;By itself the position property doesn’t do much. We need to use the placement properties (just what I call them not the official name) to tell the document exactly where the element should be placed. There are four main properties to do just that.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Top
2. Left
3. Right
4. Bottom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each of these properties define how much the element's position should be adjusted from its default and in which direction it should be adjusted. When we look at the position values below and the examples it will become more clear how these work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Position Property Values
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Static Positioning
&lt;/h3&gt;

&lt;p&gt;Static positioning is the default value for the position property. That is the elements on the page appear in the order expected by normal flow. The placement properties &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; do not affect an element that has &lt;code&gt;position: static&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It can often be useful to set the position property to static even though it is the default value. An example of when you might want to do this is when you want to override a position value you have set elsewhere.&lt;/p&gt;

&lt;p&gt;Let’s look at an example to see that &lt;code&gt;position static&lt;/code&gt; has no effect on the element with this property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"parent-box"&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;"box-original"&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;"box-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"box-original"&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;"box-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"box-original"&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;"box-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example we have three &lt;code&gt;divs&lt;/code&gt; each in a parent container with the class &lt;code&gt;box-original&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's add &lt;code&gt;position: static&lt;/code&gt; to the div with the class &lt;code&gt;box-2&lt;/code&gt;and give it box some values for &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;left&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.box-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;static&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&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;left&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;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;black&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;mediumpurple&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;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is the result of the changes we have made.&lt;/p&gt;

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

&lt;p&gt;Did you see that even though we have used the position property and the placement values that it has no effect on the element? You now know that the &lt;code&gt;static&lt;/code&gt; value is the default and that the placement values do not affect elements with &lt;code&gt;position: static&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s look at the first value that does affect the position of an element in the flow of the document.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relative Positioning
&lt;/h2&gt;

&lt;p&gt;Relative position means that an element is positioned relative to its original position in the normal flow. By setting an element to just have position: relative nothing will happen. We will need to use the placement properties to change how the element is positioned relative to its original position.&lt;/p&gt;

&lt;p&gt;Basically when you set a HTML element to position: relative, it will remain in the flow of the layout. But, by using the placement properties you can move the element around. Let’s look at an example to cement your understanding of the relative position.&lt;/p&gt;

&lt;p&gt;We are going to replace the position: static with position: relative.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.box-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&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;left&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;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;red&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;mediumpurple&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;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of the change is below.&lt;/p&gt;

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

&lt;p&gt;You can see that the purple square element has been positioned relative to where it was initially positioned the grey square. In the example above it is 10px from the top and 10px from left of where it was originally meant to be positioned in the normal flow. However, the element remains in the normal flow of the document and the offset is applied relative to its original position. Make sure to remember this as we move on to the other position values.&lt;/p&gt;

&lt;h3&gt;
  
  
  Absolute Positioning
&lt;/h3&gt;

&lt;p&gt;Absolute positioned elements are removed from the normal document flow, and the space that the element was originally occupying is no longer reserved for that element. I like to remember it by saying it is 'absolutely not there'.&lt;/p&gt;

&lt;p&gt;When the element is given &lt;code&gt;position: absolute&lt;/code&gt; all other elements behave as if that element is no longer in the document. Therefore, there is no space reserved for that element in the page layout. This can then be a really powerful tool for moving HTML elements around.&lt;/p&gt;

&lt;p&gt;An important point and something that stumped me when I was learning is that an element with &lt;code&gt;position: absolute&lt;/code&gt; is positioned &lt;strong&gt;relative&lt;/strong&gt; to its closest positional ancestor. What this means is that for absolute positioning to work, the parent element must have a position property value other than the default of &lt;code&gt;static&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a crucial point to take note of, because if the closest parent element does not have a position property, the element with the absolute position will position relative to the next parent element that has a position property value. If there is no element with a position property value the element will be positioned relative to the html or viewport element. Not knowing this is what can cause so much pain when trying to position elements in the document.&lt;/p&gt;

&lt;p&gt;We can move the absolute positioned element around just like any other CSS position property by using the placement properties. Using the &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; properties, you determine where the element will be placed relative to the first parent element in the hierarchy that has a position property other than the default &lt;code&gt;position: static&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's get back to our example. We are now going to change the position property of the second box element to &lt;code&gt;position: absolute&lt;/code&gt;. Before we look at the change and the result, check the previous pen to see what the position of the &lt;code&gt;parent-box&lt;/code&gt; element is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.box-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;red&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;mediumpurple&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;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results of the changes are below.&lt;/p&gt;

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

&lt;p&gt;Here you will see that no space was created in the document for the element. In fact the space has collapsed and the other elements are acting like it isn't even on the page. This is because the element is now positioned relative to the parent-box element.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixed positioning
&lt;/h3&gt;

&lt;p&gt;Fixed positioning works like &lt;code&gt;absolute&lt;/code&gt; positioning in that it is removed from the normal document flow, and the space that element was originally occupying is no longer reserved for that element.&lt;/p&gt;

&lt;p&gt;Fixed positioned elements are positioned relative to the &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Viewport" rel="noopener noreferrer"&gt;viewport&lt;/a&gt;. What this means is that when you scroll down the page, the element remains in its original location on the page. This is often used for &lt;a href="https://peterlunch.com/how-to-create-responsive-gaming-style-navbar/" rel="noopener noreferrer"&gt;navigation bars&lt;/a&gt;, which no matter where the users scrolls on the page always remain visible at the top of the page.&lt;/p&gt;

&lt;p&gt;We are going to change the position of box-2 from &lt;code&gt;position: absolute&lt;/code&gt; to &lt;code&gt;position: fixed&lt;/code&gt;. We are also going to change the value of the &lt;code&gt;top&lt;/code&gt; property to 0 and remove the &lt;code&gt;left&lt;/code&gt; properties value. We have also added some more boxes to show you the effect as you scroll.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.box-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;red&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;mediumpurple&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;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results of the changes are below.&lt;/p&gt;

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

&lt;p&gt;As you can see from the example the purple box element is now fixed at the top of the page, much like a&lt;a href="https://peterlunch.com/creating-a-simple-sticky-navbar-with-css-and-html/" rel="noopener noreferrer"&gt;navigation bar we've built in the past&lt;/a&gt;. This is because we have set the position property to &lt;code&gt;fixed&lt;/code&gt; and set it 0 from the &lt;code&gt;top&lt;/code&gt; of the page.&lt;/p&gt;

&lt;p&gt;When using the CSS position property with a &lt;code&gt;fixed&lt;/code&gt; value it’s important to note that it takes up the viewport space you specify the whole time the user is on the page. This can affect a users experience especially on mobile devices where screen space is limited. So ensure you are thinking about how you use it across all devices with your media queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sticky Positioning
&lt;/h3&gt;

&lt;p&gt;The sticky positioning value is positioned according to the normal flow of the document, yet it is also a mix of both position &lt;code&gt;relative&lt;/code&gt; and position &lt;code&gt;fixed&lt;/code&gt;. What I mean by this is that it behaves as a relatively positioned element until the page reaches a set scroll point then it will behave as a &lt;code&gt;fixed&lt;/code&gt; position element.&lt;/p&gt;

&lt;p&gt;Let’s look at  a new example below to see that when the element reaches a position on the page it changes to a &lt;code&gt;fixed&lt;/code&gt; position element. We are going to give the &lt;code&gt;dt&lt;/code&gt; tag the position value &lt;code&gt;sticky&lt;/code&gt; and the property &lt;code&gt;top&lt;/code&gt; with a value of &lt;code&gt;3px&lt;/code&gt; meaning it will be 3px from the top of the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;dt&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#007FFF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&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-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&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;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;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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;2px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sticky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try scrolling through the result below to see how sticky works.&lt;/p&gt;

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

&lt;p&gt;In the example above you can see that the &lt;code&gt;dt&lt;/code&gt; tags (the lines in blue) stick until we reach the point of the next &lt;code&gt;dt&lt;/code&gt; tag. Once we reach that point the next &lt;code&gt;dd&lt;/code&gt; tag becomes the sticky element. So, the &lt;code&gt;dt&lt;/code&gt; elements are positioned in the normal flow of the page, but when you reach its position when scrolling, its position becomes fixed. It sticks to that position and stays there as you scroll until the next &lt;code&gt;dt&lt;/code&gt; tag takes the fixed position.&lt;/p&gt;

&lt;p&gt;Be careful with the &lt;code&gt;sticky&lt;/code&gt; positioned property as it is not yet &lt;a href="https://caniuse.com/css-sticky" rel="noopener noreferrer"&gt;universally supported&lt;/a&gt; by all browsers at the time of writing this (those pesky IE users). You can always check if something is support by checking out &lt;a href="https://caniuse.com/" rel="noopener noreferrer"&gt;caniuse.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwq1aw2phjanbvrx86lu.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%2Fuploads%2Farticles%2Fxwq1aw2phjanbvrx86lu.png" alt="browser support for sticky position property"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Where does Z-index fit in
&lt;/h3&gt;

&lt;p&gt;Z-index is a CSS property that let’s you set the z-order of a positioned element. This means that any element that you set with a position property value other than &lt;code&gt;static&lt;/code&gt; can be positioned along the z-index plane.&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%2Fuploads%2Farticles%2F61ayi8ehkdfz1wbyggw4.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%2Fuploads%2Farticles%2F61ayi8ehkdfz1wbyggw4.png" alt="x, y, z plane highlighting z-index"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;&lt;small&gt;The 3D plane of X, Y and Z - Source: [Brilliant](https://brilliant.org/wiki/3d-coordinate-geometry-equation-of-a-plane/).&lt;/small&gt;&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;Basically the z-index lets you have control over how these elements are ordered and therefore how they overlap each other. Essentially, it is you deciding which elements should appear at the front and which should appear at the back.&lt;/p&gt;

&lt;p&gt;Elements with higher value z-index properties are displayed in front of elements with lower value z-index properties.&lt;/p&gt;

&lt;p&gt;Let's look at an example below, I am going to show you the HTML order to show you that if we use z-index the order doesn't matter we can determine their position from front to back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"parent-box"&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;"box box-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;z-index:4&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;"box box-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;z-index:1&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;"box box-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;z-index:2&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;"box box-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;z-index:5&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;"box box-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;z-index:3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then give each the &lt;code&gt;box&lt;/code&gt; class a position of &lt;code&gt;fixed&lt;/code&gt; which now allows us to change the z-index of each of the box elements. The results of doing so are below.&lt;/p&gt;

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

&lt;p&gt;As you can see from the results, the higher &lt;code&gt;z-index&lt;/code&gt; elements are in the front and the lower ones are at the back.&lt;/p&gt;

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

&lt;p&gt;To summarize what we’ve learned. The CSS position property is a powerful tool that lets you change the normal flow of a document, by determining how elements should be placed on a page.&lt;/p&gt;

&lt;p&gt;You have five position properties to work with.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static&lt;/li&gt;
&lt;li&gt;Relative&lt;/li&gt;
&lt;li&gt;Absolute&lt;/li&gt;
&lt;li&gt;Fixed&lt;/li&gt;
&lt;li&gt;Sticky&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You set the position of the element by using the &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; properties and by specifying how far away from that point the element should be.&lt;/p&gt;

&lt;p&gt;You can also set the position of the element on the z-index if you have given it a position property value other than the default &lt;code&gt;static&lt;/code&gt;. The higher the values are displayed in the front and the lower values are displayed in the back.&lt;/p&gt;

&lt;p&gt;The best way to get better at CSS position property is to play around with it. Give the pens I used here a try and play around with each property by giving them different values or changing the parent elements.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you got value out of this post, I'd really appreciate if you checkout some of my other content on my &lt;a href="https://peterlunch.com/" rel="noopener noreferrer"&gt;website&lt;/a&gt; or follow me on &lt;a href="https://twitter.com/thelynchpinau" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>How to Plan and Build a Programming Project – A Legitimate Guide for Beginners</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Mon, 12 Apr 2021 10:47:12 +0000</pubDate>
      <link>https://dev.to/peterlunch/how-to-plan-and-build-a-programming-project-a-legitimate-guide-for-beginners-1fll</link>
      <guid>https://dev.to/peterlunch/how-to-plan-and-build-a-programming-project-a-legitimate-guide-for-beginners-1fll</guid>
      <description>&lt;p&gt;This is a post I have thought about writing for a long time, I originally published it on my blog in more detail &lt;a href="https://peterlunch.com/how-to-plan-and-build-a-programming-project/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. But, I thought it could help more people in this community so I wanted to share a snappier version.  &lt;/p&gt;

&lt;p&gt;In this article, I am going explain how to plan and build a programming project. I will show you how to break down a  project, so that you can start making awesome projects to help you level up your coding skills.&lt;/p&gt;

&lt;p&gt;This article aims to help code newbies feel less intimidated as they attempt to leave tutorial purgatory and build their own awesome coding projects. So if that sounds like you keep reading. &lt;/p&gt;

&lt;p&gt;Projects are super intimidating when you are first starting out, it can seem like such a huge mountain to climb when you can't even reproduce the results of the YouTube tutorial you just watched without looking at it again 30 times 🤦‍♂️. &lt;/p&gt;

&lt;p&gt;When I first started out learning to code, I would start a course or follow a tutorial and think that I was understanding things. But, when I'd stop watching and try to reproduce the project I couldn't get anywhere.&lt;/p&gt;

&lt;p&gt;To overcome this, I posted my frustration on the popular subreddit r/learnprogramming. The responses I received were all centered around building my own projects. This advice sounds great on the surface and was the right advice, yet the issue for me was I couldn't even watch a tutorial and reproduce the results. How was I supposed to build a project? A project is 10 levels above a tutorial and at the time it seemed that projects were so far away from my abilities. I had no clue how to even get started, let alone how I was going to put it all together. The problem essentially was I didn't know how to get from point A to point B.&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%2Fuploads%2Farticles%2Fvatoqsbdoxq2y34nttfv.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%2Fuploads%2Farticles%2Fvatoqsbdoxq2y34nttfv.png" alt="Reddit conversation of users asking how to build a project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an issue I see all the time on r/learnprogramming. Beginners like me are frustrated that they can't seem to get out of tutorial purgatory and so they seek advice. But, what they get is well meaning redditor's slamming the build projects response in their face without even considering that if the newbie can't even replicate a tutorial how are they going to create their own project.  In my time learning to program I have seen so many examples of the same question I had and the same responses. I thought it was about time I did something about it and gave back to the universe.&lt;/p&gt;

&lt;p&gt;So here I am, writing a post that actually breaks down how to build your own projects so that you can become a better developer and cement what you learning.&lt;/p&gt;

&lt;p&gt;In order to plan and build a programming project there are three key steps I now use when building projects so let's start with the first step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Defining the project
&lt;/h2&gt;

&lt;p&gt;The first step when planning a programming project is to define it.&lt;/p&gt;

&lt;p&gt;When I am defining the project I ask myself these 4 questions:&lt;/p&gt;

&lt;p&gt;What is the project?&lt;br&gt;
What is the MVP (Minimal Viable Product)?&lt;br&gt;
What are the nice to haves?&lt;br&gt;
When will the project be complete?&lt;/p&gt;

&lt;h4&gt;
  
  
  Example project definition
&lt;/h4&gt;

&lt;p&gt;To give a simple example, let's say we are going to build a calculator app we would have a basic project definition like below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculator app project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is the project?&lt;/em&gt; - The calculator project is a project to build a calculator that is accessible in a web browser. The project is going to be solved using HTML, CSS and JavaScript. It will allow users to input numbers and calculate the results of those numbers based on the arithmetic operation they choose.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is the MVP?&lt;/em&gt; - The minimal viable product is a calculator that renders in a web browsers that can perform addition, subtraction, multiplication and division operations based on a users input and show the user the result of that equation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What are the nice to haves?&lt;/em&gt; - The nice to haves for this project are styling the calculator, taking keyboard presses as input not just users clicking buttons and adding higher order operations like 'to the power of x'.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;When will the project be complete?&lt;/em&gt; - The project will be complete once all the MVP features have been implemented and the calculator has been styled.&lt;/p&gt;

&lt;p&gt;The above definition is simple and straight forward. If my Mum picked it up she would understand what the project is about. She would understand because it tells you what the project is, the MVP features you must build, the nice to have features and when it will be complete. By defining the project you make a project less intimidating.&lt;/p&gt;

&lt;p&gt;Once you have the project definition you can begin the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Creating the workflow
&lt;/h2&gt;

&lt;p&gt;The next step is the simplest. Usually this step can be combined with step 3.  But, just for now we are going to look at it here as a separate step so that I can show you how to set up a very basic workflow for your own projects. Once you have done it once, it can be a default step for the rest of your projects.&lt;/p&gt;

&lt;p&gt;You first want to use something like Trello a free tool to manage projects.&lt;/p&gt;

&lt;p&gt;To set up our Kanban board we want to create 4 columns.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;TODO&lt;/li&gt;
&lt;li&gt;DOING&lt;/li&gt;
&lt;li&gt;DONE&lt;/li&gt;
&lt;li&gt;BUGS / NOT SURE HOW TO DO&lt;/li&gt;
&lt;/ol&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%2Fuploads%2Farticles%2Fq221um3ta9modcompicc.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%2Fuploads%2Farticles%2Fq221um3ta9modcompicc.png" alt="Kanban board with 4 columns listed above"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Within these columns we are going to add cards. As we work on the cards we move them into the &lt;strong&gt;doing&lt;/strong&gt; column and once we have finished with that card we can move it to the &lt;strong&gt;done&lt;/strong&gt; column. If you have a bug you are stuck on or are not sure how to do something we can move it to the &lt;strong&gt;bugs/not sure&lt;/strong&gt; column.&lt;/p&gt;

&lt;p&gt;Now we have our workflow set up we can get onto the last step, the one that stumped me the most when I was learning to code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Breaking the project down into smaller components
&lt;/h2&gt;

&lt;p&gt;The key to building your own projects starts with breaking the big project down into smaller, less intimidating components. These smaller components are what become our cards from step 2.&lt;/p&gt;

&lt;p&gt;Now this sounds simple enough, but when I was first starting out it did not occur to me that you could do this. I thought most developers just start coding and the project flowed out of them like you see in the movies. I thought that was what I was supposed to be able to do. However, now that I have had a chance to work in the industry I know that is definitely not the case, in fact a good developer will break that project down into smaller tasks.&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%2Fuploads%2Farticles%2Fx82xv7vdi7vakgvli8a3.gif" 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%2Fuploads%2Farticles%2Fx82xv7vdi7vakgvli8a3.gif" alt="estefannie pretending to code like they do in the movies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yet, as a beginner it can be hard to know how to break something down into smaller tasks. If you don't know how to actually build the project then how can you break it down?&lt;/p&gt;

&lt;p&gt;Well the first thing you need to do is look at your project definition and then break it down into smaller parts.&lt;/p&gt;

&lt;p&gt;Let's continue using the calculator app example to make our component cards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculation functions - MVP&lt;/li&gt;
&lt;li&gt;Get user input - MVP&lt;/li&gt;
&lt;li&gt;HTML user interface - MVP&lt;/li&gt;
&lt;li&gt;Style user interface - sprinkles &lt;/li&gt;
&lt;li&gt;JavaScript event listeners - MVP&lt;/li&gt;
&lt;li&gt;Add animations for calculations - sprinkles &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%2Fuploads%2Farticles%2Fc8pdhznp06ranyffza8c.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%2Fuploads%2Farticles%2Fc8pdhznp06ranyffza8c.png" alt="trello board with todo cards from list above"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll notice that for each card, we assigned a label of either MVP or sprinkles this is to visually help you see which cards are the most important and therefore the ones to work on first.&lt;/p&gt;

&lt;p&gt;The biggest benefit of the cards is that they have simplified what we have to do already. This makes projects less intimidating as you are not making a big daunting calculator app, rather you are doing 6 smaller projects that will combine to create one big project.&lt;/p&gt;

&lt;p&gt;As you work on a card you move it into the doing column. Taking your time to get the component working before you move onto the next card.&lt;/p&gt;

&lt;p&gt;But we are not done yet, we can simplify and improve our workflow even more to ensure we are not getting blocked by the size of the project when building.&lt;/p&gt;

&lt;h3&gt;
  
  
  Break each component into smaller checklists
&lt;/h3&gt;

&lt;p&gt;Once we have the high level cards we can then break those components down again into smaller tasks by breaking those tasks into checklists so we can track our progress.&lt;/p&gt;

&lt;p&gt;The example below is just how my brain works so you can break it into smaller or larger items depending on what works for you. Let's use the calculation functions card as an example of how to break a component down further.&lt;/p&gt;

&lt;p&gt;As the task is an MVP task and I have defined the MVP as basic calculations addition, subtraction, multiplication and division we need to add those functions to the checklist.&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%2Fuploads%2Farticles%2Fj89e7xq9op8x8shkhwcg.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%2Fuploads%2Farticles%2Fj89e7xq9op8x8shkhwcg.png" alt="component checklist on kanban card"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have now broken our calculation functions card into 4 little projects that we can work on. How much easier is that than the abstract and super daunting task of building a calculator app, or even writing the calculator functions (the card).&lt;/p&gt;

&lt;p&gt;We can now focus and figure out how to make each of these functions. As we do that we get to check those items off giving us a sense of accomplishment and progress. Then once we have done all four of those items we can move the card into the done column and get cracking on the next card.&lt;/p&gt;

&lt;p&gt;From here on we just need to repeat the process for each card. So you are ready to get building awesome projects. &lt;/p&gt;

&lt;h2&gt;
  
  
  Start building your programming project
&lt;/h2&gt;

&lt;p&gt;Now you have the tools to plan and build a programming project. Hopefully this post has made the concept of building projects less abstract and intimidating.&lt;/p&gt;

&lt;p&gt;The key is to clearly define the project, set up your workflow and then break the project down into smaller components that all build towards creating the larger project. By doing so the project doesn't seem like this enormous mountain to climb, instead it should feel more like a ladder with each step helping you reach your goal.&lt;/p&gt;

&lt;p&gt;If you see someone on r/learnprogramming in the future struggling to get out of tutorial purgatory, don't just tell them to build. Tell them how to plan and build.&lt;/p&gt;

&lt;p&gt;Planning is great, but the key is to then start and build. So go forth and build amazing projects and level up your coding skills.&lt;/p&gt;

&lt;p&gt;I send hot tweets so &lt;a href="https://twitter.com/thelynchpinau" rel="noopener noreferrer"&gt;follow me on twitter,&lt;/a&gt; to save scrolling time, so you have more coding time.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>6 Tactics to Stop Procrastinating Right Now</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Thu, 28 May 2020 10:27:59 +0000</pubDate>
      <link>https://dev.to/peterlunch/6-tactics-to-stop-procrastinating-right-now-54n4</link>
      <guid>https://dev.to/peterlunch/6-tactics-to-stop-procrastinating-right-now-54n4</guid>
      <description>&lt;p&gt;My procrastination problem started in my Undergraduate degree. I was unshackled from structure, no more routine or parents keeping me on task. No, I was my own man. It was a disaster.&lt;/p&gt;

&lt;p&gt;But, I have turned the regret and shame into action and now have my poor habit under control. Thanks to having control of my procrastination habit, I've been able to teach myself enough Python, HTML and CSS to be dangerous in my full time marketing role. &lt;/p&gt;

&lt;p&gt;I wanted to share my 6 favorite techniques for stopping procrastination, to help others out there with the ambition of learning a programing language.&lt;/p&gt;

&lt;p&gt;These tactics are part of my popular post an &lt;a href="https://peterlunch.com/procrastination/"&gt;Ex-Procrastinators: Guide on How to Stop Procrastinating&lt;/a&gt;. Check it out if you want to curb procrastination for the long-term.&lt;/p&gt;

&lt;h2&gt;How to Stop Procrastinating Now&lt;/h2&gt;

&lt;p&gt;Whenever I get into a bit of a rut and notice my bad procrastination habits slipping back in, I go to any of these six techniques to help get me back on track.&lt;/p&gt;

&lt;p&gt;So let's get into them and so we can be more productive, spending less time on dev.to 😜 and more time coding.&lt;/p&gt;

&lt;h3&gt;Tactic 1: Break Your Tasks Down and Gamify Them&lt;/h3&gt;

&lt;p&gt;Procrastinators love to plan. Planning gives the illusion of productivity. In reality it is activity without progress and those mega plans can tend to be more daunting. You need to break down your tasks.&lt;/p&gt;

&lt;p&gt;Breaking down your tasks means turning your big list into small, clear and actionable tasks. Let’s say you have a list of big projects, learn to code, learn linear algebra, start blog, start side hustle and apply for dev jobs. That list is daunting, it is more likely to cause you to delay action. What you need to do is prioritize and break each of those items down.&lt;/p&gt;

&lt;p&gt;If learning to code is you number one priority then you might break it down like so:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Sign up for Freecodecamp account&lt;/li&gt;
    &lt;li&gt;Start Lesson one&lt;/li&gt;
    &lt;li&gt;Summarize lesson one notes&lt;/li&gt;
    &lt;li&gt;Start Lesson two&lt;/li&gt;
    &lt;li&gt;Active recall lesson 1 and 2&lt;/li&gt;
    &lt;li&gt;Etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see how this makes the bigger task of learning to code a lot less daunting, you can easily sign up for an account and start lesson one. Your plan is more effective, clear and each task is more actionable.&lt;/p&gt;

&lt;p&gt;The last step is to gamify them. I have a points system I assign tasks and those points link to rewards. So one task might be worth 5 points because it’s a hard task, once I have 30 points I can go to the movies. The best part is the rewards are guilt free because I’ve done the work and earnt it.&lt;/p&gt;

&lt;h3&gt;Tactic 2: Set Up a Distraction Free Environment&lt;/h3&gt;

&lt;p&gt;Different people function better in certain environments, some prefer the quiet of the library others need the background noise of a cafe. You need to test and learn what works best for you. But, the key to being productive in any environment is eliminating distractions.&lt;/p&gt;

&lt;p&gt;To minimize distractions you have to understand what your distractions are. Here is a list of common distractions:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Phones&lt;/li&gt;
    &lt;li&gt;TV&lt;/li&gt;
    &lt;li&gt;Procrastination Websites (Reddit, YouTube, Facebook, Buzzfeed etc.)&lt;/li&gt;
    &lt;li&gt;People&lt;/li&gt;
    &lt;li&gt;Games&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these distractions will require a different tactic. If your phone is a big distraction, put it on airplane mode then put it in a draw or another room. Can’t help refreshing Reddit, install a website blocker (I use Self Control) and set it whenever you sit down to start working. Is TV a distraction, sell it or less drastically unplug it and put the cord at a friend’s house.&lt;/p&gt;

&lt;p&gt;Identifying and eliminating your distractions is one of the best ways to increase your productivity. You’ll quickly discover those distractions weren’t as enjoyable as the achievement you feel for achieving results.&lt;/p&gt;

&lt;h3&gt;Tactic 3: Do the Hardest Task First&lt;/h3&gt;

&lt;p&gt;Do the hardest task first, the one that makes you the weakest. If you’ve got the whole day  ahead of you, it’s easy to put it off until after you get your coffee, check our email, or finish some quick life admin.&lt;/p&gt;

&lt;p&gt;What do I mean by the hardest, it is the task you’re most likely to procrastinate on. The deadline you’re dreading, the homework you were supposed to do yesterday, the blog post you said you’d write.&lt;/p&gt;

&lt;p&gt;Why first? Because, first thing in the morning your mind is strong, your body is fresh and you haven’t had any external distractions…yet. By knocking out something important on your to-do list before anything else, you get both momentum that you can carry through with you for the rest of the day.&lt;/p&gt;

&lt;p&gt;Set yourself up to do your hardest task tomorrow morning by tonight writing down your three priorities for tomorrow on a postit note. Research has shown doing it the night before is super effective. As soon as you sit down to work before email, before coffee just start the hardest task.The momentum of completing this task will carry you through to the next and the next one after that until you’ve accomplished what you set out to.&lt;/p&gt;

&lt;h3&gt;Tactic 4: Make the Rewards and Consequences More Immediate&lt;/h3&gt;

&lt;p&gt;If you can find a way to make the rewards of not procrastinating and the consequences of procrastinating more immediate then it becomes easier to avoid procrastination. Making either the rewards or the consequences more immediate will help greatly but doing both will rocket you into a god tier anti-procrastinator.&lt;/p&gt;

&lt;p&gt;One of the best ways to make the rewards more immediate is to bring future rewards into the current moment. Say you need to go to the gym, your reward could be watching your favorite TV show while doing cardio, this is known as temptation bundling. Combining the thing you dread with the reward will make you more likely to stop procrastinating.&lt;/p&gt;

&lt;p&gt;One way to make the consequences of procrastination more immediate is by using a commitment device. For example, committing to working on your side hustle with a friend at the library if you don’t show your friend will think you’re a jerk. You could also try paying upfront for personal training sessions, so that the cost of missing a session is instant.&lt;/p&gt;

&lt;p&gt;By making the rewards and consequences of procrastination more immediate you are actively avoiding procrastination.&lt;/p&gt;

&lt;h3&gt;Tactic 5: Enlist Help&lt;/h3&gt;

&lt;p&gt;It can be dangerous to go it alone. One of the best ways to ensure you accomplish what you set out to do is to enlist the help of friends and family.&lt;/p&gt;

&lt;p&gt;For example, get support by telling one of your friends or family about a goal you’re trying to accomplish and then asking them to hold you accountable. Bonus points if you give them money or something you care about to hold onto until you achieve the goal.&lt;/p&gt;

&lt;p&gt;Another way is to enlist the help of deadlines. Let’s say you’re trying to write a blog post a week, then put it on your blog for your readers to see that you publish a new post every week (I’m currently trying this out myself). If I don’t post then my readers think I’m lazy and I’ve missed a deadline leaving me with shame.&lt;/p&gt;

&lt;p&gt;Putting skin in the game and asking others to hold you accountable or scheduling deadlines will help you reduce the odds of procrastinating.&lt;/p&gt;

&lt;h3&gt;Tactic 6: The Pomodoro Technique&lt;/h3&gt;

&lt;p&gt;The Pomo-what? The Pomodoro technique, it’s a time management approach based on working in 25-minute intervals using a timer to keep you accountable.&lt;/p&gt;

&lt;p&gt;Here is how you enlist the pomodoro technique to overcome procrastination.&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;Pick the task you want to work on.&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Set a timer for 25 minutes and work only on that task.&lt;/strong&gt;&lt;/li&gt;
   &lt;li&gt;
&lt;strong&gt;Make notes of all the distractions you experience during the 25 minutes&lt;/strong&gt; on a note-pad – When you first try using the Pomodoro, you will probably be amazed at how often the urge arises to take a quick peek at something non-work-related so just write it down to review later.&lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;Take a 5 minute break&lt;/strong&gt; – surf the web, do whatever you want.&lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;Repeat steps 1 – 4, 2-4 more times, then take a longer break&lt;/strong&gt; where you get up and the environment before coming back to start again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The technique is an effective tool for stopping procrastination as it imposes a short burst of discipline onto you. It is an achievable non-daunting amount of time to focus, rather than saying I’m going to do 8 hours of work today you only have to do 25 minutes which is much more appealing and effective.&lt;/p&gt;

&lt;p&gt;Try a pomodoro session next time you notice yourself putting off a task, tell yourself I’ll just do 25 minutes and you’ll see how you reduce your time procrastinating.&lt;/p&gt;

&lt;h2&gt;Procrastination be gone&lt;/h2&gt;

&lt;p&gt;So there you have it six techniques you can use right now, to stop procrastinating and to start living the productive life you've always wanted.&lt;/p&gt;

&lt;p&gt;Let me know what your tactics are, I'm always looking to improve my anti-procrastination system.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>codenewbie</category>
      <category>career</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
