<?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: vijitail</title>
    <description>The latest articles on DEV Community by vijitail (@vijitail).</description>
    <link>https://dev.to/vijitail</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%2F166698%2F693069b9-98ed-4717-8279-c5bfcbdaee99.jpg</url>
      <title>DEV Community: vijitail</title>
      <link>https://dev.to/vijitail</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vijitail"/>
    <language>en</language>
    <item>
      <title>Let’s code a client side router for your frameworkless SPA</title>
      <dc:creator>vijitail</dc:creator>
      <pubDate>Fri, 24 May 2019 19:12:40 +0000</pubDate>
      <link>https://dev.to/vijitail/let-s-code-a-client-side-router-for-your-frameworkless-spa-2bg</link>
      <guid>https://dev.to/vijitail/let-s-code-a-client-side-router-for-your-frameworkless-spa-2bg</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7QB1OW_---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AXsdtxKTqZPC7DTtzLBEgfA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7QB1OW_---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AXsdtxKTqZPC7DTtzLBEgfA.jpeg" alt='"Photo by Jordan Ladikos on Unsplash"'&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, you read the title right, Client side router for a frameworkless SPA, that’s exactly what we are going to build in this story.&lt;/p&gt;




&lt;p&gt;Before we dive into the code, let’s first understand what is client side routing.&lt;/p&gt;

&lt;p&gt;A client side router runs on the user’s browser. The browser does not make a request to the server for the page, rather it looks into the JavaScript code that is loaded onto the browser to render the page for the matched route.&lt;/p&gt;

&lt;p&gt;This is how our router would render the page — &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Listen on hashchange event.&lt;/li&gt;
&lt;li&gt;When the url changes, match and parse the url to the route predefined in the code.&lt;/li&gt;
&lt;li&gt;Look for the view to be rendered for that route, if no match is found render a 404 message.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QVwWGPCa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1000/1%2A9ntD58Eb0tHhvcuOwUC7fQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QVwWGPCa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1000/1%2A9ntD58Eb0tHhvcuOwUC7fQ.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enough theory, show me the code already!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Below is the folder structure that we’d be working with&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BLfpExy6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1000/1%2Ahp_m21itclu4CkEgLMj_Ow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BLfpExy6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1000/1%2Ahp_m21itclu4CkEgLMj_Ow.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s define a class to represent the Route in the router folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DYX4JKc3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2A7fAYkPLx6KQo4Y1YU4T0Wg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DYX4JKc3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2A7fAYkPLx6KQo4Y1YU4T0Wg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Route class would take in 3 parameters while instantiating; name, path and the view associated to the route.&lt;/p&gt;

&lt;p&gt;The setProps() method will set the props or properties that would be passed on to the route from the url and the renderView() method would return the view of the route.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Afj8ZJTt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2Ayeqz__GDjOxGuDeS6wdQVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Afj8ZJTt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2Ayeqz__GDjOxGuDeS6wdQVA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Router class will be the heart of our routing system. It will take an array of route objects as the first parameter and the renderNode where the view will be injected as the second.&lt;/p&gt;

&lt;p&gt;Our Router class will have methods like match() and navigate() to match the routes and navigate respectively. Lets look at their definitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--73y1Ajtz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AknwAYtBoAzPZv0v7tf7o4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--73y1Ajtz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AknwAYtBoAzPZv0v7tf7o4w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The navigate() method will filter through each route and check if it matches with any of the predefined routes. If no route is matched the renderNode will render a 404 message, else it would render the matched route’s view;&lt;br&gt;
In the match(), we are creating regular expression of the route path and matching it with the requested path. If it matches we are also finding out if the requested route has any route parameters.&lt;/p&gt;

&lt;p&gt;Well you might have already noticed the problem in the navigation(), we are literally injecting the view using innerHTML, which btw must be avoided at all cost. Mainly because of security reasons regarding XSS and also another problem that I encountered while coding, that any element in the injected view does not have an event listener attached to it. So that means you cannot have a button in a view to navigate to another route, it simply won’t work. To get around this we need to build the view using document.createElement(). To keeps this post concise, I’m leaving it upto you to figure it out(I may explore it later).&lt;/p&gt;

