<?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: ljc-dev</title>
    <description>The latest articles on DEV Community by ljc-dev (@ljcdev).</description>
    <link>https://dev.to/ljcdev</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%2F372406%2Fa85a735c-6425-4063-8a7c-c85950cd25e3.jpg</url>
      <title>DEV Community: ljc-dev</title>
      <link>https://dev.to/ljcdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ljcdev"/>
    <language>en</language>
    <item>
      <title>Introduction to GitFlow</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Mon, 18 Mar 2024 13:58:24 +0000</pubDate>
      <link>https://dev.to/ljcdev/introduction-to-gitflow-45hp</link>
      <guid>https://dev.to/ljcdev/introduction-to-gitflow-45hp</guid>
      <description>&lt;p&gt;Working together on a project can get pretty chaotic. That's where GitFlow comes in 😎!&lt;/p&gt;

&lt;p&gt;GitFlow is a simple &lt;strong&gt;set of branching and merging rules&lt;/strong&gt; for better collaboration, less errors and code conflicts. It's easy to pick up and adapt to your own team's needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  In GitFlow, the main branches are:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Main branch:&lt;/strong&gt; production-ready code. This is where the working version of your project is stored.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Develop branch:&lt;/strong&gt; created from the &lt;strong&gt;main&lt;/strong&gt; branch, it is used for integration and testing of new features or improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Feature branches:&lt;/strong&gt; each new feature/change should be developed on a separate &lt;strong&gt;feature&lt;/strong&gt; branch created from the &lt;strong&gt;develop&lt;/strong&gt; branch, and then merged back into it when ready.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6i2ojtugch3a9nz5darc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6i2ojtugch3a9nz5darc.png" alt="git branching example" width="582" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  More complex projects might also include:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;4. Release branches:&lt;/strong&gt; created from the &lt;strong&gt;develop&lt;/strong&gt; branch, they allow for final testing, bug fixes, without affecting ongoing development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Hotfix branches:&lt;/strong&gt; created from the &lt;strong&gt;main&lt;/strong&gt; branch, to fix critical issues or bugs in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  HowTo GitFlow branching:
&lt;/h3&gt;