&lt;p&gt;I like to add utility functionalities so lets define another method to add routes to the router.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sH1ARKoJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2A7MKnCbvmD6lrozOFktDohA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sH1ARKoJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2A7MKnCbvmD6lrozOFktDohA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s take a look at the index.js of router.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vR-0mJ8C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AKa8fMeFz1XbKV8p2sFO72Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vR-0mJ8C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AKa8fMeFz1XbKV8p2sFO72Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we are exporting a function which takes routes as the parameter and creates an instance of the Router Class. The renderNode is a div with an id of app. We are adding the click event listener to the buttons that have a route attribute (inspired from other libraries), and listening for the hashchange event on the url to call the navigate() method.&lt;/p&gt;

&lt;p&gt;Now, lets take a look at all the views in the application (look at the captions if you get lost keeping tracks of files)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9z6LspSE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2ASIoXdaag6fKEERNjJFm6JQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9z6LspSE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2ASIoXdaag6fKEERNjJFm6JQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---4Wwatwx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AefpgntCNeD3sAkd86DgiWw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---4Wwatwx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AefpgntCNeD3sAkd86DgiWw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uf41r3pv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2A24Tr_XCNYltCn-Pz_ZrhgA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uf41r3pv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2A24Tr_XCNYltCn-Pz_ZrhgA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r2bdoPgh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AvGO31jw1iMUvu-B9HA2-LA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r2bdoPgh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AvGO31jw1iMUvu-B9HA2-LA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can install html pragmas in your code editor for syntax highlighting the html in template literals.&lt;/p&gt;

&lt;p&gt;And finally in our app.js file lets define all our routes and pass it to our router.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8tRWtWyO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AXeyYB6XCEhgVqduVr2GsYw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8tRWtWyO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AXeyYB6XCEhgVqduVr2GsYw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following code would go in the body of the index.html file&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xc1jEdcN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AZj2wL9El6b9AxNwry0Lx7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xc1jEdcN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AZj2wL9El6b9AxNwry0Lx7w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to add the type=”module” in the script tag in order to use the import/export es6 feature, because of this we don’t have to setup any extra configuration.&lt;/p&gt;

&lt;p&gt;To wrap this up lets add a few lines of CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j8V7381B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AVFmylzBVlVMjurDiBdz6VQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j8V7381B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1500/1%2AVFmylzBVlVMjurDiBdz6VQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To conclude this post, I’d say that you don’t need to bring in other libraries for small and simple Single Page Application, you can spin up you own custom solution, I just happen to show you one of the many ways, probably you can do more and much better. If you do, do let me know, I’d be happy to see your work.&lt;/p&gt;

&lt;p&gt;I referred to this video on YouTube for writing the story — &lt;a href="https://www.youtube.com/watch?v=D1fLaNxd-ZM"&gt;https://www.youtube.com/watch?v=D1fLaNxd-ZM&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;You can take a look at the final repo in my &lt;a href="https://github.com/vijitail/simple-javascript-router"&gt;github&lt;/a&gt;, if you get stuck while following along. You can DM me on instagram &lt;a href="https://instagram.com/vijit__ail"&gt;@vijit__ail&lt;/a&gt; if you come across any problem.&lt;/p&gt;

&lt;p&gt;Cheers and happy coding 🍻😉&lt;/p&gt;

&lt;p&gt;&lt;i&gt;This post was originally shared on medium. Check out my medium profile &lt;a href="https://medium.com/@vijit2ail"&gt;@vijit2ail&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>frontenddevelopment</category>
      <category>clientsiderouter</category>
      <category>javascriptframework</category>
    </item>
    <item>
      <title>Build a simple CSS grid layout system</title>
      <dc:creator>vijitail</dc:creator>
      <pubDate>Wed, 15 May 2019 18:48:52 +0000</pubDate>
      <link>https://dev.to/vijitail/build-a-simple-css-grid-layout-system-3nkn</link>
      <guid>https://dev.to/vijitail/build-a-simple-css-grid-layout-system-3nkn</guid>
      <description>&lt;p&gt;You must be very familiar with the layout system of popular CSS frameworks like Bootstrap, Bulma, etc. But have you ever wondered how these are built and work behind the scenes. 🤔&lt;/p&gt;

&lt;p&gt;In this story, lets try to build our own grid layout system and understand the basics. 😃&lt;/p&gt;

&lt;p&gt;I’ll be using Sass for this project so that less code can be written. Sass is really simple, and it won’t be difficult for you to follow along if you are a pure CSS person.&lt;br&gt;
&lt;a href="https://sass-lang.com/guide"&gt;Official Sass&lt;/a&gt; guide is a great place to start learning Sass.&lt;/p&gt;

&lt;p&gt;Lets begin by defining the responsive breakpoints&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8MvxFsby--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5d6xziawoxoxciv8hcj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8MvxFsby--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5d6xziawoxoxciv8hcj7.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These will declare the various screen sizes our grid would support.&lt;/p&gt;

&lt;p&gt;Next lets style the rows and columns&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PhesWr1D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bg9nec2dm08hgc5jx3mn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PhesWr1D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bg9nec2dm08hgc5jx3mn.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next few lines will be the core of our layout, basically we’ll loop through the breakpoints map and add media queries and create 12 columns for each breakpoint. We’ll also include containers for each breakpoints.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--64NhKTaL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hta7v1q3s0pidgksabnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--64NhKTaL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hta7v1q3s0pidgksabnc.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just imagine the amount of code that we would have had to write for the same thing in CSS. 🤦‍♂️ Anyways moving forward.&lt;/p&gt;

&lt;p&gt;To calculate the width of the column we need to divide the columns into 12 groups based on their size in terms of percentage.&lt;br&gt;
So to do that lets write a function in Sass that takes the column size as an argument and returns the width in percentage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L2WFZWCG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/sjshnfz6ui7vz8g1593c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L2WFZWCG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/sjshnfz6ui7vz8g1593c.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then call the function inside the for loop&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qDxQvw-t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qt3puqqt6w8nmmzgym6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qDxQvw-t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qt3puqqt6w8nmmzgym6e.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it we are done with the12 column layout system 🍻.&lt;/p&gt;

&lt;p&gt;As a bonus feature lets write a class that will remove the column margin and update our calcWidth() function accordingly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DAF3if95--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fywnam2lohpc5wf0ag1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DAF3if95--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fywnam2lohpc5wf0ag1z.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have a look at the layout in &lt;a href=""&gt;action&lt;/a&gt;. Resize your browser and see how the columns behave.&lt;/p&gt;




&lt;p&gt;Thanks for reading the post. If you would like to add any other feature let me know below or you can DM me on Instagram &lt;a href="https://instagram.com/vijit__ail"&gt;@vijit__ail&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;This post was originally posted on &lt;a href="https://medium.com/@vijit2ail/build-a-simple-css-grid-layout-system-8e37e3e16d5f"&gt;Medium&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>sass</category>
      <category>gridsystem</category>
    </item>
    <item>
      <title>Pull to refresh animation with Vanilla JavaScript</title>
      <dc:creator>vijitail</dc:creator>
      <pubDate>Sun, 12 May 2019 11:35:57 +0000</pubDate>
      <link>https://dev.to/vijitail/pull-to-refresh-animation-with-vanilla-javascript-17oc</link>
      <guid>https://dev.to/vijitail/pull-to-refresh-animation-with-vanilla-javascript-17oc</guid>
      <description>&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnaxkjcuajuvanrfym6cu.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnaxkjcuajuvanrfym6cu.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pull-to-refresh is a very popular swipe gesture on smartphones that allow users to load new content on top of listed data. Its used in all popular apps for smartphones and as well as in web apps these days and has become a major part of UX.&lt;/p&gt;