&lt;p&gt;Let's say I've created a new repo with a branch &lt;strong&gt;main&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;1- create a &lt;strong&gt;develop&lt;/strong&gt; branch and switch to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- push the &lt;strong&gt;develop&lt;/strong&gt; branch to the remote repository (if needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push -u origin develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- while in the &lt;strong&gt;develop&lt;/strong&gt; branch, create a &lt;strong&gt;feature&lt;/strong&gt; branch and switch to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b feature/your-feature-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4- push the &lt;strong&gt;feature&lt;/strong&gt; branch to the remote repository (if needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push -u origin feature/your-feature-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠ Remember to send your &lt;strong&gt;feature&lt;/strong&gt; branch PRs (pull requests) to the &lt;strong&gt;develop&lt;/strong&gt; branch and not &lt;strong&gt;main&lt;/strong&gt;, and &lt;strong&gt;develop&lt;/strong&gt; branch PRs to the &lt;strong&gt;main&lt;/strong&gt; branch (or a &lt;strong&gt;release&lt;/strong&gt; branch).&lt;/p&gt;

&lt;p&gt;Sometimes you might find &lt;strong&gt;develop&lt;/strong&gt; or &lt;strong&gt;feature&lt;/strong&gt; branches being X commits behind &lt;strong&gt;main&lt;/strong&gt;. It happens when people forget to update the development branches after successfully merging PR(s) into &lt;strong&gt;main&lt;/strong&gt;. The &lt;strong&gt;develop&lt;/strong&gt; and &lt;strong&gt;feature&lt;/strong&gt; branches should be kept up-to-date to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reduce the chance of merge conflicts&lt;/li&gt;
&lt;li&gt;detect integration issues early on&lt;/li&gt;
&lt;li&gt;and for consistency 👍&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So make sure to merge changes from the &lt;strong&gt;main&lt;/strong&gt; branch into your &lt;strong&gt;develop&lt;/strong&gt; and &lt;strong&gt;feature&lt;/strong&gt; branches 😀!&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Git branching commands:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;get a list of all branches:
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;create a new branch:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git branch your-branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;switch to an existing branch:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout your-branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;create a new branch and switch to it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b your-branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;delete a branch:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git branch -d your-branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;push a branch to a remote repository:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push origin your-branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;cloning a specific branch from a remote repository:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone -b your-branch-name your-repository-url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>github</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Introduction to GSAP</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Wed, 22 Sep 2021 21:36:08 +0000</pubDate>
      <link>https://dev.to/ljcdev/introduction-to-gsap-17be</link>
      <guid>https://dev.to/ljcdev/introduction-to-gsap-17be</guid>
      <description>&lt;p&gt;I've made this cover animation with GSAP a year ago as part of my 1st portfolio. It starts playing when the user scrolls to it.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47td3ebmltk662vyq0ra.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47td3ebmltk662vyq0ra.gif" alt="portfolio" width="600" height="386"&gt;&lt;/a&gt;&lt;br&gt;
(Github repo &lt;a href="https://github.com/ljc-dev/portfolio"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;A friend of mine is looking to start playing with GSAP so I've put together this short introduction to GSAP animations 🙃.&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction to GSAP
&lt;/h2&gt;

&lt;p&gt;First of all, why GSAP? I've played with a lot of other animation libraries in the past like Framer motion, react-spring, etc. This one stood out the most because of its ease of use and the range of animations it covers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The GreenSock Animation Platform (GSAP) animates anything JavaScript can touch (CSS properties, SVG, React, canvas, generic objects, whatever) and solves countless browser inconsistencies, all with blazing speed (up to 20x faster than jQuery).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, I'm not saying it's the best - I haven't tested Three.js or Anime.js - but I promise it's worth getting to know it through this little guide. (Not gonna lie, it's pretty awesome 😄.)&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up GSAP
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ojvuztnh7kbker26i63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ojvuztnh7kbker26i63.png" alt="gsap install" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To use GSAP, download their zip file or copy their CDN/npm code at &lt;a href="https://greensock.com/docs/v3/Installation"&gt;https://greensock.com/docs/v3/Installation&lt;/a&gt; or test it in Codepen with their &lt;a href="https://codepen.io/GreenSock/pen/aYYOdN"&gt;GSAP Starter Template&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extra Plugins&lt;/strong&gt; are free. &lt;strong&gt;Club Plugins&lt;/strong&gt; aren't, but you can still test them out in Codepen.&lt;/p&gt;

&lt;p&gt;I'll touch on how to add and use a plugin in a moment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Initialize GSAP
&lt;/h2&gt;

&lt;p&gt;Actually, there's nothing to initialize 😂. The GSAP script exposes a &lt;code&gt;gsap&lt;/code&gt; variable which we are going to use for all animations.&lt;/p&gt;

&lt;p&gt;So let's start animating!&lt;/p&gt;
&lt;h2&gt;
  
  
  First animation
&lt;/h2&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/NWgBKqg?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
(Click on Rerun to repeat the animation)&lt;/p&gt;

&lt;p&gt;All the js I needed to create this translation effect is this line:&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="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;to()&lt;/code&gt; method animates one or more elements from their current state to a new state.&lt;/p&gt;

&lt;p&gt;The first parameter is the object(s) you are animating. It can be an object, an array of objects or a &lt;strong&gt;CSS selector&lt;/strong&gt;. In this example its targets are all the elements with the class of square. To add more targets in a selector, separate them with a comma:&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="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square, .rect&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 2nd parameter takes an object of property/value pairs that you're animating. You can animate &lt;strong&gt;all the CSS properties&lt;/strong&gt; from margins, paddings to font-size, line-height. &lt;/p&gt;

&lt;p&gt;In this example I'm animating &lt;code&gt;x: 200&lt;/code&gt; which is a GSAP shorthand for &lt;code&gt;translateX: 200&lt;/code&gt;. And 200 means 200px. You can also use the other CSS units like &lt;code&gt;x: "100%"&lt;/code&gt;, &lt;code&gt;x: "20em"&lt;/code&gt; , &lt;code&gt;x: "20rem"&lt;/code&gt; , etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Warning&lt;/em&gt;: unlike CSS, Javascript doesn't allow compound name. You'll have to use camel case instead. For example: &lt;code&gt;fontSize&lt;/code&gt;, &lt;code&gt;backgroundColor&lt;/code&gt; and &lt;code&gt;translateX&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;duration&lt;/strong&gt; is a special GSAP property. It represents the duration of the animation (in seconds). Default: 0.5. There are other special properties like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;delay&lt;/strong&gt;: Amount of delay before the animation should begin (in seconds).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ease&lt;/strong&gt;: Controls the rate of change during the animation, giving it a specific feel. For example, "elastic" or "strong.inOut". See the &lt;a href="https://greensock.com/docs/v3/Eases"&gt;Ease Visualizer&lt;/a&gt; for a list of all of the options. Default: "power1.out".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;repeat:&lt;/strong&gt; Number of times that the animation should repeat after its first iteration. -1 for infinite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check the list of all special properties &lt;a href="https://greensock.com/docs/v3/GSAP/Tween/vars"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;Note&lt;/em&gt;: GSAP call their animations &lt;strong&gt;tweens&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Animate on click
&lt;/h2&gt;

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

&lt;p&gt;The code is self-explanatory. I've only moved the gsap line above inside a function that gets called on button click.&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;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;What if I wanted to animate from these values instead of to? Easy! Just replace &lt;code&gt;to()&lt;/code&gt; with &lt;code&gt;from()&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;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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/ljc-dev/embed/yLXqNaE?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;And now the square goes from &lt;code&gt;x: 200&lt;/code&gt; to its default position.&lt;/p&gt;

&lt;p&gt;What if you wanted to immediately set some properties without animation? Replace &lt;code&gt;to()&lt;/code&gt; with &lt;code&gt;set()&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;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;Noticed how I've removed &lt;code&gt;duration&lt;/code&gt;? It wouldn't have broke the code if I left it but it would have been ignored either way.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;set()&lt;/code&gt; is also useful for properties that have no animations like display, z-index, transform-origin:&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="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.mySVG&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;transformOrigin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50% 50%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding a delay
&lt;/h2&gt;

&lt;p&gt;How do we add a delay between animations? &lt;/p&gt;

&lt;p&gt;For simple cases we can just add a delay to later animations like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.circle&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;delay&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;But what if we were adding a dozen animations? Adding incremental delays everywhere would be a nightmare. Even if you were good at Maths, if you ever need to tweak one animation, you'll have to update all the later animations.&lt;/p&gt;

&lt;p&gt;The solution is to use timelines. Timeline in GSAP is a sequencing tool for chaining animations.&lt;/p&gt;

&lt;p&gt;Create a timeline with &lt;code&gt;timeline()&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;tl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use it we only need to replace &lt;code&gt;gsap&lt;/code&gt; with the timeline variable:&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;tl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.circle&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;I've removed the delay from the 2nd animation. We don't need it anymore because it'll start automatically after the first one.&lt;/p&gt;

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

&lt;p&gt;Last but not least, there's a really cool way to add delay for animation: &lt;strong&gt;stagger&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Staggers make it easy to animate a group of objects with a small delay between the start of each object's animation:&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;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stagger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.15&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/ljc-dev/embed/qBjyaJL?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Here's a better stagger animation by &lt;a href="https://www.twitter.com/kbyebea"&gt;Beatrize Agustin&lt;/a&gt;.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Gotcha
&lt;/h3&gt;

&lt;p&gt;Before GSAP v3.0, an animation (tween) was created with &lt;code&gt;TweenMax&lt;/code&gt; , a timeline with &lt;code&gt;TimelineMax&lt;/code&gt;. You might find a lot of examples (like the one above) with the old syntax. When in doubt, check the docs 👍.&lt;/p&gt;

&lt;h2&gt;
  
  
  Controlling the animation
&lt;/h2&gt;

&lt;p&gt;GSAP packed some really neat and easy to use controls: &lt;code&gt;play()&lt;/code&gt;, &lt;code&gt;pause()&lt;/code&gt;, &lt;code&gt;resume(),&lt;/code&gt;  &lt;code&gt;restart()&lt;/code&gt;, &lt;code&gt;reverse()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Those controls can be used with a timeline or an instance of an animation. &lt;/p&gt;

&lt;p&gt;GSAP's &lt;code&gt;to()&lt;/code&gt; and &lt;code&gt;from()&lt;/code&gt; returns an instance of the animation. We can save it in a variable and use it to control the animation.&lt;/p&gt;

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

&lt;p&gt;(Example from GSAP)&lt;/p&gt;

&lt;p&gt;If you've played with the blue square codepens above, you've probably noticed how the animations only played once. And clicking on the button didn't restart the animation. That can be fixed with:&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;animation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;   &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;paused&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;restart&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;Thanks to &lt;code&gt;restart()&lt;/code&gt; the animation will repeat every time the button is clicked. &lt;/p&gt;

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

&lt;p&gt;The special property &lt;code&gt;paused: true&lt;/code&gt; prevent the animation from playing before we click on the button.&lt;/p&gt;

&lt;p&gt;Same with timeline:&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;tl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.square&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.circle&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;duration&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animateOnClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;restart&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/ljc-dev/embed/QWgBqBr?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If we only wanted the timeline animation to play once, we could use &lt;code&gt;play()&lt;/code&gt; instead. &lt;/p&gt;

&lt;h2&gt;
  
  
  Using a plugin
&lt;/h2&gt;

&lt;p&gt;To add a plugin, go to  &lt;a href="https://greensock.com/docs/v3/Installation"&gt;https://greensock.com/docs/v3/Installation&lt;/a&gt; , pick one and add the code to your project. The codepen &lt;a href="https://codepen.io/GreenSock/pen/aYYOdN"&gt;GSAP Starter Template&lt;/a&gt; already includes all the plugins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ojvuztnh7kbker26i63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ojvuztnh7kbker26i63.png" alt="install page" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm going to go with the scrollTrigger which I've used for my portfolio. It's a very popular (free) plugin for scroll-based animations.&lt;/p&gt;

&lt;p&gt;First we need to register the plugin to gsap:&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="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ScrollTrigger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use the special property scrollTrigger like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.myImg&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;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.myImg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;That's it for this intro to GSAP. To learn more about scrollTrigger watch the official tutorial &lt;a href="https://www.youtube.com/watch?v=X7IBa7vZjmo"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading! And I hope I've got you hooked. I've barely scratched the surface of what's possible with GSAP.&lt;/p&gt;

&lt;p&gt;Now I'll leave you with one of the best GSAP animation from &lt;a href="https://twitter.com/@jh3yy"&gt;Jhey&lt;/a&gt;: &lt;/p&gt;

&lt;p&gt;Try clicking on the switch 😉.&lt;/p&gt;

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

</description>
      <category>tutorial</category>
      <category>beginners</category>
      <category>javascript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>How to create a newsletter with Mailchimp (not affiliated/ad).</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sun, 19 Sep 2021 22:06:31 +0000</pubDate>
      <link>https://dev.to/ljcdev/how-to-create-a-newsletter-with-mailchimp-not-affiliated-ad-4m82</link>
      <guid>https://dev.to/ljcdev/how-to-create-a-newsletter-with-mailchimp-not-affiliated-ad-4m82</guid>
      <description>&lt;p&gt;For dev bloggers looking to grow an audience.&lt;/p&gt;

&lt;p&gt;A newsletter is an indispensable communication tool for building relationships with your readers.&lt;/p&gt;

&lt;p&gt;Mailchimp is one of the most popular newsletter tool out there - with a generous free tier of 2000 contacts and 10 000 emails/month. Yet new users can find it quite daunting to get started with because of all the services it offers. It's a swiss army knife like AWS. You can go from creating a simple survey, to building landing pages or even a full-fledge e-commerce store. They have docs, but you could easily spend the whole day jumping from one guide to another and googling for more information like how to prevent your home address from being revealed to your readers.&lt;/p&gt;

&lt;p&gt;But worry not 😁! In this short guide, you'll learn everything you need to start your first newsletter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create and Setup a Mailchimp account
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgc8tqjj7yhkstxcwyjag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgc8tqjj7yhkstxcwyjag.png" alt="Mailchimp sign up" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;a href="https://login.mailchimp.com/signup/"&gt;Mailchimp Sign Up&lt;/a&gt; page and fill the form.
No credits card or phone number required.&lt;/li&gt;
&lt;li&gt;Go to your confirmation mail and click the activation link.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might have to pass a robot test. We can now start setting up the account.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4vnzfrzv1bgqpker5gsf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4vnzfrzv1bgqpker5gsf.png" alt="Choose free plan" width="800" height="633"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose Free plan ( 2000 contacts and 10 000 emails send / month ) and click &lt;strong&gt;Next&lt;/strong&gt;
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13srimicjmoivq9kacya.png" alt="Fill form" width="800" height="491"&gt;
&lt;/li&gt;
&lt;li&gt;Fill in your first name, last name and a business name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't have a business name you can just use your name.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj09xwaiworls3dlw5u5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj09xwaiworls3dlw5u5b.png" alt="fill in address" width="800" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fill in your address. Apparently it's required by anti-spam laws.
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1k2ui0b4t78w2nho1n1l.png" alt="contacts" width="800" height="432"&gt;
&lt;/li&gt;
&lt;li&gt;Pick No if you don't have any contacts to import.
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbf9psrv7vna85ll5rdv.png" alt="Customize" width="800" height="417"&gt;
&lt;/li&gt;
&lt;li&gt;Finish customizing.
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fduiewl201r0g9xmv94dm.png" alt="Done setting up" width="800" height="491"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Done!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create a Sign Up form
&lt;/h2&gt;

&lt;p&gt;After the setup is complete, you are redirected to the dashboard.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi01lfblr2lucti5i44nq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi01lfblr2lucti5i44nq.png" alt="Dashboard" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the audience icon which is the 3rd one on the left, right below the pencil icon, then Signup forms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To add a subscription form to your website you only need to get familiar with the first two sections:&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;strong&gt;Form builder&lt;/strong&gt;: where you personalize your sign up form ( and other forms like confirmation emails).&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;strong&gt;Embedded forms&lt;/strong&gt;: where you get the embed code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click on &lt;strong&gt;Form builder.&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuexvnv530az4gzgatljy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuexvnv530az4gzgatljy.png" alt="sign up form" width="800" height="892"&gt;&lt;/a&gt;&lt;br&gt;
The default template has way too many fields. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on each field you don't need and delete them.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuyoosit1tiql7e1rtwr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuyoosit1tiql7e1rtwr.png" alt="only email address field left" width="800" height="518"&gt;&lt;/a&gt;&lt;br&gt;
In this example, I've removed every field other than the email address. We are now ready to embed the form.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Get the embed code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsox50hoy94l6aiptfc7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsox50hoy94l6aiptfc7j.png" alt="embedded form" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Get back to the Signup form menu and choose &lt;strong&gt;Embedded forms.&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1lzjfxx63k6k4rtuwyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1lzjfxx63k6k4rtuwyq.png" alt="classic embed code" width="800" height="896"&gt;&lt;/a&gt;&lt;br&gt;
By default Mailchimp has added its own CSS. If you are ok wih how it looks, copy this code.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftc1u36t102z7wt0yuvl3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftc1u36t102z7wt0yuvl3.png" alt="unstyled embed code" width="800" height="448"&gt;&lt;/a&gt;&lt;br&gt;
If not, switched to the &lt;strong&gt;Unstyled&lt;/strong&gt; tab and you'll get the CSS-free version.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4y0f87oqv3m2g8wjhiv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4y0f87oqv3m2g8wjhiv.png" alt="forms options" width="800" height="448"&gt;&lt;/a&gt;&lt;br&gt;
I only need the email address and the subscribe button. So in the form options on the left, I've removed everything else.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Add it to your website
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xfxofvopugikgrp34un.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xfxofvopugikgrp34un.png" alt="codepen live testing" width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;
I've pasted the code in Codepen to test it.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk88iyvcfv1yhokgf8i6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk88iyvcfv1yhokgf8i6.png" alt="confirmation page with address" width="800" height="374"&gt;&lt;/a&gt;&lt;br&gt;
On submit, I'm redirected to a confirmation thank you page. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything works! The only problem is, my address is shown in the confirmation message 😱.&lt;/p&gt;

&lt;p&gt;If you have a business address, you wouldn't mind it but I'm not that ok with showing my home address over the net 😅.&lt;/p&gt;

&lt;p&gt;If you want to hide it too, go back to Form Builder (Audience &amp;gt; Signup forms).&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58abuvx6badv1hxopfox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58abuvx6badv1hxopfox.png" alt="remove address" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the top switch from &lt;strong&gt;Signup form&lt;/strong&gt; to &lt;strong&gt;Confirmation thank you page.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Then add a redirect thank you page and save. Mailchimp will redirect there instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't want to create a thank you page in your website you can just redirect to the home page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OR if you don't add your own redirect page, you could edit the Mailchimp form and remove the bottom section.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;*|&lt;/span&gt;&lt;span class="nx"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;LIST_ADDRESS_HTML&lt;/span&gt;&lt;span class="o"&gt;|*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the part that Mailchimp use to add in the address.&lt;/p&gt;

&lt;p&gt;I don't recommend this method because while the address is not visible here, if the user happens to click on the Mailchimp button &lt;strong&gt;manage your preferences&lt;/strong&gt;, they'll land in a page where your address is exposed.&lt;/p&gt;

&lt;h3&gt;
  
  
  That's it!
&lt;/h3&gt;

&lt;p&gt;Now you are ready to start blasting ads... I mean engaging with your precious community 😁.&lt;/p&gt;

&lt;p&gt;Peace.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>beginners</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Top 5 design mistakes web developers make (and how to avoid them).</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Fri, 17 Sep 2021 19:40:47 +0000</pubDate>
      <link>https://dev.to/ljcdev/top-5-design-mistakes-web-developers-make-and-how-to-avoid-them-2bla</link>
      <guid>https://dev.to/ljcdev/top-5-design-mistakes-web-developers-make-and-how-to-avoid-them-2bla</guid>
      <description>&lt;p&gt;&lt;em&gt;For Web Developers at the start of their journey, curious about design.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Design is an art. As such there's no right or wrong 😤!&lt;/p&gt;

&lt;p&gt;With that said, here are the most common beginner mistakes I see 😄.&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - Too many colors.
&lt;/h2&gt;

&lt;p&gt;This is by far the most common mistake new devs make. And I get it. Black and white is too dull for the enlightened CSS dev. Can't help enhancing the page with &lt;code&gt;background-image&lt;/code&gt; and &lt;code&gt;background-color&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnpkrbryd7g524ag1id3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnpkrbryd7g524ag1id3.png" alt="multicolored page" width="567" height="520"&gt;&lt;/a&gt;&lt;br&gt;
So, what's wrong with this?&lt;/p&gt;

&lt;p&gt;Well, it's like being hit by a wall of light 😆. Every color is fighting for the spotlight. There's no way the users can focus on the content. &lt;/p&gt;

&lt;p&gt;This example is extreme. But my point is, colors are really eye-catching. If you use too many, you might confuse and even annoy your readers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use less colors.
Consider removing any colors that doesn't have any meaning behind it or decreasing their intensity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2onjxpxxy0ib60jqhx99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2onjxpxxy0ib60jqhx99.png" alt="less color page" width="551" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use colors that go well with each other.&lt;/p&gt;

&lt;p&gt;I know it's super hard to pick colors at first. It was my number one struggle beside centering divs. &lt;/p&gt;

&lt;p&gt;How to be better at picking colors? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Just browse around for inspiration and bookmark the sites you like.&lt;/li&gt;
&lt;li&gt;Look for color palette websites. My favorite one is &lt;a href="https://colorhunt.co/palettes/popular"&gt;colorHunt&lt;/a&gt;.
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57grxwbfztbid1cxt7qb.png" alt="palette colors" width="569" height="520"&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2 - Gradients.
&lt;/h2&gt;

&lt;p&gt;Nothing screams amateur more than a big awkward gradient.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdeg668kxq52s5255h7n5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdeg668kxq52s5255h7n5.png" alt="ugly-ish gradient" width="541" height="498"&gt;&lt;/a&gt;&lt;br&gt;
What's wrong with gradients? Nothing. Only that they really grab the users' attention. So it's a big turn off if they are ugly or don't fit with the overall design.&lt;/p&gt;

&lt;p&gt;There's a reason 99% of the pages you visit don't use gradients.&lt;/p&gt;

&lt;p&gt;Now, I'm not saying gradients are bad and you shouldn't use them - I can almost hear the "booo, gatekeeper!" - but rather you might want to think twice about how your &lt;code&gt;background: linear-gradient(...)&lt;/code&gt; button, that changes colors on hover and focus, fits with the rest of the page 😄.&lt;/p&gt;

&lt;p&gt;Plus it's just hard to make a nice gradient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trust the stats, use sparingly 🤭.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://mycolor.space/gradient"&gt;colorSpace&lt;/a&gt; to make better gradients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3 - Not enough contrast difference between text and background.
&lt;/h2&gt;

&lt;p&gt;Related to the 1st point. Because black and white text is too boring we get things like:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftn489dz12suij1jtf4jd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftn489dz12suij1jtf4jd.png" alt="multicolored pages" width="800" height="406"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Go easy with your newly found powers 😁.&lt;/p&gt;

&lt;p&gt;In most cases, it's a good idea to keep the text black or white, especially for lenghty text. The world is not ready for multicolored text yet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add contrast between the background color and the text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9lzvaij9e0hn6puygtn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9lzvaij9e0hn6puygtn.png" alt="button" width="265" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also check contrast with &lt;a href="https://accessible-colors.com/"&gt;Accessible Colors&lt;/a&gt;. They'll tell you if your text would be hard to read for some and suggest alternative colors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd6k8p9amq2qmk6p3xo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd6k8p9amq2qmk6p3xo1.png" alt="accessible colors" width="796" height="637"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add contrast to the text above the image.&lt;/p&gt;

&lt;p&gt;Darken the image using filter or an overlay.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rdxyrcbch9j00bzgsig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rdxyrcbch9j00bzgsig.png" alt="overlay" width="532" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or wrap the text in a semi-transparent/white container.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5lru3kbm38footbqhcix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5lru3kbm38footbqhcix.png" alt="white container" width="800" height="792"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4 - Misalignments and spacing.
&lt;/h2&gt;

&lt;p&gt;Everyone make those mistakes. Then as we build more, we become more mindful of how the elements we create should fit with other elements to create a more coherent design.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo80e1rwklf195wkjksr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo80e1rwklf195wkjksr2.png" alt="misalignment" width="800" height="1015"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every element you add should be connected with another element or both sides of the page.&lt;/li&gt;
&lt;li&gt;Keep the spacing consistent.&lt;/li&gt;
&lt;li&gt;Keep building more projects. Seriously, there are no shortcuts.&lt;/li&gt;
&lt;li&gt;Get feedback and/or compare with your favorite websites. (It would also make nice trainings to clone those websites.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5 - Inconsistent headers
&lt;/h2&gt;

&lt;p&gt;Avoid making headers too big compared to the text around them.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ssq4qpzz6igin315wu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ssq4qpzz6igin315wu5.png" alt="headers" width="800" height="282"&gt;&lt;/a&gt;&lt;br&gt;
Also most of the time, one to two font families is enough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An easily readable font for lengthy text.&lt;/li&gt;
&lt;li&gt;And perhaps a more fancy font for headers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fonts.google.com/"&gt;Google Fonts&lt;/a&gt; is your friend👌.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  That's it!
&lt;/h3&gt;

&lt;p&gt;I hope you've found this short guide useful. If you are making any of the mistakes above, it's super fine. I've made them all 😂. Keep building 💪!!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>css</category>
      <category>design</category>
    </item>
    <item>
      <title>Introduction to scroll animations with Intersection Observer</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sat, 06 Feb 2021 09:14:47 +0000</pubDate>
      <link>https://dev.to/ljcdev/introduction-to-scroll-animations-with-intersection-observer-d05</link>
      <guid>https://dev.to/ljcdev/introduction-to-scroll-animations-with-intersection-observer-d05</guid>
      <description>&lt;p&gt;The Intersection Observer (IO) detects when an element enters or leaves the viewport (or a parent element). It can be used to easily add animation on scroll without external libraries.&lt;/p&gt;

&lt;p&gt;IO is asynchronous and much more performant than scroll listeners 👍.&lt;/p&gt;

&lt;p&gt;Btw, if you learn better through videos, I highly suggest this &lt;a href="https://www.youtube.com/watch?v=T8EYosX4NOo"&gt;youtube tutorial&lt;/a&gt; by Kewin Powell.&lt;/p&gt;

&lt;p&gt;Here's a basic example of a fade in animation on scroll using the intersection observer.&lt;/p&gt;

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

&lt;p&gt;In this example we fade in an image on scroll by adding the class &lt;code&gt;fadeIn&lt;/code&gt;  to it when it enters the viewport. This is the js:&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;img&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&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;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;observer&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;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entry&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;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fadeIn&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&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;myObserver&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;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy, right? Let's get started 😁!&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating an intersection observer
&lt;/h1&gt;

&lt;p&gt;First, we create an intersection observer by calling its constructor and passing it a callback function and an optional options object.&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;myObserver&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;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The options
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;options&lt;/code&gt; is an object with 3 properties:&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;rootMargin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;threshold&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;In my fade in example, I've returned an empty object &lt;code&gt;{}&lt;/code&gt; so the default options will apply. (Same with not return anything. )&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;root&lt;/strong&gt;: default &lt;code&gt;null&lt;/code&gt;.  it's the viewport. Can be the document or an HTML element. If the root is &lt;code&gt;null&lt;/code&gt;, defaults to &lt;code&gt;document&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rootMargin&lt;/strong&gt;: default 0px. defines the offsets of each side of the root's bounding box. In other words, positive values reduce the root bounding box and negative values increase it. Try scrolling the 3 boxes in this example.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Similar to CSS's margin syntax: "0px 5px 10px 15px" means top: 0px, right: 5px, bottom: 10px and left: 0px. Accepts px and % only. ⚠ 0 is not an accepted value, use 0px or 0% instead.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;threshold:&lt;/strong&gt;  default 0. The threshold is a number between 0 and 1.0. 
0 meaning as soon as one pixel is visible, the callback will be run.  1.0  means every pixel needs to be visible before calling the callback. (⚠ If you set the threshold to 1 and the element is bigger than the root, the number won't reach 1 because there will be some parts invisible at all time.)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  The callback
&lt;/h2&gt;

&lt;p&gt;The callback function takes a list of entries and an intersection observer as parameter.&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;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;observer&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;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&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;// Each entry describes an intersection change for one observed&lt;/span&gt;
    &lt;span class="c1"&gt;// target element:&lt;/span&gt;
    &lt;span class="c1"&gt;//   entry.boundingClientRect&lt;/span&gt;
    &lt;span class="c1"&gt;//   entry.intersectionRatio&lt;/span&gt;
    &lt;span class="c1"&gt;//   entry.intersectionRect&lt;/span&gt;
    &lt;span class="c1"&gt;//   entry.isIntersecting&lt;/span&gt;
    &lt;span class="c1"&gt;//   entry.rootBounds&lt;/span&gt;
    &lt;span class="c1"&gt;//   entry.target&lt;/span&gt;
    &lt;span class="c1"&gt;//   entry.time&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;strong&gt;observer&lt;/strong&gt; can be used to dynamically add or remove elements to observe. More on it below.&lt;/p&gt;

&lt;p&gt;The focus is on the list of &lt;strong&gt;entries&lt;/strong&gt;. There is one entry object for each observed element. It's common practice to use &lt;code&gt;forEach&lt;/code&gt; to iterate.&lt;/p&gt;

&lt;p&gt;Each entry has the following helpful properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;entry.isIntersecting&lt;/code&gt; returns a boolean. True means the element is currently intersecting with the root.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;entry.target&lt;/code&gt; returns the observed element.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've used them both in the fadeIn animation:&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;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;observer&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;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entry&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;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fadeIn&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;entry.boundingClientRect&lt;/code&gt; returns the bounds rectangle of the observed element.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;entry.intersectionRatio&lt;/code&gt; returns a number between 0.0 and 1.0 which indicates how much of the observed element is actually visible within the root.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Etc. 😁 I've named the most important ones. You can find a list of all the entry properties &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Select elements to be observed
&lt;/h2&gt;

&lt;p&gt;To select an element to observe, we use the &lt;strong&gt;observe()&lt;/strong&gt; method of our Intersection Observer.&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="nx"&gt;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Now &lt;code&gt;myObserver&lt;/code&gt; will detect when &lt;code&gt;img&lt;/code&gt; enters or leave the viewport and trigger the callback.&lt;/p&gt;

&lt;p&gt;If you want to observe many elements, you have to add them one by one.&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="nx"&gt;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or by giving them a common class and iterate with &lt;code&gt;forEach&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;imgList&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;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.imgToAnimate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// setting your observer here&lt;/span&gt;

&lt;span class="nx"&gt;imgList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&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;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&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;To stop observing, call &lt;code&gt;unobserve()&lt;/code&gt; on the element:&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="nx"&gt;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unobserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To stop observing every element at once call &lt;code&gt;disconnect()&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="nx"&gt;myObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use those methods in the callback:&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;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;observer&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;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entry&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;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fadeIn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;// stop observing this element&lt;/span&gt;
      &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unobserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit: It's a good practice to unobserve an element after we are done playing with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's it!
&lt;/h2&gt;

&lt;p&gt;I hope you've enjoyed this short intro on Intersection Observer 😃. &lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API"&gt;MDN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beside animating on scroll, it can be used to improve render speed and First Contentful Paint with lazy loading of scripts and media.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the basics
&lt;/h2&gt;

&lt;p&gt;Here are a few examples of scroll animations with IO. I'll try to write a blog on each when I find some time 😅.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter &amp;amp; Leave Anim
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Scroll To Top
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Update current tab on scroll
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  And more to come 😁!
&lt;/h3&gt;

</description>
      <category>tutorial</category>
      <category>codenewbie</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Review on AOS (animation on scroll) and Rellax (parallax)</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sun, 17 Jan 2021 15:44:12 +0000</pubDate>
      <link>https://dev.to/ljcdev/review-on-rellax-for-parallax-and-aos-animate-on-scroll-jf4</link>
      <guid>https://dev.to/ljcdev/review-on-rellax-for-parallax-and-aos-animate-on-scroll-jf4</guid>
      <description>&lt;p&gt;AOS is a very popular scroll animation library but it has some unexpected shortcomings with responsive design. Rellax is a rising star for parallax animations on desktop and mobile.&lt;/p&gt;

&lt;p&gt;I wrote this short review after playing with both on a react website project.&lt;/p&gt;

&lt;h1&gt;
  
  
  AOS (Animate on Scroll)
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://michalsnik.github.io/aos" rel="noopener noreferrer"&gt;AOS&lt;/a&gt; is an animation library that handles all the scroll logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Super easy to implement.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just add a data attribute &lt;code&gt;data-aos&lt;/code&gt; with an animation class like &lt;code&gt;fade-up&lt;/code&gt; to have a fade up animation.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 html
&amp;lt;div data-aos="fade-up"&amp;gt;&amp;lt;/div&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;AOS has a lot of built-in animations classes like &lt;code&gt;fade-up&lt;/code&gt;, &lt;code&gt;fade-in&lt;/code&gt;, &lt;code&gt;zoom-in&lt;/code&gt;, &lt;code&gt;flip-up&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We only need to initialize AOS in js and our div will fade up when it enters the viewport.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 js
 AOS.init();


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

&lt;/div&gt;

&lt;p&gt;You can add custom animations too:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 css
[data-aos="my-fade-up"] {
  transform: translate3d(0, 100px, 0);
  opacity: 0;
  transition-property: transform, opacity;
}

[data-aos="my-fade-up"].aos-animate {
  transform: translate3d(0, 0, 0);
    opacity: 1;
}


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

&lt;/div&gt;

&lt;p&gt;You can customize with data attributes to change the animation duration, delay, or add an anchor, offset, etc.&lt;/p&gt;

&lt;p&gt;In my project, I used AOS for fade in and up animations:&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%2Fks3oscghzt73z2hzxlql.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%2Fks3oscghzt73z2hzxlql.gif" alt="aos fade in and up"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;No built-in responsive design support.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want an animation to play only on mobile, you need to create your own. Say you want the built-in class &lt;code&gt;fade-up&lt;/code&gt; to play on desktop but not on mobile. Well you can't 😅. You need to write your own fade-up with media query like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 css
@media (min-width:1024px) {
  [data-aos="my-fade-up"] {
    transform: translate3d(0, 100px, 0);
    opacity: 0;
    transition-property: transform, opacity;
  }

  [data-aos="my-fade-up"].aos-animate {
    transform: translate3d(0, 0, 0);
      opacity: 1;
  }
}


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Verdict on AOS
&lt;/h3&gt;

&lt;p&gt;If you don't know - or don't want - to handle scroll logic and create animations yourself, AOS is a real time saver!&lt;/p&gt;

&lt;p&gt;Not a great pick for users who need to disable or show different animations depending on screen sizes.&lt;/p&gt;

&lt;p&gt;An alternative would be to create CSS animations ourselves and use the intersection observer API to listen to scroll. I've made an introduction post on it &lt;a href="https://dev.to/posts/introduction-to-scroll-animations-with-intersection-observer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;There's a lightweight library built upon it with &lt;a href="https://github.com/mciastek/sal" rel="noopener noreferrer"&gt;sal.js&lt;/a&gt; that I'm really looking forward to play with.&lt;/p&gt;
&lt;h1&gt;
  
  
  Rellax
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://dixonandmoe.com/rellax/" rel="noopener noreferrer"&gt;Rellax&lt;/a&gt; is a parallax library that works in both desktop &amp;amp; mobile (parallax is famous for not working on mobile).&lt;/p&gt;
&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Super easy to implement&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a class to an element:
```

html

I’m slow and smooth
 &lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
* And initialize rellax by referring to that class in js: 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 js&lt;br&gt;
var rellax = new Rellax('.rellax'); &lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
With reactJS, you can use refs instead of classes.

* Customizable with data attributes. 

For example, the following code is used to play the parallax at different speed on mobile and pc:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 html&lt;/p&gt;

&lt;p&gt;I’m slow on mobile but fast on pc!&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
I've used it for the hero section of my site:

![hero section](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4kun9qkjc87fmcmd3ya.gif)

### Cons

The only downside is that sometimes the animation can be *jumpy*.

![jumpy image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5r7xgo8kug84ase0dzmw.gif)

It gets much worse when trying to record it (My AMD processor is like an old i3 😄).

### Verdict on Rellax

If you tried parallax before, you know how hard it is to get parallax working on mobile. Rellax is a real time saver if you don't mind occasional jumps 😅.

An alternative would be to use gsap with [scrollTrigger plugin](https://greensock.com/scrolltrigger).

### Thanks for reading 😄✨!!

Please share what you agree &amp;amp; disagree on.

And tell me what js/react libraries you use the most 😍.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>Introduction to CSS Animations</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Tue, 15 Sep 2020 20:18:52 +0000</pubDate>
      <link>https://dev.to/ljcdev/introduction-to-css-animation-4762</link>
      <guid>https://dev.to/ljcdev/introduction-to-css-animation-4762</guid>
      <description>&lt;p&gt;So you want to animate with CSS? Great, let's get started 😄!&lt;/p&gt;

&lt;p&gt;Most properties can be animated: &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;opacity&lt;/code&gt;, &lt;code&gt;transform&lt;/code&gt;, etc. In this tutorial, we are going to focus on &lt;code&gt;transform&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With CSS &lt;code&gt;transform&lt;/code&gt; we can rotate, scale, skew, or translate an html element.&lt;/p&gt;

&lt;p&gt;Try hovering ( or clicking if you are on mobile) on the ninja images:&lt;/p&gt;

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

&lt;p&gt;No animations yet. Here's the code:&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;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ninja1"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://ljc-dev.github.io/fluffy-octo-adventure/nin.png"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ninja2"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://ljc-dev.github.io/fluffy-octo-adventure/nin.png"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ninja3"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://ljc-dev.github.io/fluffy-octo-adventure/nin.png"&lt;/span&gt;&lt;span class="nt"&gt;&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;img&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;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&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;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;object-fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.ninja1&lt;/span&gt;&lt;span class="nd"&gt;:hover&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;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;.ninja2&lt;/span&gt;&lt;span class="nd"&gt;:hover&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;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.ninja3&lt;/span&gt;&lt;span class="nd"&gt;:hover&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;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;45deg&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;On hover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;translateY(50px)&lt;/code&gt; moves &lt;em&gt;ninja1&lt;/em&gt; 50px down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;scale(1.5)&lt;/code&gt; makes &lt;em&gt;ninja2&lt;/em&gt; 1.5 times bigger.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;rotate(45deg)&lt;/code&gt; rotates &lt;em&gt;ninja3&lt;/em&gt; 45deg clockwise.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transitions
&lt;/h3&gt;

&lt;p&gt;Now let's see how we can animate those transformations with &lt;em&gt;CSS transitions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A transition animates the changes of one or multiple properties.&lt;/p&gt;

&lt;p&gt;We add a 2s transition on &lt;code&gt;transform&lt;/code&gt; with the following:&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;.ninja1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2s&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;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;transition-property&lt;/code&gt; takes the name of the property to add a transition to. We can add multiple properties with the keyword &lt;code&gt;all&lt;/code&gt; or separating each property with commas like &lt;code&gt;transition-property: transform, opacity&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;transition-duration&lt;/code&gt; sets the duration of the transition.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can also use the shorthand &lt;code&gt;transition&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;.ninja1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code and the one above are the same. &lt;/p&gt;

&lt;p&gt;We get an animation on hover:&lt;/p&gt;

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

&lt;p&gt;We can change the feel of the transition with &lt;code&gt;transition-timing-function&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fko8ksfqq1hapnk2w69ij.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fko8ksfqq1hapnk2w69ij.gif" alt="timing function" width="600" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Defaults to &lt;code&gt;ease&lt;/code&gt;. Let's try &lt;code&gt;ease-in-out&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And finally add a 1s delay with &lt;code&gt;transition-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;.ninja1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1s&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;Or&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;.ninja1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.ninja3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt; &lt;span class="m"&gt;1s&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;If you hover again on the ninja images, you'll notice the animations start with 1s delay.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  @keyframes animations
&lt;/h3&gt;

&lt;p&gt;Another way to animate in CSS is with &lt;code&gt;animation&lt;/code&gt; and &lt;code&gt;@keyframes&lt;/code&gt; rules.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@keyframes&lt;/code&gt; rules define steps in an 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;moveDown&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;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="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;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;50px&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;Some like to replace 0% and 100% with their keywords equivalent &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can add as many keyframes as you want from 0 to 100% and animate as many properties as you want.&lt;/p&gt;

&lt;p&gt;This weird animation would totally work 👍.&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;weirdAnim&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;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="err"&gt;11&lt;/span&gt;&lt;span class="o"&gt;%&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;50px&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;green&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;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;90deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&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="err"&gt;66&lt;/span&gt;&lt;span class="o"&gt;%&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;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-720deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;99&lt;/span&gt;&lt;span class="o"&gt;%&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;200px&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;black&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;background-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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run it we need to refer to its name with &lt;code&gt;animation-name&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;.ninja1&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;weirdAnim&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And give it a duration with &lt;code&gt;animation-duration&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;.ninja1&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;weirdAnim&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5s&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;With the &lt;code&gt;animation&lt;/code&gt; shorthand:&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;.ninja1&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;weirdAnim&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we get this monstrosity:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/NWbyvaq?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
(click on rerun to play the animation again)&lt;/p&gt;

&lt;p&gt;Same with transitions we can change the feel of the animation with an&lt;br&gt;
&lt;code&gt;animation-timing-function&lt;/code&gt;. And add a delay with &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;.ninja1&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;weirdAnim&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease&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;1s&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;Or:&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;.ninja1&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;weirdAnim&lt;/span&gt; &lt;span class="m"&gt;5s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt; &lt;span class="m"&gt;1s&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;With keyframes animation, we can also decide how many times to run an animation with &lt;code&gt;animation-iteration-count&lt;/code&gt;. Defaults to &lt;code&gt;1&lt;/code&gt;. Setting it to &lt;code&gt;infinite&lt;/code&gt; makes it run indefinitely.&lt;/p&gt;

&lt;p&gt;I've used &lt;code&gt;infinite&lt;/code&gt; for the cover animation. Here is the code for my text animation:&lt;/p&gt;

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

&lt;p&gt;There are two more advanced animation properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;animation-direction&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;normal&lt;/code&gt; (default) starts from the 1st keyframe.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reverse&lt;/code&gt; starts from the last keyframe.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;alternate&lt;/code&gt; starts from the 1st to last but if the animation is repeated the next animation will go from last to first.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;alternate-reverse&lt;/code&gt; is the same as alternate except it starts from the last keyframe.
(&lt;a href="https://www.w3schools.com/cssref/playit.asp?filename=playcss_animation-direction"&gt;example&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;animation-fill-mode&lt;/code&gt;. It's set to &lt;code&gt;forwards&lt;/code&gt; when we want to keep the animation state after it finished playing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are going to slide down the kpop girl image three times and hold the final position with &lt;code&gt;forwards&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"kpop"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://ljc-dev.github.io/fluffy-octo-adventure/kpop.png"&lt;/span&gt;&lt;span class="nt"&gt;&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;img&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;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&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;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;object-fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;slideDown&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;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="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;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;75%&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="nc"&gt;.kpop&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;slideDown&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-iteration-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-fill-mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;forwards&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;Or:&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;.kpop&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;slideDown&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="n"&gt;alternate&lt;/span&gt; &lt;span class="n"&gt;forwards&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/ljc-dev/embed/eYBVLZB?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Notice how &lt;code&gt;alternate&lt;/code&gt; is used to change the direction of the 2nd iteration. So instead of jumping back up and sliding down again, the animation runs in reverse and slides up.&lt;/p&gt;

&lt;p&gt;And that's the end of this intro to transitions and keyframes animations.&lt;/p&gt;

&lt;p&gt;One thing to be careful with shorthands is not to mix the properties order. You can omit the properties you won't change but don't put duration before the animation name for example.&lt;/p&gt;

&lt;p&gt;Here's the correct properties order for transitions and animations:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;transition: property duration timing-function delay;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;animation: name duration timing-function delay iteration-count direction fill-mode;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thanks for reading!!
&lt;/h3&gt;

&lt;p&gt;I hope you've got a better idea on how to animate with CSS now.&lt;/p&gt;

&lt;p&gt;I've posted below a small series of common CSS animations - some with js. If you have any questions, leave a comment or hit me up on socials 👌.&lt;/p&gt;

&lt;h3&gt;
  
  
  Happy coding 👋!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;button transition opacity on hover &amp;amp; scale on active &lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/poNaaGO?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;spinner &lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/wvoypbG?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;progress bar anim &lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/gOLvvPP?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;menu links bottom line on hover&lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/poNaapV?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;scroll to top with fade up anim &lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/rNWYyjv?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;hamburger slide down menu &lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/xxRpgaL?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;hamburger slide right menu + overlay&lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/zYoqbrN?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;post cover for those who are curious how I did it (not responsive)&lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/ljc-dev/embed/RwoQxYm?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>css</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Embedding an Instagram post in your website</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sat, 12 Sep 2020 17:37:46 +0000</pubDate>
      <link>https://dev.to/ljcdev/embedding-an-instagram-post-in-your-website-3666</link>
      <guid>https://dev.to/ljcdev/embedding-an-instagram-post-in-your-website-3666</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Ever wanted to share an Instagram post to your website? It is remarkably easy. You only need to know &lt;strong&gt;basic html&lt;/strong&gt; to share one. And it works for photos, videos, and even reels and IGTV! &lt;/p&gt;

&lt;h1&gt;
  
  
  Easy embedding to HTML.
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;First, go to a post and click on the options "...".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs9da6p6vafq52ieros02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs9da6p6vafq52ieros02.png" alt="click on the ... dot at the top right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;And choose &lt;em&gt;Embed&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9h2x2n8wo66v1wvgf65d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9h2x2n8wo66v1wvgf65d.png" alt="choose the embed option"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then click on &lt;em&gt;Copy Embed code&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbt7nn7gvp310eocgwua2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbt7nn7gvp310eocgwua2.png" alt="click on copy the embed code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tada!
&lt;/h4&gt;

&lt;p&gt;Now you have all you need to generate your post. Just paste it in your html and your post will be embedded into your website. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The embed post will adapt itself to the place it has. You can't really style it. But you can put it inside a parent container like a div and control its width for example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fczk5gz0qky2pzv30s2a1.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%2Fi%2Fczk5gz0qky2pzv30s2a1.gif" alt="example of embedding a post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example I'm using &lt;strong&gt;codepen&lt;/strong&gt; (online code editor) to paste the result and show the embedded post.&lt;/p&gt;

&lt;h1&gt;
  
  
  Optional
&lt;/h1&gt;

&lt;p&gt;The above is enough to share your Instagram post in your own website. &lt;/p&gt;

&lt;p&gt;Instagram also offers a dynamic embedding method. That way we can  &lt;strong&gt;fetch the post from an instagram url and display it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But first, you'll need a facebook developer account and setup an app there (coz facebook owns Insta 😁). Sign up for one at &lt;a href="https://developers.facebook.com/" rel="noopener noreferrer"&gt;https://developers.facebook.com&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Setup a Facebook app
&lt;/h1&gt;

&lt;p&gt;We need a facebook app and add the oEmbed product that is going to generate the post to be embedded for us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once logged in, choose &lt;em&gt;Create App&lt;/em&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2gq2icfrqor6qzzodxoi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2gq2icfrqor6qzzodxoi.png" alt="click on create an app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter a name and email:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv73z4271d97ebdsk0j5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv73z4271d97ebdsk0j5z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the app dashboard and scroll down the products list to find oEmbed then click on &lt;em&gt;Set Up&lt;/em&gt; to add it:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8f1wompxk1tpni52k2tn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8f1wompxk1tpni52k2tn.png" alt="find the oEmbed product"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to Settings &amp;gt; Advanced and copy the app ID and the client token for later use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxbr950ml9if9yjygbyfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxbr950ml9if9yjygbyfd.png" alt="app id and client token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right next to the app ID is a switch that says &lt;strong&gt;In development&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click to switch your app from development to &lt;strong&gt;live&lt;/strong&gt;. Because oEmbed only work if the app is in live mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Embedding the post dynamically.
&lt;/h1&gt;

&lt;p&gt;This tutorial follow the &lt;a href="https://developers.facebook.com/docs/instagram/oembed/#oembed-product" rel="noopener noreferrer"&gt;oEmbed guide&lt;/a&gt;. We are going to focus on how to implement this on a static website with client-side fetch and no backend. For full stack devs, click on the guide above to see how to fetch code from backend.&lt;/p&gt;

&lt;p&gt;We need to use the fetch api which works asynchronously. A basic knowledge of async/await could help. But I'll try to explain how it works in easy terms 😄.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: fetch the instagram post
&lt;/h2&gt;

&lt;p&gt;The url to be fetched look like this:&lt;/p&gt;

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

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://graph.facebook.com/v8.0/instagram_oembed?url=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;POST_URL&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;omitscript=true&amp;amp;access_token=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;APP_ID&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;CLIENT_TOKEN&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Create variables POST_URL, APP_ID , CLIENT_TOKEN.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;POST_URL is the link to your post, just copy and paste the url bar of your post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste in your app id and client token. (In production, save those in environment variables to prevent everyone from accessing it)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;omitscript=true&lt;/code&gt; is needed to load the post ourselves to the DOM. I'll detail about it later on.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are fetching with the built-in javascript &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" rel="noopener noreferrer"&gt;fetch api&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Async/await&lt;/strong&gt; is used to run &lt;strong&gt;asynchronous code&lt;/strong&gt;. Fetch is asynchronous as the response from fetch will take time to arrive.&lt;br&gt;
To use async/await, we need to place async before declaring a function and add await right before the asynchronous part like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 javascript
async function getPost() {
  var response = await fetch(
"https://graph.facebook.com/v8.0/instagram_oembed?url=" + 
POST_URL + "&amp;amp;omitscript=true&amp;amp;access_token=" + APP_ID + "|" + 
CLIENT_TOKEN)
}


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

&lt;/div&gt;

&lt;p&gt;The response from fetch comes as a JSON and need to be parsed into a javascript object with the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Body/json" rel="noopener noreferrer"&gt;json() method&lt;/a&gt; like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 javascript
response.json()


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

&lt;/div&gt;

&lt;p&gt;It's also asynchronous so we are adding await before it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 javascript
await response.json()


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

&lt;/div&gt;

&lt;p&gt;And we are going to save it in a &lt;code&gt;data&lt;/code&gt; variable&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 javascript
async function getPost() {
  var response = await fetch(
"https://graph.facebook.com/v8.0/instagram_oembed?url=" + 
POST_URL + "&amp;amp;omitscript=true&amp;amp;access_token=" + APP_ID + "|" + 
CLIENT_TOKEN)
  var data = await response.json()
}


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt; holds the object we fetched from Instagram. It has the following form:
```javascript
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;{&lt;br&gt;
  "version": "1.0",&lt;br&gt;
  "author_name": "diegoquinteiro",&lt;br&gt;
  "provider_name": "Instagram",&lt;br&gt;
  "provider_url": "&lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;https://www.instagram.com/&lt;/a&gt;",&lt;br&gt;
  "width": 658,&lt;br&gt;
  "html": "&amp;lt;blockquote class=\"instagram-media\" data-instgrm-ca...",&lt;br&gt;
  "thumbnail_width": 640,&lt;br&gt;
  "thumbnail_height": 640&lt;br&gt;
}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
The `html` property holds the post to be embedded. 

* Save `html` in a variable named `myPostHtml`:
```javascript


var myPostHtml = data.html


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 2: display the post
&lt;/h2&gt;

&lt;p&gt;The hardest part is over. Now let's add it to the HTML.&lt;/p&gt;

&lt;p&gt;Let's say we have a div with a class of post like&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;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We will add &lt;code&gt;myPostHtml&lt;/code&gt; to the div with a class of &lt;code&gt;post&lt;/code&gt; with:&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;var&lt;/span&gt; &lt;span class="nx"&gt;post&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myPostHtml&lt;/span&gt; 


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

&lt;/div&gt;

&lt;p&gt;And finally will be loading it. &lt;/p&gt;

&lt;p&gt;Remember in the fetch request we added &lt;code&gt;omitscript=true&lt;/code&gt;? The script won't run when you add it dynamically so we had to omit it.&lt;br&gt;
You'll need to include a copy of that script in your website. Following the guide above, here's the &lt;a href="https://www.instagram.com/static/bundles/metro/EmbedSDK.js/33cd2c5d5d59.js?fbclid=IwAR3asja2rHbvcnjCUehbSFMHng39Vyrrky12upuxrjNnt1J9_qoD5IG7gWk" rel="noopener noreferrer"&gt;link to the Instagram script&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saved the file from this link in an &lt;em&gt;embed.js&lt;/em&gt; file and add it as a script in your html code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can now used embed.js.&lt;br&gt;
The load method we are going to call in our function is:&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;instgrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Embeds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We add this at the end of our function. The final javascript code look like this:&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;var&lt;/span&gt; &lt;span class="nx"&gt;POST_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my post url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;APP_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my app ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;CLIENT_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my client token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;post&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://graph.facebook.com/v8.0/instagram_oembed?url=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
&lt;span class="nx"&gt;POST_URL&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;omitscript=true&amp;amp;access_token=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;APP_ID&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
&lt;span class="nx"&gt;CLIENT_TOKEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;myPostHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;
  &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myPostHtml&lt;/span&gt;
  &lt;span class="nx"&gt;instgrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Embeds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&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;By calling getPost() we will get an embed post to display where we want.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If we want to display a post from an url a user enters we just need to replace POST_URL inside fetch() with the value of the user's input url. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example we added a text input with a class of &lt;code&gt;inputUrl&lt;/code&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;var&lt;/span&gt; &lt;span class="nx"&gt;POST_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my post url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;APP_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my app ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;CLIENT_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my client token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;post&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;inputUrl&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.inputUrl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// get value from user input&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://graph.facebook.com/v8.0/instagram_oembed?url=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;omitscript=true&amp;amp;access_token=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;APP_ID&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
&lt;span class="nx"&gt;CLIENT_TOKEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;myPostHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;
  &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myPostHtml&lt;/span&gt;
  &lt;span class="nx"&gt;instgrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Embeds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&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;h1&gt;
  
  
  Improvements:
&lt;/h1&gt;

&lt;p&gt;We would like to make it work with not just the post url from the address bar but also in case the user click on the copy link in the options:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyfrumufynpwpyqhc4q0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyfrumufynpwpyqhc4q0u.png" alt="copy link"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As of now it won't work. Because at the end of the post url Instagram added a query like this:&lt;/p&gt;

&lt;p&gt;"&lt;a href="https://www.instagram.com/p/CFA8H3sob2_/?utm_source=ig_web_copy_link" rel="noopener noreferrer"&gt;https://www.instagram.com/p/CFA8H3sob2_/?utm_source=ig_web_copy_link&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;We need to remove the query part: "?utm_source=ig_web_copy_link" and only keep the post url. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We could use slice to remove it:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
  &lt;span class="c1"&gt;//remove ? and the part after it&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;indexOfQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;indexOfQuery&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&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="nx"&gt;indexOfQuery&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;ul&gt;
&lt;li&gt;Or regex:&lt;/li&gt;
&lt;/ul&gt;

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

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
  &lt;span class="c1"&gt;//remove ? and the part after it&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&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="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\?&lt;/span&gt;&lt;span class="sr"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

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

&lt;h1&gt;
  
  
  Thanks for reading 😁!!
&lt;/h1&gt;

&lt;p&gt; &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>html</category>
      <category>javascript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Scroll-to-top Button in vanilla JS (Beginners)</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sun, 23 Aug 2020 09:27:04 +0000</pubDate>
      <link>https://dev.to/ljcdev/scroll-to-top-button-in-vanilla-js-beginners-2nc</link>
      <guid>https://dev.to/ljcdev/scroll-to-top-button-in-vanilla-js-beginners-2nc</guid>
      <description>&lt;p&gt;Scroll to top button is a very common UX feature in websites. It's goal is to prevent annoying users forced to scroll back up - especially on mobile devices. In this short tutorial, we'll see how to implement one with css and pure (vanilla) javascript.&lt;/p&gt;

&lt;p&gt;The simplest way to get a scroll to top button is to have an html element at the top and a link near the end of your page that calls it:&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;id=&lt;/span&gt;&lt;span class="s"&gt;"scroll-to-top"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- ... --&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;"#scroll-to-top"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;And this css to make the scroll smooth:&lt;/p&gt;

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

&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;scroll-behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"smooth"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;That's the easiest way to get a scroll to top (I've actually missed this on my original post as &lt;em&gt;Loouis Low&lt;/em&gt; pointed out in the comments.)&lt;/p&gt;

&lt;p&gt;Result here:&lt;/p&gt;

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

&lt;p&gt;No javascript needed!&lt;/p&gt;

&lt;h1&gt;
  
  
  Scroll to top button with vanilla js
&lt;/h1&gt;

&lt;p&gt;The previous example works fine but has a serious drawback because after clicking on that link, the anchor &lt;em&gt;#scroll-to-top&lt;/em&gt; will show up in the url . We could call the anchor &lt;em&gt;#home&lt;/em&gt;. But it'll still be in the url history when the user clicks back.&lt;/p&gt;

&lt;p&gt;That's why I prefer to do it in js 😁. Plus js allows much more customization like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show button after the user has scrolled down x % of the page.&lt;/li&gt;
&lt;li&gt;Animate entrance and leave.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The button
&lt;/h2&gt;

&lt;p&gt;Let's just created a simple button with a class of &lt;code&gt;scrollToTopBtn&lt;/code&gt; so we can refer to it in js.&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;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"scrollToTopBtn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;TOP&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here are a few CSS properties for the button:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;position: fixed;&lt;/code&gt; gets it out of the flow of the page. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;bottom: 50px;&lt;/code&gt; and &lt;code&gt;right: 50px;&lt;/code&gt; places it at the bottom right corner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;z-index: 100;&lt;/code&gt; a large z-index keeps the button on top of every other elements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;display: none;&lt;/code&gt; is used to hide it at first.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Detect user scroll
&lt;/h2&gt;

&lt;p&gt;we can detect user's scroll with a &lt;code&gt;scroll&lt;/code&gt; event listener:&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="s2"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do something on scroll&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Show the Scroll to Top button logic
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;handleScroll&lt;/code&gt; function, we'll check whether we need to show or hide the button. We are going to use three element properties: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight" rel="noopener noreferrer"&gt;clientHeight&lt;/a&gt; gives us the &lt;strong&gt;visible part&lt;/strong&gt; of an element in its parent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight" rel="noopener noreferrer"&gt;scrollHeight&lt;/a&gt; gives the &lt;strong&gt;total height&lt;/strong&gt; of an element including the overflow part.&lt;/p&gt;&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%2F87q7kw5ft26x55mi8c7o.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%2F87q7kw5ft26x55mi8c7o.png" alt="clientHeight and scrollHeight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The height of the overflow part is the &lt;strong&gt;total amount of pixels that can be scrolled&lt;/strong&gt;. In other words: scrollableHeight = scrollHeight - clientHeight&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;var&lt;/span&gt; &lt;span class="nx"&gt;scrollableHeight&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;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&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;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;document.documentElement&lt;/code&gt; is the document element. We are using it instead of &lt;code&gt;document&lt;/code&gt; because scrollHeight and clientHeight are elements' properties.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop" rel="noopener noreferrer"&gt;scrollTop&lt;/a&gt; gives the number of pixels scrolled from the top. It's the &lt;strong&gt;amount of pixels scrolled&lt;/strong&gt; by the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By dividing scrollTop with scrollableHeight we get a ratio between 0 and 1. 0 meaning the user hasn't scrolled and 1 meaning the user scrolled to the end of the page. This ratio tells us how much the user scrolled.&lt;/p&gt;

&lt;p&gt;If we want the scroll to top button to show up after the user scrolled 50% we set a &lt;em&gt;golden ratio&lt;/em&gt; of 0.5. And, with an if else statement, make the button visible above and hidden below.&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="s2"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// get a reference to the button&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scrollToTopBtn&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.scrollToTopBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scrollableHeight&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;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&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;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;GOLDEN_RATIO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;scrollableHeight&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;GOLDEN_RATIO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//show button&lt;/span&gt;
    &lt;span class="nx"&gt;scrollToTopBtn&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//hide button&lt;/span&gt;
    &lt;span class="nx"&gt;scrollToTopBtn&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;With that the scroll-to-top button appears and hides on scroll.&lt;/p&gt;

&lt;h1&gt;
  
  
  Scroll to top
&lt;/h1&gt;

&lt;p&gt;There a lot of scrolling examples that use jQuery. But these days it is really easy to do this in pure js with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo" rel="noopener noreferrer"&gt;&lt;strong&gt;scrollTo&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;

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

&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;scrollToTopBtn&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="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scrollToTop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scrollToTop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scrollTo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;top&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="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;smooth&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;ul&gt;
&lt;li&gt;
&lt;code&gt;top: 0,&lt;/code&gt; means scroll to 0px vertically.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;behavior: "smooth"&lt;/code&gt; makes the scroll smooth.&lt;/li&gt;
&lt;li&gt;there's also a &lt;code&gt;left&lt;/code&gt; property for horizontal scroll.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's it! Here's the final js:  &lt;/p&gt;


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

&lt;p&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="s2"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;
&lt;span class="c1"&gt;// get a reference to our predefined button&lt;/span&gt;&lt;br&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scrollToTopBtn&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.scrollToTopBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scrollableHeight&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;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&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;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;GOLDEN_RATIO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;if &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;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;scrollableHeight&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;GOLDEN_RATIO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="c1"&gt;//show button&lt;/span&gt;&lt;br&gt;
    &lt;span class="nx"&gt;scrollToTopBtn&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;br&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="c1"&gt;//hide button&lt;/span&gt;&lt;br&gt;
    &lt;span class="nx"&gt;scrollToTopBtn&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;br&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nx"&gt;scrollToTopBtn&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="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scrollToTop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scrollToTop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scrollTo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;br&gt;
    &lt;span class="na"&gt;top&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;br&gt;
    &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;smooth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;br&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Tada 🎉🎉🎉!&lt;br&gt;
&lt;/h3&gt;

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

&lt;p&gt;Thanks for reading 🥰🥰!! I hope this was of help.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improvements:
&lt;/h3&gt;

&lt;p&gt;I've tried to keep it simple. Usually I would also toggle a class instead of the display to show a transition animation.&lt;/p&gt;

&lt;p&gt;Here's how you could fade up the button:&lt;/p&gt;

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

</description>
      <category>tutorial</category>
      <category>css</category>
      <category>codenewbie</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Simple typing effect pure JS (beginner)</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sat, 01 Aug 2020 15:44:22 +0000</pubDate>
      <link>https://dev.to/ljcdev/simple-typing-effect-pure-js-4p5m</link>
      <guid>https://dev.to/ljcdev/simple-typing-effect-pure-js-4p5m</guid>
      <description>&lt;p&gt;The typing effect is a simple yet stylish animation used by many bloggers and web developers to introduce themselves in an elegant fashion.&lt;/p&gt;

&lt;p&gt;This tutorial will show you how to create the typing effect with plain css and js (no libraries).&lt;/p&gt;

&lt;p&gt;Let's start by creating a text holder &lt;code&gt;p&lt;/code&gt; with a class of &lt;code&gt;typeText&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"typeText"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We add a blinking cursor after our paragraph with a CSS 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="nc"&gt;.typeText&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;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;blink&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="nb"&gt;blink&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="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="err"&gt;50&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&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 pseudo class &lt;code&gt;::after&lt;/code&gt; is going to add the cursor &lt;code&gt;|&lt;/code&gt; and make it blink with the keyframes animation blink.&lt;/p&gt;

&lt;p&gt;If you are not familiar with animations, I made an introduction to CSS animations &lt;a href="https://dev.to/ljcdev/introduction-to-css-animation-4762"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's all the js to the typing effect:&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;var&lt;/span&gt; &lt;span class="nx"&gt;typeText&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.typeText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;textToBeTyped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a software engineer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;playAnim&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="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// set the text of typeText to a substring of&lt;/span&gt;
    &lt;span class="c1"&gt;// the textToBeTyped using index.&lt;/span&gt;
    &lt;span class="nx"&gt;typeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;textToBeTyped&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="nx"&gt;index&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;isAdding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// adding text&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;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;textToBeTyped&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// no more text to add&lt;/span&gt;
        &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
        &lt;span class="c1"&gt;//break: wait 2s before playing again&lt;/span&gt;
        &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;playAnim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// increment index by 1&lt;/span&gt;
        &lt;span class="nx"&gt;index&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// removing text&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;index&lt;/span&gt; &lt;span class="o"&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="c1"&gt;// no more text to remove&lt;/span&gt;
        &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// decrement index by 1&lt;/span&gt;
        &lt;span class="nx"&gt;index&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="c1"&gt;// call itself&lt;/span&gt;
    &lt;span class="nf"&gt;playAnim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// start animation&lt;/span&gt;
&lt;span class="nf"&gt;playAnim&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;playAnim()&lt;/code&gt; function calls itself repeatedly using &lt;code&gt;setTimeout&lt;/code&gt; with a delay of 120ms.&lt;/p&gt;

&lt;p&gt;By using the string method &lt;code&gt;slice(0, index)&lt;/code&gt; we set the text of &lt;code&gt;typeText&lt;/code&gt; to a substring of the &lt;code&gt;textToBeTyped&lt;/code&gt;.&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;typeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;textToBeTyped&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="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;index&lt;/code&gt; begins at 0 and increments by 1 when we are adding and decrements by 1 when we are removing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;isAdding&lt;/code&gt; is a boolean that is used to check whether we are adding or removing.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;index&lt;/code&gt; is larger than the length of &lt;code&gt;textToBeTyped&lt;/code&gt;, we set &lt;code&gt;isAdding&lt;/code&gt; to false to start removing. And when &lt;code&gt;index&lt;/code&gt; is equal to 0, we set &lt;code&gt;isAdding&lt;/code&gt; is true to start adding again.&lt;/p&gt;

&lt;p&gt;After it has finished adding, a setTimeout with a 2000ms delay will create a break for people to read the text before it gets removed again.&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="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;textToBeTyped&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// no more text to add&lt;/span&gt;
  &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="c1"&gt;//break: wait 2s before playing again&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;playAnim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we get:&lt;/p&gt;

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

&lt;p&gt;And that's it! You should now be able to make your own typing effect.&lt;/p&gt;

&lt;p&gt;I've tried to make it beginner friendly but I think my explanations weren't that great 😅. If you have questions, please leave a comment or hit me up on my socials 😁. &lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond the basics
&lt;/h3&gt;

&lt;p&gt;The cursor animation can be made more realistic by adding a built-in animation-timing-function &lt;code&gt;step-end&lt;/code&gt; to our blink animation like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.typeText&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="c"&gt;/* animation: blink 1s infinite; */&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;blink&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;step-end&lt;/span&gt; &lt;span class="n"&gt;infinite&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;code&gt;steps&lt;/code&gt; are a recent addition to css. They break the flow of an animation by playing it in jumping steps. The only difference between the two animations below is the addition of steps on the 2nd div.&lt;/p&gt;

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

&lt;p&gt;We can increase the removing speed by changing the setTimeout delay with the boolean &lt;code&gt;isAdding&lt;/code&gt; and a ternary operator like this:&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;function&lt;/span&gt; &lt;span class="nf"&gt;playAnim&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="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ternary operator means if it's adding set the delay to 120ms. If it's removing set the delay to 60ms.&lt;/p&gt;

&lt;p&gt;And instead of typing one string we can choose an array of string &lt;code&gt;textToBeTypedArr&lt;/code&gt; to be typed in turn. And a &lt;code&gt;textToBeTypedIndex&lt;/code&gt; variable to keep track of the current text index in the array. textToBeTypedIndex will be updated it each time after we are done removing the previous text.&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;var&lt;/span&gt; &lt;span class="nx"&gt;typeText&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.typeText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// var textToBeTyped = "a software engineer"&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;textToBeTypedArr&lt;/span&gt; &lt;span class="o"&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;a software engineer&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;a warlord&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;a king&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;a peasant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textToBeTypedIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;playAnim&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="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// set the text of typeText to a substring of the text to be typed using index.&lt;/span&gt;
    &lt;span class="nx"&gt;typeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;textToBeTypedArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;textToBeTypedIndex&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="nx"&gt;index&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;isAdding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// adding text&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;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;textToBeTypedArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;textToBeTypedIndex&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//...&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// removing text&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;index&lt;/span&gt; &lt;span class="o"&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="c1"&gt;//...&lt;/span&gt;
        &lt;span class="c1"&gt;//switch to next text in text array&lt;/span&gt;
        &lt;span class="nx"&gt;textToBeTypedIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;textToBeTypedIndex&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="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;textToBeTypedArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&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;// calls itself&lt;/span&gt;
    &lt;span class="nf"&gt;playAnim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// start animation&lt;/span&gt;
&lt;span class="nf"&gt;playAnim&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/ljc-dev/embed/rNWYrax?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;And for prefectionists that don't like the cursor blinking when the text is being added/removed, we can toggle the blink animation by removing the animation from ::after and adding it only in js with the &lt;code&gt;showAnim&lt;/code&gt; class:&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;.typeText&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="c"&gt;/* animation: blink 1s step-end infinite; */&lt;/span&gt;
  &lt;span class="nl"&gt;animation&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="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.showAnim.typeText&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;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;blink&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;step-end&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And toggling the &lt;code&gt;showAnim&lt;/code&gt; class in js:&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;function&lt;/span&gt; &lt;span class="nf"&gt;playAnim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&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;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;textToBeTyped&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// no more text to add&lt;/span&gt;
        &lt;span class="nx"&gt;isAdding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
        &lt;span class="c1"&gt;//break: wait 2s before playing again&lt;/span&gt;
        &lt;span class="c1"&gt;// play cursor blink animation&lt;/span&gt;
        &lt;span class="nx"&gt;typeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;showAnim&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// remove cursor blink animation&lt;/span&gt;
          &lt;span class="nx"&gt;typeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;showAnim&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="nf"&gt;playAnim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="c1"&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/ljc-dev/embed/jOVYPQX?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;End!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>codenewbie</category>
      <category>codepen</category>
    </item>
    <item>
      <title>Easy hamburger menu with JS - Beginners</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sun, 26 Jul 2020 10:56:06 +0000</pubDate>
      <link>https://dev.to/ljcdev/easy-hamburger-menu-with-js-2do0</link>
      <guid>https://dev.to/ljcdev/easy-hamburger-menu-with-js-2do0</guid>
      <description>&lt;p&gt;A hamburger menu is a classic UI feature present in countless websites. It's used to show and hide a menu on click, especially used in mobile design. &lt;/p&gt;

&lt;p&gt;In this tutorial, we'll learn to create a hamburger menu with HTML, CSS and Javascript.&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%2F11z26o40wnm6qa7vd35x.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%2F11z26o40wnm6qa7vd35x.gif" alt="result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the HTML:&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;head&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Material Icon CDN --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.googleapis.com/icon?family=Material+Icons"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"menuItem"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"menuItem"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Profile&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"menuItem"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"menuItem"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contacts&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hamburger"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- material icons https://material.io/resources/icons/ --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"menuIcon material-icons"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;menu&lt;span class="nt"&gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"closeIcon material-icons"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;close&lt;span class="nt"&gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Begin by adding a basic menu with a class of &lt;code&gt;menu&lt;/code&gt; and menu links with a class of &lt;code&gt;menuItem&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then add a button with a class of &lt;code&gt;hamburger&lt;/code&gt; and both a &lt;em&gt;menu&lt;/em&gt; and a &lt;em&gt;close&lt;/em&gt; icons inside of it. Later on we will hide the &lt;em&gt;close&lt;/em&gt; icon by default with CSS and alternate which icon to show with Javascript.&lt;/p&gt;

&lt;p&gt;You can use any icons family you want. I've used &lt;a href="https://material.io/resources/icons/" rel="noopener noreferrer"&gt;material icons&lt;/a&gt; by loading their CDN in the head and adding the &lt;em&gt;menu&lt;/em&gt; and &lt;em&gt;close&lt;/em&gt; icons inside of the button.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;menuIcon&lt;/code&gt; and &lt;code&gt;closeIcon&lt;/code&gt; classes are used to reference the icons in CSS and Javascript later on.&lt;/p&gt;

&lt;p&gt;Now let's add some CSS.&lt;/p&gt;

&lt;p&gt;Add to the button &lt;code&gt;position: fixed;&lt;/code&gt; so scrolling won't affect it. And &lt;code&gt;z-index:100;&lt;/code&gt; to make sure it stays above every other element. &lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; with a value of &lt;code&gt;1rem&lt;/code&gt; to place it at the top-right corner of the screen.&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;.hamburger&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;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&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="no"&gt;black&lt;/span&gt; &lt;span class="nb"&gt;solid&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;background&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;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;To hide the &lt;em&gt;close&lt;/em&gt; icon by default, add &lt;code&gt;display: none;&lt;/code&gt; to the &lt;code&gt;closeIcon&lt;/code&gt; class.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 css
.closeIcon {
  display: none;
}


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

&lt;/div&gt;

&lt;p&gt;In the menu class, add &lt;code&gt;position: fixed;&lt;/code&gt; so it can't be scrolled away. &lt;/p&gt;

&lt;p&gt;Set the &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt; and &lt;code&gt;left&lt;/code&gt; to 0 to make the menu cover the whole screen.&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;.menu&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;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;-100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.2s&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;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;right&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;bottom&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="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&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;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;list-style&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;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4rem&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;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;transform: translateY(-100%);&lt;/code&gt; is used to hide the menu by default above the screen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;transition: transform 0.2s;&lt;/code&gt; is optional. It is used to animate the change in translation value to create a slide up/down effect.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By resetting &lt;em&gt;translateY&lt;/em&gt; to 0, the menu will slide down and cover the whole screen.&lt;/p&gt;

&lt;p&gt;Add it in a &lt;code&gt;showMenu&lt;/code&gt; class:&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;.showMenu&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This class will be added and removed from the menu with Javascript to show and hide the menu.&lt;/p&gt;

&lt;p&gt;Here's the Javascript for toggling the menu:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 javascript
const menu = document.querySelector(".menu");
const menuItems = document.querySelectorAll(".menuItem");
const hamburger= document.querySelector(".hamburger");
const closeIcon= document.querySelector(".closeIcon");
const menuIcon = document.querySelector(".menuIcon");

function toggleMenu() {
  if (menu.classList.contains("showMenu")) {
    menu.classList.remove("showMenu");
    closeIcon.style.display = "none";
    menuIcon.style.display = "block";
  } else {
    menu.classList.add("showMenu");
    closeIcon.style.display = "block";
    menuIcon.style.display = "none";
  }
}

hamburger.addEventListener("click", toggleMenu);


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

&lt;/div&gt;

&lt;p&gt;Clicking on the hamburger button will call &lt;code&gt;toggleMenu()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It checks if the menu contains the class &lt;code&gt;showMenu&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the menu &lt;strong&gt;contains&lt;/strong&gt; the &lt;code&gt;showMenu&lt;/code&gt; class, we &lt;strong&gt;remove&lt;/strong&gt; it to hide the menu. We also toggle the &lt;code&gt;display&lt;/code&gt; to hide the &lt;em&gt;close&lt;/em&gt; icon and show the &lt;em&gt;menu&lt;/em&gt; icon.&lt;/p&gt;

&lt;p&gt;If the menu doesn't have the &lt;code&gt;showMenu&lt;/code&gt; class, we &lt;strong&gt;add&lt;/strong&gt; it, show the &lt;em&gt;close&lt;/em&gt; icon and hide the &lt;em&gt;menu&lt;/em&gt; icon.&lt;/p&gt;

&lt;p&gt;The hardest part is over! All that's left is to hide the menu when the user click on the links.&lt;/p&gt;

&lt;p&gt;In the Javascript above, we got all the menu items with &lt;code&gt;querySelectorAll&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 javascript
const menuItems = document.querySelectorAll(".menuItem");


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

&lt;/div&gt;

&lt;p&gt;With &lt;code&gt;forEach&lt;/code&gt;, we can iterate through each link and add a call to &lt;code&gt;toggleMenu()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;toggleMenu()&lt;/code&gt; will in turn hide the menu (because if the user can click on the menu items it means that the menu is showing).&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&lt;br&gt;
 javascript&lt;br&gt;
menuItems.forEach( &lt;br&gt;
  function(menuItem) { &lt;br&gt;
    menuItem.addEventListener("click", toggleMenu);&lt;br&gt;
  }&lt;br&gt;
)

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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  And that's it!&lt;br&gt;
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Thanks for reading 😄!!
&lt;/h3&gt;

&lt;p&gt;(2nd rewrite 01/10/21)&lt;br&gt;
I hope you've found it useful and happy coding 👨‍💻!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hamburger CSS (no JS)</title>
      <dc:creator>ljc-dev</dc:creator>
      <pubDate>Sat, 25 Jul 2020 20:26:30 +0000</pubDate>
      <link>https://dev.to/ljcdev/hamburger-css-no-js-2dfa</link>
      <guid>https://dev.to/ljcdev/hamburger-css-no-js-2dfa</guid>
      <description>&lt;p&gt;I put together this short tutorial on how to make a &lt;strong&gt;hamburger menu with no js&lt;/strong&gt; in response to the feedback on my original Twitter post.&lt;/p&gt;

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

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

&lt;h2&gt;
  
  
  :target
&lt;/h2&gt;

&lt;p&gt;Have you heard of the CSS pseudo-class on &lt;code&gt;:target&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;It styles the element with an &lt;strong&gt;anchor id&lt;/strong&gt; that that has been called by a &lt;strong&gt;link&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;For example, a &lt;code&gt;p&lt;/code&gt; with an id of &lt;code&gt;home&lt;/code&gt; and an &lt;code&gt;a&lt;/code&gt; link with &lt;code&gt;href=#home&lt;/code&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&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Go to Home&lt;span class="nt"&gt;&amp;lt;/a&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="nd"&gt;:target&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;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%2Fgh7760oizvorseckf251.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%2Fgh7760oizvorseckf251.gif" alt="target example 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we click on the &lt;code&gt;a&lt;/code&gt; link, the text of the targeted &lt;code&gt;p&lt;/code&gt; changes to red.&lt;/p&gt;

&lt;p&gt;By clicking on another link, the &lt;code&gt;:target&lt;/code&gt; style gets hidden.&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&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Go to Home&lt;span class="nt"&gt;&amp;lt;/a&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="nt"&gt;&amp;gt;&lt;/span&gt;Go somewhere else&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

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

&lt;p&gt;Here's the whole html code.&lt;/p&gt;

&lt;p&gt;I'm using &lt;a href="https://material.io/resources/icons/" rel="noopener noreferrer"&gt;material icons&lt;/a&gt; by adding their cdn in the head of the html file.&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;head&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.googleapis.com/icon?family=Material+Icons"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;


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

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

  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;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="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;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="nt"&gt;&amp;gt;&lt;/span&gt;Profile&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;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="nt"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;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="nt"&gt;&amp;gt;&lt;/span&gt;Contacts&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"close"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"material-icons"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      close
    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hamburger"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#menu"&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;"material-icons"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      menu
    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Material icons work by defining a span with &lt;code&gt;material-icons&lt;/code&gt; class and adding a keyword between the tags:&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;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"material-icons"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    close
  &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;ul&lt;/code&gt; has an id of &lt;code&gt;menu&lt;/code&gt;. It holds the menu and the close icon link. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;a&lt;/code&gt; with a class of &lt;code&gt;hamburger&lt;/code&gt; has a href &lt;code&gt;#menu&lt;/code&gt;, clicking on it will show the on &lt;code&gt;:target&lt;/code&gt; style for the &lt;code&gt;ul&lt;/code&gt; menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clicking on other links (Home, Profile, About, Contacts) and the &lt;code&gt;close&lt;/code&gt; link will remove the on &lt;code&gt;:target&lt;/code&gt; style of the &lt;code&gt;ul&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we just need to add a sprinkle of CSS ✨.&lt;/p&gt;

&lt;p&gt;The hamburger link has a position &lt;code&gt;fixed&lt;/code&gt; to get it out of the flow of the page. &lt;/p&gt;

&lt;p&gt;The menu has a position &lt;code&gt;fixed&lt;/code&gt; too and a bigger &lt;code&gt;z-index&lt;/code&gt; than the hamburger link to put the menu above the link.&lt;/p&gt;

&lt;p&gt;For consistency, I've put the hamburger and close links on the same corner.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 css
.hamburger {
  position: fixed;
  /* a large z-index puts the ham button above the rest of the page*/
  z-index: 99;
  background: white;
  border: none;
  cursor: pointer;
  top: 1rem;
  right: 1rem;
}

.menu {
  position: fixed;
  /* give the menu a larger z-index than the ham link
  to put the menu above it */
  z-index: 100;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100vh;
  /* basic menu styling*/
  list-style: none;
  background: black;
  display: flex;

  flex-direction: column;
  /* animate slide up/down */
  transform: translateY(-100%);
  transition: transform 0.2s ease;
}

.close {
  position: absolute;
  border: none;
  color: white;
  cursor: pointer;
  top: 1rem;
  right: 1rem;
}


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

&lt;/div&gt;

&lt;p&gt;The menu is hidden by default with &lt;code&gt;transform: translateY(-100%);&lt;/code&gt;. Translating -100% on the Y axis moves it 100% up above the screen.&lt;/p&gt;

&lt;p&gt;By adding a transition &lt;code&gt;transition: transform 0.2s;&lt;/code&gt; on transform we get a small slide in and out animation when the value of transform translateY changes.&lt;/p&gt;

&lt;p&gt;And we reset the translation Y to 0 and show the menu on &lt;code&gt;:target&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 css
.menu:target {
  /* show menu */
  transform: translateY(0);
}


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

&lt;/div&gt;

&lt;p&gt;Thanks for reading 😄!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thanks &lt;a href="https://twitter.com/BelevMartin" rel="noopener noreferrer"&gt;Martin&lt;/a&gt; for telling me to animate transform instead of height to get GPU support.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