&lt;p&gt;A few days ago I came across this kind of animation on &lt;a href="https://dribbble.com/shots/4963449-Pull-to-Refresh-Animation" rel="noopener noreferrer"&gt;dribbble&lt;/a&gt;, so I thought why not come up with my version of it.&lt;/p&gt;

&lt;p&gt;Guess what, I managed to build this with no libraries or JQuery plugin, just plain Vanilla JavaScript. 😎&lt;/p&gt;

&lt;p&gt;A very simple markup , a top loading container that will contain the loader and a bunch of cards.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_Ih6pqytK38ZhOJ_anWDuw.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_Ih6pqytK38ZhOJ_anWDuw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s get to the fun stuff now 😁.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ABuVmdgooGuq8bNUs97wDOw.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ABuVmdgooGuq8bNUs97wDOw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is to hide the loading container by default and slide it down when the user swipes down.&lt;br&gt;
&lt;b&gt;transform-style : preserve-3d&lt;/b&gt; will enable the cards to be positioned in 3D space and the &lt;b&gt;perspective&lt;/b&gt; property on the card wrapper will determine how the user will see from their perspective; lower values will produce more intense 3D effects. Note that perspective is not set on the child elements.&lt;br&gt;
&lt;a href="https://3dtransforms.desandro.com/" rel="noopener noreferrer"&gt;More about CSS 3D animations and transforms&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That was it for the CSS, now let’s begin adding the swipe gesture.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AzpDoJNqjDREy9U5uXE2Kxw.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AzpDoJNqjDREy9U5uXE2Kxw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Touch events in JS are handled by the touch event listeners. These are similar to mouse events except they allow multiple touch on the touch surface.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AqtypiV59daSkoDAdaZ3VBQ.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AqtypiV59daSkoDAdaZ3VBQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;pStart and pCurrent objects will store the touch positions of the start and current touch. We’ll require these to find the change in the Y coordinate to calculate the rotation of the cards.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A5HSwcCE7va1TREQ-Rj4u7w.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A5HSwcCE7va1TREQ-Rj4u7w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the swipeStart() function, we’ll capture the touch coordinates and assign it to the pStart object.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_yDlEjxwPY82fVqm90JnmQ.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_yDlEjxwPY82fVqm90JnmQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the swipe() function, we are setting the pCurrent object with current touch coordinates. Next step is to find the difference between the start and current Y position to calculate the distance of swipe and make a rotation based on the 30th percent of the distance. The loading container will only appear if the distance is greater than 100.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AVl8xswbts96XM06u5CtQlA.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AVl8xswbts96XM06u5CtQlA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The swipeEnd() function will undo the rotation if the touch has begun but has not enabled the loading.&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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AcdXAjW9Ge8RMSZl7afiOPg.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%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AcdXAjW9Ge8RMSZl7afiOPg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While loading, the loading container will slide down for 2 seconds for the purposes of demonstration but in a real world example it can take longer or less time based on the response from the server. The loading container and cards will get back to original state once the loading has finished.&lt;/p&gt;

&lt;p&gt;I took reference for JavaScript from &lt;a href="https://stackoverflow.com/questions/46190436/how-to-detect-pull-to-refresh" rel="noopener noreferrer"&gt;this&lt;/a&gt; stackoverflow question.&lt;/p&gt;

&lt;p&gt;Complete source code in my &lt;a href="https://codepen.io/Vijit_Ail/pen/pmbypw" rel="noopener noreferrer"&gt;codepen&lt;/a&gt;. Open the devtools to see the animation in action.&lt;/p&gt;




&lt;p&gt;I hope you got to learn something new today 😄. If you have any questions or have any suggestions for improving the code, feel free to write your response.&lt;/p&gt;

&lt;p&gt;Cheers and happy coding 🍻 ✌&lt;/p&gt;

&lt;p&gt;This post was originally shared on medium. Check out my medium profile &lt;a href="https://medium.com/@vijit2ail" rel="noopener noreferrer"&gt;@vijit2ail&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>ui</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
