<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Clinton Joy - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Clinton Joy - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 05 May 2026 22:19:34 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/Cejay101/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Immutable JavaScript – How to Improve the Performance of Your JS Applications ]]>
                </title>
                <description>
                    <![CDATA[ Javascript has become a very popular programming language thanks to its growing use in frontend and backend development.  And as devs build JavaScript applications for different companies and organizations, the size and complexity of these applicatio... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/immutable-javascript-improve-application-performance/</link>
                <guid isPermaLink="false">66bc4c5c303bf450de87bc7c</guid>
                
                    <category>
                        <![CDATA[ immutability ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Clinton Joy ]]>
                </dc:creator>
                <pubDate>Mon, 05 Feb 2024 15:09:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/Screen-Shot-2024-02-01-at-11.16.23-AM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Javascript has become a very popular programming language thanks to its growing use in frontend and backend development. </p>
<p>And as devs build JavaScript applications for different companies and organizations, the size and complexity of these applications can pose interesting performance challenges.</p>
<p>As developers, we seek to create applications that not only have high performance but also have an enhanced user experience. To do this, we must fully understand how immutability works in Javascript, as this is one factor that contributes a lot to achieving the enhanced performance we seek.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ol>
<li><a class="post-section-overview" href="#heading-what-is-immutability-in-javascript">What is immutability in JavaScript?</a></li>
<li><a class="post-section-overview" href="#heading-benefits-of-immutability-in-applications">Benefits of Immutability in Applications</a></li>
<li><a class="post-section-overview" href="#heading-techniques-for-achieving-immutability">Techniques for Achieving Immutability</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-es6-features-for-immutability-spread-syntax-and-objectfreeze">How to Use ES6 Features for Immutability – Spread Syntax and <code>Object.freeze()</code></a></li>
<li><a class="post-section-overview" href="#heading-performance-optimization-through-immutability">Performance Optimization through Immutability</a></li>
<li><a class="post-section-overview" href="#heading-real-world-examples-of-companies-and-projects-benefiting-from-immutability">Real-World Examples of Companies and Projects Benefiting from Immutability</a></li>
<li><a class="post-section-overview" href="#heading-common-pitfalls-of-immutable-javascript">Common Pitfalls of Immutable JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-best-practices-for-overcoming-immutability-related-issues">Best Practices for Overcoming Immutability-Related Issues</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-what-is-immutability-in-javascript">What is Immutability in JavaScript?</h2>
<p>According to the Oxford English Learners Dictionary, immutability means "something that cannot be changed; that will never change," whereas on the other hand, we have mutability, which is the direct opposite of immutability and means something that can change.</p>
<p>If you want to grasp the full meaning of immutability, we have to differentiate it from mutability. Mutability, in JavaScript, refers to the ability to modify the value of a variable or a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures">data type</a>. Immutability, on the other hand, means that once a value is created, it cannot be changed. JavaScript differentiates data types by their default characters.</p>
<p>Primitive data types such as <code>strings</code>, <code>numbers</code>, <code>booleans</code>, and symbols are immutable, while reference data types such as <code>objects</code>, <code>arrays</code>, and <code>functions</code> are mutable. </p>
<p>To explain further, let's take a look at this simple example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> person1 = <span class="hljs-number">10</span>;
person2 = person1
person2 = <span class="hljs-number">8</span>;

<span class="hljs-built_in">console</span>.log(person2) <span class="hljs-comment">// 8</span>
<span class="hljs-built_in">console</span>.log(person1) <span class="hljs-comment">// 10</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/image-7.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On examining this example, it would seem as if <code>person1</code> was modified. But the variable <code>person1</code> was reassigned to take the value of <code>person2</code>. But when we check the value of <code>person1</code> in the console, we will notice that the value of <code>person1</code> remains unchanged.</p>
<p>This means that the <code>person2</code> variable is just a clone of the <code>person1</code> variable that has been reassigned, and the actual value of the <code>person1</code> variable was not modified. </p>
<p>On the other hand, if we were to try to do the same with a reference data type, here's what would happen:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> student1 = {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Kevin"</span>,
    <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>,
};

student2 = student1;

student2.name = <span class="hljs-string">"Paul"</span>;

<span class="hljs-built_in">console</span>.log(student1) <span class="hljs-comment">// {name: 'Paul', age: 20}</span>
<span class="hljs-built_in">console</span>.log(student2) <span class="hljs-comment">// {name: 'Paul', age: 20}</span>
</code></pre>
<p><img src="https://hackmd.io/_uploads/B1WcDwZDp.png" alt="Screen Shot 2023-12-21 at 9.21.34 AM" width="600" height="400" loading="lazy">
<em>Mutable data example</em></p>
<p>On close inspection, you'll notice that as we set <code>student2</code> to be equal to <code>student1</code> and reassign the value of <code>student2.name</code>, it also changes the value of <code>student1.name</code>. This means that the value of <code>student1</code> was not just reassigned but modified. This proves that reference data types are mutable.</p>
<h2 id="heading-benefits-of-immutability-in-applications">Benefits of Immutability in Applications</h2>
<p>You may already be wondering: Isn't it a good thing for your variable to be mutable rather than rigid? Though mutability comes with some perks, so does immutability. In this section, we will see the benefits of immutability in applications.</p>
<p>First of all, immutable data structures are more stable and predictable. They're immune to unexpected alterations, rendering the code more deterministic and less prone to unforeseen bugs or side effects, which is very useful in large-scale applications.</p>
<p>You also have fewer bugs and data races. Immutability eliminates the possibility of accidentally modifying data in place, which can lead to data races and concurrency issues. By preventing direct modifications, immutability promotes thread safety and ensures that data remains consistent across multiple threads or processes.</p>
<p>Memory management and optimization also improve with immutability. It improves memory utilization by enabling safe data structure sharing, eliminating concerns about unintended modifications. </p>
<p>While the idea of creating copies might seem counterintuitive in pursuit of immutability, it is balanced by the benefits of structural sharing, efficient garbage collection, and the design of data structures.</p>
<p>These elements work to ensure that, despite the initial creation of copies for immutability, the long-term memory optimization prevails. The utilization of structural sharing minimizes the need for complete data duplication, while efficient garbage collection promptly removes unused data structures, contributing to optimal memory usage over time. </p>
<p>This approach not only reduces memory overhead but also optimizes resource utilization, playing a crucial role in scaling applications efficiently.</p>
<p>And finally, immutability produces more effective testing and debugging. Immutable data simplifies testing and debugging by providing a stable and predictable environment. Since objects cannot be modified, tests can focus on specific behaviors without worrying about external changes. This makes it easier to isolate and fix bugs.</p>
<h2 id="heading-techniques-for-achieving-immutability">Techniques for Achieving Immutability</h2>
<p>You can achieve immutability in JavaScript in a lot of ways, from using a persistent data structure to using ES6 features such as <code>Object.freeze()</code>. This section seeks to explain these techniques for achieving immutability and how you can use them.</p>
<h3 id="heading-introduction-to-persistent-data-structures">Introduction to Persistent Data Structures</h3>
<p>Persistence in data structures refers to the ability to retain the previous version while accommodating changes. In traditional mutable data structures, alterations directly modify the existing data. But in <a target="_blank" href="https://en.wikipedia.org/wiki/Persistent_data_structure#1">persistent data structures</a>, any modification creates a new version of the structure, leaving the original intact.</p>
<p>This characteristic is what makes persistent data structures inherently immutable. This promotes code reliability, efficient memory utilization, and allows for concurrent operations.</p>
<p>JavaScript itself, as a language, does not inherently offer persistent data structures in its standard library. But libraries and frameworks in JavaScript, like <a target="_blank" href="https://immutable-js.com/">Immutable.js</a>, offer implementations of persistent data structures. </p>
<p>Immutable.js provides various persistent data structures, including:</p>
<ul>
<li>Persistent List</li>
<li>Persistent Maps &amp; Sets</li>
<li>Persistent Trees</li>
</ul>
<h3 id="heading-persistent-lists">Persistent Lists</h3>
<p>Persistent lists, like immutable linked lists, allow for efficient modifications by creating new versions while reusing the majority of the existing structure.<br>Let's consider this example:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ShoppingList</span> </span>{
  <span class="hljs-keyword">constructor</span>(item, next = null) {
    <span class="hljs-built_in">this</span>.item = item;
    <span class="hljs-built_in">this</span>.next = next;
  }

  addItem(newItem) {
    <span class="hljs-comment">// Create a copy of the list</span>
    <span class="hljs-keyword">const</span> copiedList = <span class="hljs-built_in">this</span>.copyList();
    <span class="hljs-comment">// Add the new item to the copied list</span>
    <span class="hljs-keyword">return</span> copiedList.addItemToCopy(newItem);
  }

  addItemToCopy(newItem) {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ShoppingList(newItem, <span class="hljs-built_in">this</span>);
  }

  removeItem(itemToRemove) {
    <span class="hljs-comment">// Create a copy of the list</span>
    <span class="hljs-keyword">const</span> copiedList = <span class="hljs-built_in">this</span>.copyList();
    <span class="hljs-keyword">let</span> current = copiedList;
    <span class="hljs-keyword">let</span> previous = <span class="hljs-literal">null</span>;

    <span class="hljs-keyword">while</span> (current !== <span class="hljs-literal">null</span>) {
      <span class="hljs-keyword">if</span> (current.item === itemToRemove) {
        <span class="hljs-keyword">if</span> (previous === <span class="hljs-literal">null</span>) {
          <span class="hljs-keyword">return</span> current.next;
        } <span class="hljs-keyword">else</span> {
          previous.next = current.next;
          <span class="hljs-keyword">return</span> copiedList;
        }
      }
      previous = current;
      current = current.next;
    }
    <span class="hljs-keyword">return</span> copiedList;
  }

  copyList() {
    <span class="hljs-comment">// Create a copy of the list</span>
    <span class="hljs-keyword">let</span> current = <span class="hljs-built_in">this</span>;
    <span class="hljs-keyword">let</span> newList = <span class="hljs-literal">null</span>;
    <span class="hljs-keyword">let</span> newListTail = <span class="hljs-literal">null</span>;

    <span class="hljs-keyword">while</span> (current !== <span class="hljs-literal">null</span>) {
      <span class="hljs-keyword">if</span> (newList === <span class="hljs-literal">null</span>) {
        newList = <span class="hljs-keyword">new</span> ShoppingList(current.item);
        newListTail = newList;
      } <span class="hljs-keyword">else</span> {
        newListTail.next = <span class="hljs-keyword">new</span> ShoppingList(current.item);
        newListTail = newListTail.next;
      }
      current = current.next;
    }
    <span class="hljs-keyword">return</span> newList;
  }
}

<span class="hljs-comment">// Creating a persistent shopping list</span>
<span class="hljs-keyword">const</span> originalList = <span class="hljs-keyword">new</span> ShoppingList(<span class="hljs-string">"Milk"</span>).addItem(<span class="hljs-string">"Eggs"</span>).addItem(<span class="hljs-string">"Bread"</span>);
<span class="hljs-keyword">const</span> updatedList = originalList.addItem(<span class="hljs-string">"Butter"</span>).addItem(<span class="hljs-string">"Cheese"</span>);

<span class="hljs-comment">// Removing an item from the list</span>
<span class="hljs-keyword">const</span> removedItem = updatedList.removeItem(<span class="hljs-string">"Eggs"</span>);

<span class="hljs-comment">// Logging the original, updated, and list after removing an item</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Original List:"</span>);
<span class="hljs-built_in">console</span>.log(originalList);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\nUpdated List:"</span>);
<span class="hljs-built_in">console</span>.log(updatedList);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\nList after removing an item:"</span>);
<span class="hljs-built_in">console</span>.log(removedItem);
</code></pre>
<p>In our code above, we define a class called <code>ShoppingList</code> which we use as a representation of a persistent shopping list. This persistent shopping list is one that can be modified and added to over time.</p>
<p>We have a constructor <code>constructor(item, next = null)</code> which initializes a new list node with the specified item and an optional reference to the next node.</p>
<p>The <code>addItem(newItem)</code> method creates a copy of the current list, adds the new item to the copy, and returns the modified copy. This ensures that the original list remains unchanged. The private <code>addItemToCopy(newItem)</code> method appends the new item to the end of the copied list. It creates a new list node with the new item and links it to the end of the copied list.</p>
<p>Then we have the <code>removeItem(itemToRemove)</code> method which is used to create a copy of the current list. It then searches for the specified item to remove, and returns the modified copy. It handles the case of removing an item from the beginning or middle of the list.</p>
<p>The <code>copyList()</code> method recursively traverses the current list, creating new list nodes in the copied list and linking them together. It ensures that the copied list accurately represents the original list.</p>
<p>This example demonstrates using the ShoppingList class to create a persistent shopping list. It starts with an initial list of "Milk", "Eggs", and "Bread", adds "Butter" and "Cheese", and then removes "Eggs".</p>
<p>Here is the result of our code:</p>
<p><img src="https://hackmd.io/_uploads/r1Uk3SNup.png" alt="Screen Shot 2024-01-04 at 5.16.10 PM" width="600" height="400" loading="lazy"></p>
<p><img src="https://hackmd.io/_uploads/Byf9CH4_p.png" alt="Screen Shot 2024-01-04 at 5.27.59 PM" width="600" height="400" loading="lazy">
<em>Persistent list Example</em></p>
<p>As you can see, despite updating the list, the original list still retains its original data and can be accessed.</p>
<h3 id="heading-persistent-maps-and-sets">Persistent Maps and Sets</h3>
<p>Persistent maps and sets retain their previous versions when modified, offering efficient key-value pair storage or unique value collections with immutability.<br>Let's consider this example:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TreasureChest</span> </span>{
  <span class="hljs-keyword">constructor</span>(contents = {}) {
    <span class="hljs-built_in">this</span>.contents = { ...contents };
  }

  addTreasure(key, value) {
    <span class="hljs-keyword">const</span> newContents = { ...this.contents, [key]: value };
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TreasureChest(newContents);
  }
}

<span class="hljs-comment">// Creating a persistent treasure chest (map-like)</span>
<span class="hljs-keyword">const</span> originalChest = <span class="hljs-keyword">new</span> TreasureChest({ <span class="hljs-attr">gold</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">gems</span>: <span class="hljs-number">5</span> });
<span class="hljs-keyword">const</span> updatedChest = originalChest.addTreasure(<span class="hljs-string">"diamonds"</span>, <span class="hljs-number">10</span>);

<span class="hljs-comment">// Logging the original and updated chests</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Original Chest:"</span>);
<span class="hljs-built_in">console</span>.log(originalChest);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\nUpdated Chest:"</span>);
<span class="hljs-built_in">console</span>.log(updatedChest);
</code></pre>
<p>Above, we have a real-world code example. I like to call her Treasure Chest. In the code, we define a class called <code>TreasureChest</code> to represent a treasure chest that holds various items. The constructor method initializes the treasure chest with an optional contents object, which represents the initial items in the chest. If no contents object is provided, an empty object is used.</p>
<p>The <code>addTreasure</code> method adds a new item to the treasure chest. It takes two arguments: the name of the item (<code>key</code>) and the quantity (<code>value</code>). It creates a new contents object by merging the current contents with a new entry for the specified item, ensuring that the new item is added without modifying the original contents. It then creates a new <code>TreasureChest</code> object using the updated contents and returns it.</p>
<p>From the code, you can see we created two instances for the <code>TreasureChest</code> class. First the <code>originalChest</code> and then the <code>updatedChest</code>. <code>originalChest</code> is initialized with { <code>gold: 100, gems: 5</code> }, representing a chest with 100 gold coins and 5 gems. <code>updatedChest</code> is created using <code>originalChest.addTreasure('diamonds', 10)</code>, adding 10 diamonds to the chest.  </p>
<p><img src="https://hackmd.io/_uploads/HyU7JIVua.png" alt="Screen Shot 2024-01-04 at 5.30.27 PM" width="600" height="400" loading="lazy">
<em>Persistent Maps and Sets Example</em></p>
<p>From our console, we can confirm that this immutability technique works as our original Chest value is retrieved.</p>
<h3 id="heading-persistent-trees">Persistent Trees</h3>
<p>Persistent trees, such as binary trees or trie structures, are yet another technique for achieving immutability. They maintain previous versions during operations like insertion, deletion, or search. They create new tree instances upon modifications while reusing unchanged parts from the original tree.</p>
<p>This preservation of versions enables efficient manipulation and retrieval of data without mutating the original tree. Aside from immutability, a persistent tree also has some key characteristics, such as shared structure and efficient modifications.</p>
<p>These two features let us share unchanged parts between versions of our tree and enable efficient operations (such as insertion, deletion, or traversal) by reusing existing nodes and creating new branches only when necessary, respectively.<br>Here is an example:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TreeNode</span> </span>{
  <span class="hljs-keyword">constructor</span>(value, left = null, right = null) {
    <span class="hljs-built_in">this</span>.value = value;
    <span class="hljs-built_in">this</span>.left = left;
    <span class="hljs-built_in">this</span>.right = right;
  }

  insert(newValue) {
    <span class="hljs-keyword">if</span> (newValue &lt; <span class="hljs-built_in">this</span>.value) {
      <span class="hljs-comment">// Insert to the left</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TreeNode(
        <span class="hljs-built_in">this</span>.value,
        <span class="hljs-built_in">this</span>.left ? <span class="hljs-built_in">this</span>.left.insert(newValue) : <span class="hljs-keyword">new</span> TreeNode(newValue),
        <span class="hljs-built_in">this</span>.right
      );
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// Insert to the right</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TreeNode(
        <span class="hljs-built_in">this</span>.value,
        <span class="hljs-built_in">this</span>.left,
        <span class="hljs-built_in">this</span>.right ? <span class="hljs-built_in">this</span>.right.insert(newValue) : <span class="hljs-keyword">new</span> TreeNode(newValue)
      );
    }
  }
}

<span class="hljs-comment">// Creating a simplified tree structure</span>
<span class="hljs-keyword">const</span> root = <span class="hljs-keyword">new</span> TreeNode(<span class="hljs-number">5</span>);
root.left = <span class="hljs-keyword">new</span> TreeNode(<span class="hljs-number">3</span>);
root.right = <span class="hljs-keyword">new</span> TreeNode(<span class="hljs-number">8</span>);

<span class="hljs-comment">// Logging the original tree</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Original Tree:"</span>);
<span class="hljs-built_in">console</span>.log(root);

<span class="hljs-comment">// Creating an updated tree by inserting a new value (in this case, 10)</span>
<span class="hljs-keyword">const</span> updatedRoot = root.insert(<span class="hljs-number">10</span>);

<span class="hljs-comment">// Logging the updated tree</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\nUpdated Tree:"</span>);
<span class="hljs-built_in">console</span>.log(updatedRoot);
</code></pre>
<p>In the code above, we focused on creating and modifying a <code>TreeNode</code>. We defined a <code>TreeNode</code> class that represents a node in a binary tree. A binary tree is a hierarchical data structure where each node can have up to two child nodes, referred to as the left child and the right child.</p>
<p>Our <code>TreeNode</code> class has two constructors: the default constructor, which creates a node with the specified value, and two child nodes, which can also be null. The left and right properties represent the left and right child nodes, respectively.</p>
<p>The <code>TreeNode</code> class also has the insert method, which is used to insert a new value into the tree. The method takes a single argument, which is the value to be inserted.</p>
<p>The insert method first compares the new value to the value of the current node. If the new value is less than the value of the current node, it is inserted to the left of the current node. If the new value is greater than the value of the current node, it is inserted to the right of the current node.</p>
<p>If the current node does not have a child node corresponding to the insertion direction, a new node is created and inserted as the child node. If the current node already has a child node in that direction, the insertion method is recursively called on that child node to handle the insertion.</p>
<p>The code then creates a simplified tree structure with the root node having value 5, a left child node with value 3, and a right child node with value 8. Later on, we insert a new value of 10 into the tree using the insert method of the root node.</p>
<p><img src="https://hackmd.io/_uploads/SkQ2yLEOa.png" alt="Screen Shot 2024-01-04 at 5.32.43 PM" width="600" height="400" loading="lazy">
<em>Persistent Tree Example</em></p>
<h2 id="heading-how-to-use-es6-features-for-immutability-spread-syntax-and-objectfreeze">How to Use ES6 Features for Immutability – Spread Syntax and <code>Object.freeze()</code></h2>
<p>At the start of this tutorial, I explained the difference between mutable and immutable data types, and we saw some examples illustrating how they work. </p>
<p>Mutable data types such as arrays and objects are still super useful, and through the use of some ES6 features such as the spread operator and <code>Object.freeze</code>, we can utilize data types like arrays and objects while maintaining a degree of immutability.</p>
<h3 id="heading-the-spread-syntax">The Spread Syntax</h3>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread operator (…)</a> in JavaScript is a powerful tool that facilitates the creation of shallow copies of arrays, objects, and iterables. When it comes to immutability, the spread operator plays a crucial role in ensuring that the original data remains unchanged while allowing the creation of new, independent data structures.</p>
<p>Let's consider an array in JavaScript:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> originalArray = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];
</code></pre>
<p>Using the spread operator, you can create an immutable copy of this array:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> immutableCopy = [...originalArray];
</code></pre>
<p>Here, <code>immutableCopy</code> holds a new array with the same elements as <code>originalArray</code>. Any modifications to <code>immutableCopy</code> won't affect <code>originalArray</code>, ensuring the immutability of the original data. This technique has been adopted by a lot of developers in modern-day software development.</p>
<h3 id="heading-the-objectfreeze-method">The <code>Object.freeze()</code> method</h3>
<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze"><code>Object.freeze()</code></a> is a method that can be used on reference data types. It prevents any form of modification or addition to an object, thereby creating an object with a read-only type.</p>
<p>Let's consider this example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Creating an immutable object using Object.freeze()</span>
<span class="hljs-keyword">const</span> originalObj = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Alice"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">25</span> };
<span class="hljs-keyword">const</span> immutableObj = <span class="hljs-built_in">Object</span>.freeze(originalObj); <span class="hljs-comment">// Freezes the object</span>

<span class="hljs-comment">// Attempting to modify a frozen object (in strict mode)</span>
immutableObj.age = <span class="hljs-number">30</span>; <span class="hljs-comment">// This change will not take effect (in strict mode)</span>
<span class="hljs-built_in">console</span>.log(originalObj);
<span class="hljs-built_in">console</span>.log(immutableObj);
</code></pre>
<p>In the code, the <code>originalObj</code> is a simple object with two properties: <code>name</code> and <code>age</code>. The <code>immutableObj</code> is created by calling <code>Object.freeze(originalObj)</code>. This effectively freezes the <code>originalObj</code>, preventing any further modifications to its properties.</p>
<p>We then try to code to modify the <code>immutableObj</code> by changing its age property to 30. However, since the object is frozen, this change will not take effect. In strict mode, attempting to modify a frozen object will result in a type error.</p>
<p><img src="https://hackmd.io/_uploads/r16WDjNvp.png" alt="Screen Shot 2023-12-23 at 8.29.17 PM" width="600" height="400" loading="lazy"></p>
<p>Without strict mode, the <code>immutableObj</code> object remains immutable.</p>
<p><img src="https://hackmd.io/_uploads/ByKYwjNwT.png" alt="Screen Shot 2023-12-23 at 8.30.34 PM" width="600" height="400" loading="lazy">
<em>Object.freeze for javaScript immutability.</em></p>
<h2 id="heading-performance-optimization-through-immutability">Performance Optimization through Immutability</h2>
<p>Immutability, unchangeability—you might wonder, does this cause more harm than good? Well, let's see.</p>
<p>Let's consider a few more steps in the process, like safeguarding your data. These steps are an investment in stability and predictability.</p>
<p>In mutable structures, whenever data changes, it involves copying or altering existing data, which can get messy, especially in large-scale applications.</p>
<p>When you're dealing with tons of data and constantly modifying it in a mutable structure, your code has to keep track of those changes. This constant tracking and altering can add up, leading to higher computational costs.</p>
<p>On the other hand, with immutable data, once created, it stays put. This means fewer surprises and less overhead in managing changes.</p>
<h3 id="heading-comparison-of-mutable-vs-immutable-data">Comparison of mutable vs. immutable data</h3>
<p>When comparing mutable and immutable data structures in large-scale applications, it's essential to highlight the fundamental differences that affect performance, memory usage, and overall stability.</p>
<p>Here's a breakdown in a more technical manner:</p>
<table><thead><tr><th><span>Aspect</span></th><th><span>Mutablility</span></th><th><span>Immutability</span></th></tr></thead><tbody><tr><td><span>Memory Management</span></td><td><span>Tend to require more memory due to in-place modifications.</span></td><td><span>Often use memory more efficiently by creating new instances.</span></td></tr><tr><td><span>Concurrent Access</span></td><td><span>Prone to issues with concurrent access (race conditions).</span></td><td><span>Safe for concurrent access as data doesn't change.</span></td></tr><tr><td><span>Error-Prone</span></td><td><span>Mutable states can lead to unintended bugs and errors.</span></td><td><span>Immutable structures minimize unintended side effects, reducing errors.</span></td></tr><tr><td><span>Ease of Reasoning and Debugging</span></td><td><span>Tracking changes can be complex, making debugging harder.</span></td><td><span>Easier to reason about as data remains consistent. Debugging is more straightforward.</span></td></tr><tr><td><span>Scalability</span></td><td><span>Can pose challenges in managing state changes at scale.</span></td><td><span>Facilitate scalability due to predictable and consistent data.</span></td></tr></tbody></table>

<p>As you can see from the table, there is a lot to benefit from adopting immutability.</p>
<h2 id="heading-real-world-examples-of-companies-and-projects-benefiting-from-immutability">Real-World Examples of Companies and Projects Benefiting from Immutability</h2>
<p>Immutability in programming is a concept that has several advantages, and several companies and projects have benefited from it. Some of the companies are Facebook, Github, Netflix, WhatsApp, and Uber.</p>
<p>React, a Facebook library, uses immutability as a major principle, providing improved performance and responsiveness. Github, a collaborative tool, also makes use of React in its user interface, thereby benefiting from immutability. Netflix, WhatsApp, and Uber also benefit from immutability by making use of immutable data structures to produce consistent and reliable applications.</p>
<p>These are a few of the many examples of companies benefiting from immutability.</p>
<h2 id="heading-common-pitfalls-of-immutable-javascript">Common Pitfalls of Immutable JavaScript</h2>
<p>Although immutability has its advantages, it can also be quite challenging if you don't use it properly. Most of the time, many beneficial things come with a cost.</p>
<p>Immutability may cause a decrease in performance if used on large datasets, because new data structures are created instead of modifying existing ones.<br>Also totally learning the immutable approach to programming can be quite tasking, since it may involve learning how to use new libraries and techniques. But it's definitely worth it.</p>
<p>Since immutability works hand in hand with functional programming, it's also a good idea for someone implementing immutability to learn functional programming.</p>
<h3 id="heading-data-races-and-concurrency-issues">Data races and concurrency issues</h3>
<p>When working with immutable data, data races and concurrency issues can still be potential issues. Some of these issues relate to shared reference, asynchronous operations, and state management.</p>
<p>While the data itself might be immutable, references to that data can still be shared among different parts of the code. And if multiple parts of the codebase hold references to the same immutable data and one of them attempts to modify it (even though it can't change the original data), it can cause unintended consequences or unexpected behavior elsewhere in the code that relies on the unchanged data.</p>
<p>In JavaScript, asynchronous operations can introduce concurrency issues. Even though JavaScript is single-threaded, asynchronous functions (like fetching data from APIs or handling events) can create scenarios where different parts of the code operate at different times. </p>
<p>If these asynchronous operations involve shared state, even with immutable data, managing the changes or handling the state updates can lead to unexpected behavior or bugs.</p>
<p>While immutability helps in maintaining predictable state changes, managing the state across an application can still be a challenge. Libraries like Redux in React applications, for instance, rely heavily on immutable data principles to manage state changes effectively. But improper handling of state updates or mutations within such libraries can lead to unexpected behavior.</p>
<h2 id="heading-best-practices-for-overcoming-immutability-related-issues">Best Practices for Overcoming Immutability-Related Issues</h2>
<p>Since immutability can pose some challenges, especially when used in a large-scale applications, it's a good idea to learn ways that we can overcome these challenges.</p>
<ul>
<li>Selective usage: To avoid decreased performance in your projects, you can choose where to use immutable data. Since immutability relies on creating new datasets instead of modifying them, you should use it in parts of your projects that do not require high performance.</li>
<li>Avoid deep cloning: Deep clones of data structures can be resource-intensive, so it's best to make use of shallow or partial updates if they can also provide the same results for you.</li>
<li>Implement Copy-on-Write strategy: The creation of new copies of data should only be used when you need data in a data structure to be modified. This can reduce copies that could be avoided, thereby increasing performance.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The benefits of leveraging immutability in your applications are clear. Immutability serves as a powerful tool that can help you reduce bugs, improve responsiveness, and prevent unnecessary re-renders. </p>
<p>It may still pose some challenges, but through practicing the right strategies, you can handle them and use them to develop very high-quality as well as cost-effective applications.</p>
<p>Immutability remains an essential component of the optimization and responsiveness of large-scale applications being built in the JavaScript community, an area where JavaScript is still growing.</p>
<p>As a developer, learning to apply the immutable method of programming will go a long way toward optimizing most of your projects and reducing the occurrence of bugs and errors. Learning this method of programming would be an investment that yields long-term benefits.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build an Image Carousel with React and Framer Motion ]]>
                </title>
                <description>
                    <![CDATA[ You've probably come across carousels in many modern-day applications. Known by various names such as sliders or rotators, these versatile web elements showcase content in a visually appealing, sliding, or rotating manner.  Carousels can help you sav... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-an-image-carousel-with-react-and-framer-motion/</link>
                <guid isPermaLink="false">66bc4c55a37e8c5876cb4d67</guid>
                
                    <category>
                        <![CDATA[ animation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Clinton Joy ]]>
                </dc:creator>
                <pubDate>Mon, 03 Jul 2023 09:47:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-26-at-10.45.34.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You've probably come across carousels in many modern-day applications. Known by various names such as sliders or rotators, these versatile web elements showcase content in a visually appealing, sliding, or rotating manner. </p>
<p>Carousels can help you save space as well as enhance your User Interface and provide a great user experience.</p>
<p>Carousels have become a staple in UI design, often used to display images, testimonials, and more. They are indispensable when creating an engaging and dynamic interface.</p>
<p>In this article, we'll dive into the process of building an image carousel using React and Framer Motion, guiding you through every step to create a stunning and interactive visual component for your application.</p>
<h2 id="heading-what-is-framer-motion">What is Framer Motion?</h2>
<p>This is an open-source animation library for React applications that you can use to create dynamic and responsive animations for our web application.</p>
<p>Framer motion has several helpful features, including:</p>
<ol>
<li>Animation: This allows you to do seamless transitions for your components.</li>
<li>Gesture: It supports touch and mouse motions, which allows you to account for certain events.</li>
<li>Variants: Framer motion enables you to declare components declaratively, keeping your code organized and reusable.</li>
</ol>
<p>All these features are very useful and we will see them in action soon.</p>
<p>To gain a deeper understanding of Framer Motion, you can explore its <a target="_blank" href="https://www.framer.com/motion/">documentation and resources</a>. But for this article, we'll focus on the fundamentals. As I guide you through the basics of utilizing Framer Motion, my primary goal is to build an impressive and engaging image carousel.</p>
<h2 id="heading-how-to-set-up-your-development-environment">How to Set Up Your Development Environment</h2>
<p>The first thing we are gonna do is to set up your development Environment. This involves installing the necessary packages to successfully build your application. This includes installing <a target="_blank" href="https://nodejs.dev/en/download/">Node.js</a> and <a target="_blank" href="https://www.npmjs.com/package/download">npm</a></p>
<p>If you already have Node.js and npm installed, you don't need to download and install them again.</p>
<h3 id="heading-create-a-react-application">Create a React application</h3>
<p>At this point, I will assume you have Node and npm installed. To create a React application, simply go to your terminal and visit the directory you want your application to be in. Then run this command:</p>
<pre><code class="lang-js">npx create-react-app react-image-carousel
</code></pre>
<p>You can name your application whatever you want – but for the purpose of this article I will be calling it <code>react-image-carousel</code>.</p>
<p>When your React application is successfully created, open up your directory in your code editor. You should get some default files and styles and it should look something like this:</p>
<p><img src="https://i.imgur.com/rC9qt5N.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We won't need most of these files and styles for this project so you can clear up files like the: app.test.js, and logo.svg, and reportWebVitals.js,setupTest.js. You can also delete all the default styles in the App.css sheet.</p>
<p><img src="https://i.imgur.com/3en8Ssk.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now that your React application is created and set up, the last step in setting up your development environment for this project is installing Framer motion. </p>
<p>To do this, simply go to your terminal make sure you are in the project directory and run this command:</p>
<pre><code class="lang-js"> npm  install framer-motion
</code></pre>
<p>and this should install the latest version of Framer Motion. Now you should be good to go. Simply use <code>npm run start</code> to fire the development server on your browser.</p>
<h2 id="heading-how-to-design-the-image-carousel-component">How to Design the Image Carousel Component</h2>
<p>To kick off the design we will first create a <code>Carousel.js</code> component. In the carousel component, we will import the <code>useState</code> hook from React and then the <code>motion</code> and <code>AnimatePresence</code> properties from Framer Motion.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { motion, AnimatePresence } <span class="hljs-keyword">from</span> <span class="hljs-string">"framer-motion"</span>;
</code></pre>
<p>We then create our carousel function which takes in the <code>images</code> prop  which will be an array of image URLs:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Carousel = <span class="hljs-function">(<span class="hljs-params">{ images }</span>) =&gt;</span> {};
</code></pre>
<p>In our carousel function, we initialize a state variable with useState to keep track of the current image index we use <code>setCurrentIndex</code> as the corresponding function to update the index.</p>
<p>Next, we create 3 helper functions to handle user interactions which include:</p>
<ul>
<li>handleNext: this updates the currentIndex to the next index in order to change the image and if it reaches the end of the array it cycles back.</li>
<li>handlePrevious: this does the same as the handleNext function, but this time in reverse order. This allows us to go back to images.</li>
<li>handleDotClick: this takes an index as a parameter and updates the currentIndex. With this, we can jump forward and backward to images just by clicking the dots.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Carousel = <span class="hljs-function">(<span class="hljs-params">{ images }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [currentIndex, setCurrentIndex] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> handleNext = <span class="hljs-function">() =&gt;</span> {
    setCurrentIndex(<span class="hljs-function">(<span class="hljs-params">prevIndex</span>) =&gt;</span>
      prevIndex + <span class="hljs-number">1</span> === images.length ? <span class="hljs-number">0</span> : prevIndex + <span class="hljs-number">1</span>
    );
  };
  <span class="hljs-keyword">const</span> handlePrevious = <span class="hljs-function">() =&gt;</span> {
    setCurrentIndex(<span class="hljs-function">(<span class="hljs-params">prevIndex</span>) =&gt;</span>
      prevIndex - <span class="hljs-number">1</span> &lt; <span class="hljs-number">0</span> ? images.length - <span class="hljs-number">1</span> : prevIndex - <span class="hljs-number">1</span>
    );
  };
  <span class="hljs-keyword">const</span> handleDotClick = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
    setCurrentIndex(index);
  };
</code></pre>
<p>These are the helper functions we will need for our component</p>
<h3 id="heading-how-to-create-our-template">How to Create our Template</h3>
<p>Our template is a pretty simple one and is made up of our image, our slider direction, and the dots (indicator).</p>
<pre><code class="lang-jsx">  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"carousel"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span>
          <span class="hljs-attr">key</span>=<span class="hljs-string">{currentIndex}</span>
          <span class="hljs-attr">src</span>=<span class="hljs-string">{images[currentIndex]}</span>
        /&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"slide_direction"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"left"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handlePrevious}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
            <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
            <span class="hljs-attr">height</span>=<span class="hljs-string">"20"</span>
            <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 96 960 960"</span>
            <span class="hljs-attr">width</span>=<span class="hljs-string">"20"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M400 976 0 576l400-400 56 57-343 343 343 343-56 57Z"</span> /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"right"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleNext}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
            <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
            <span class="hljs-attr">height</span>=<span class="hljs-string">"20"</span>
            <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 96 960 960"</span>
            <span class="hljs-attr">width</span>=<span class="hljs-string">"20"</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"m304 974-56-57 343-343-343-343 56-57 400 400-400 400Z"</span> /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"indicator"</span>&gt;</span>
        {images.map((_, index) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
            <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">dot</span> ${<span class="hljs-attr">currentIndex</span> === <span class="hljs-string">index</span> ? "<span class="hljs-attr">active</span>" <span class="hljs-attr">:</span> ""}`}
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> handleDotClick(index)}
          &gt;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
</code></pre>
<p>As you can see in the template, we display the image at the current index. Then we have a div of <code>slider_direction</code> which holds two divs with class names <code>left</code> and <code>right</code>. We created these as navigation buttons for the carousel. They use inline SVGs to display arrow icons, and their onClick handlers are set to <code>handlePrevious</code> and <code>handleNext</code>, respectively.</p>
<p>We also have an indicator div which we created to display a series of dots that represent each image in the carousel. It maps over the images array and creates a dot for each image, setting the active class for the dot corresponding to the <code>currentIndex</code>. </p>
<p>We then attached an onClick handler for each dot which is set to call <code>handleDotClick</code> with the index of the dot.</p>
<p>And that should be our template, for now. All that is left is to export the carousel component, import it into the <code>App.js</code> component, and add some CSS. Then we will be ready to start animating.</p>
<p>So we simply export our carousel function from our <code>Carousel.js</code> component.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Carousel;
</code></pre>
<h2 id="heading-how-to-use-the-carousel-component">How to Use the Carousel Component</h2>
<p>We have created our carousel component. But to use it we have to import it into our App.js component:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> Carousel <span class="hljs-keyword">from</span> <span class="hljs-string">"./Carousel"</span>;
</code></pre>
<p>After that, we can create our images array, which will hold our image URLs.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> images = [
  <span class="hljs-string">"https://images.pexels.com/photos/169647/pexels-photo-169647.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=600"</span>,
  <span class="hljs-string">"https://images.pexels.com/photos/313782/pexels-photo-313782.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1260&amp;h=750&amp;dpr=1"</span>,
  <span class="hljs-string">"https://images.pexels.com/photos/773471/pexels-photo-773471.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1260&amp;h=750&amp;dpr=1"</span>,
  <span class="hljs-string">"https://images.pexels.com/photos/672532/pexels-photo-672532.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1260&amp;h=750&amp;dpr=1"</span>,
  <span class="hljs-string">"https://images.pexels.com/photos/632522/pexels-photo-632522.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1260&amp;h=750&amp;dpr=1"</span>,
  <span class="hljs-string">"https://images.pexels.com/photos/777059/pexels-photo-777059.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1260&amp;h=750&amp;dpr=1"</span>,
];
</code></pre>
<p>These are just images I got from <a target="_blank" href="https://www.pexels.com/">pexels</a> – that's what we are gonna use for this project.</p>
<p>Next, we add our App function which will hold our application template.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Image Carousel using React and Framer Motion<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Carousel</span> <span class="hljs-attr">images</span>=<span class="hljs-string">{images}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>As you can see, we have our header that just displays a header showing what our application is about. </p>
<p>Then we have the main section which has our carousel component added and takes in a prop of the images array. If you recall, this was the prop we used in our carousel component to display images.</p>
<p>Lastly, we export the App component so we can use it in the index.js file.</p>
<p>To see all this together with no styling, run the <code>npm run start</code> command. The application should look like this:</p>
<p><img src="https://i.imgur.com/xN2meFY.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Ugly right? Yes, I agree with you. But with just a few lines of CSS, this will be transformed. So let's dive in.</p>
<h3 id="heading-how-to-add-the-css">How to Add the CSS</h3>
<p>I don't want to create a separate style sheet for the carousel component, so we will do all our CSS in the App.css file. Don't forget to import your style sheet.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>
</code></pre>
<p>This is our CSS:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> url(<span class="hljs-string">"https://fonts.googleapis.com/css2?family=Oswald:wght@600&amp;display=swap"</span>);
<span class="hljs-selector-class">.App-header</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1rem</span>;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">"Oswald"</span>, sans-serif;
  <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">2rem</span>;
}
<span class="hljs-selector-class">.carousel-images</span> {
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">400px</span>;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">650px</span>;
  <span class="hljs-attribute">margin</span>: auto;
  <span class="hljs-attribute">overflow</span>: hidden;
}
<span class="hljs-selector-class">.carousel-images</span> <span class="hljs-selector-tag">img</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">99%</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">99%</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">#ff00008e</span> solid <span class="hljs-number">2px</span>;
}
<span class="hljs-selector-class">.slide_direction</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">justify-content</span>: space-between;
}
<span class="hljs-selector-class">.left</span>,
<span class="hljs-selector-class">.right</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fb666675</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span> <span class="hljs-number">8px</span> <span class="hljs-number">8px</span> <span class="hljs-number">13px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">50%</span>;
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">bottom</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">margin</span>: auto <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">25px</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">25px</span>;
}
<span class="hljs-selector-class">.left</span> {
  <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span>;
}
<span class="hljs-selector-class">.right</span> {
  <span class="hljs-attribute">right</span>: <span class="hljs-number">0</span>;
}
<span class="hljs-selector-class">.carousel-indicator</span> {
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">20px</span>;
}
<span class="hljs-selector-class">.dot</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#333</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">15px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">15px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">50%</span>;
}
<span class="hljs-selector-class">.active</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fa2020</span>;
}
</code></pre>
<p>And here is the result with our CSS:  </p>
<p><img src="https://i.imgur.com/0CfxWn4.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You'll probably agree that this looks a whole lot better and is already fully functional.</p>
<p>Now let's move on to adding our animation using Framer Motion to give it a nice sliding look.</p>
<h2 id="heading-how-to-add-animation-to-the-carousel-component">How to Add Animation to the Carousel Component</h2>
<p>To start animating with Framer Motion there are a few concepts you must be familiar with because we will be using them often in this section. These concepts include:</p>
<ul>
<li>Variants: Think of a variant as a named group of properties. Its job is to define how an element should appear or animate. You can create different variants to represent different visual states or animations for an element, like <code>open</code>, <code>closed</code>, <code>hover</code>, and so on.</li>
<li>Initial: This is simply the state your object will posses before the animation kicks in.</li>
<li>Animate: This is simply the state your object will animate to, it's as simple as that.</li>
</ul>
<p>Back to the project, we'll add our animations to our carousel component. We have already imported the two properties which we will be needing – the <code>motion</code> and <code>AnimatePresence</code> properties. </p>
<p>I will be breaking this section into three parts because we will be adding animation to three parts of our code, including the image, the slider directions, and the indicator dot.</p>
<h3 id="heading-image-animation">Image Animation</h3>
<p>To animate the exit and entrance of an image, we need to wrap our <code>img</code> element with an <code>AnimationPresence</code>  component. This enables us to add animation whenever an image leaves or enters. Then we attach a <code>motion.</code> to our tag just like this.</p>
<pre><code class="lang-jsx"> &lt;AnimatePresence&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">motion.img</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{currentIndex}</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{images[currentIndex]}</span> /&gt;</span></span>
&lt;/AnimatePresence&gt;;
</code></pre>
<p>Next, we go outside our template and declare our variants.</p>
<pre><code class="lang-jsx">  <span class="hljs-keyword">const</span> slideVariants = {
    <span class="hljs-attr">hiddenRight</span>: {
      <span class="hljs-attr">x</span>: <span class="hljs-string">"100%"</span>,
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">0</span>,
    },
    <span class="hljs-attr">hiddenLeft</span>: {
      <span class="hljs-attr">x</span>: <span class="hljs-string">"-100%"</span>,
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">0</span>,
    },
    <span class="hljs-attr">visible</span>: {
      <span class="hljs-attr">x</span>: <span class="hljs-string">"0"</span>,
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">transition</span>: {
        <span class="hljs-attr">duration</span>: <span class="hljs-number">1</span>,
      },
    },
    <span class="hljs-attr">exit</span>: {
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">0</span>,
      <span class="hljs-attr">scale</span>: <span class="hljs-number">0.8</span>,
      <span class="hljs-attr">transition</span>: {
        <span class="hljs-attr">duration</span>: <span class="hljs-number">0.5</span>,
      },
    },
  };
</code></pre>
<p>As you can see, the <code>sliderVariants</code> has four properties:</p>
<ul>
<li>hiddenRight: this sets the opacity of the image to 0 and places it at the right side of the container.</li>
<li>hiddenLeft: this does the same as the hiddenRight but this time it's set on the left side.</li>
<li>visible: this is the property that will be called for the slide animation to happen from whichever position the image is to the center of the container.</li>
<li>exit: this animation controls the removal of the image from the screen as another image slides in.</li>
</ul>
<p>Now our variants are set. How do we tell where the image should slide in from? We need to set a direction state and update the state based on which of the <code>slide_direction</code>s was clicked.</p>
<pre><code class="lang-jsx">  <span class="hljs-keyword">const</span> [direction, setDirection] = useState(<span class="hljs-string">'left'</span>);
</code></pre>
<p>So we set the direction to start at the left. This is only logical since the first image to be displayed will be the first image. Then we go over to our helper function and set the direction depending on which direction was clicked.</p>
<pre><code class="lang-jsx">  <span class="hljs-keyword">const</span> handleNext = <span class="hljs-function">() =&gt;</span> {
    setDirection(<span class="hljs-string">"right"</span>);
    setCurrentIndex(<span class="hljs-function">(<span class="hljs-params">prevIndex</span>) =&gt;</span>
      prevIndex + <span class="hljs-number">1</span> === images.length ? <span class="hljs-number">0</span> : prevIndex + <span class="hljs-number">1</span>
    );
  };

  <span class="hljs-keyword">const</span> handlePrevious = <span class="hljs-function">() =&gt;</span> {
    setDirection(<span class="hljs-string">"left"</span>);

    setCurrentIndex(<span class="hljs-function">(<span class="hljs-params">prevIndex</span>) =&gt;</span>
      prevIndex - <span class="hljs-number">1</span> &lt; <span class="hljs-number">0</span> ? images.length - <span class="hljs-number">1</span> : prevIndex - <span class="hljs-number">1</span>
    );
  };

  <span class="hljs-keyword">const</span> handleDotClick = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
    setDirection(index &gt; currentIndex ? <span class="hljs-string">"right"</span> : <span class="hljs-string">"left"</span>);
    setCurrentIndex(index);
  };
</code></pre>
<p>You may have noticed that we didn't just set the state for the <code>handleNext</code> and <code>handlePrevious</code>. We also did for the <code>handleDotClick</code>. So whenever a previous or next dot is clicked the direction will be set accordingly.</p>
<p>Just a reminder – the purpose of direction is to set the initial state of the image so the slider can work as it ought to.</p>
<p>Now that our direction is set, let's use our variants in our <code>img</code> element.</p>
<pre><code class="lang-jsx">&lt;AnimatePresence&gt;
          <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">motion.img</span>
            <span class="hljs-attr">key</span>=<span class="hljs-string">{currentIndex}</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">{images[currentIndex]}</span>
            <span class="hljs-attr">variants</span>=<span class="hljs-string">{slideVariants}</span>
            <span class="hljs-attr">initial</span>=<span class="hljs-string">{direction</span> === <span class="hljs-string">"right"</span> ? "<span class="hljs-attr">hiddenRight</span>" <span class="hljs-attr">:</span> "<span class="hljs-attr">hiddenLeft</span>"}
            <span class="hljs-attr">animate</span>=<span class="hljs-string">"visible"</span>
            <span class="hljs-attr">exit</span>=<span class="hljs-string">"exit"</span>
          /&gt;</span></span>
        &lt;/AnimatePresence&gt;
</code></pre>
<p>So we add the <code>variants</code> prop and set it equal to the <code>slideVariants</code> we created. Then we added the initial prop and set it equal to a ternary operator. This sets the initial state of the image to either be <code>hiddenRight</code> or <code>hiddenLeft</code> depending on which of the <code>slider_direction</code> or <code>dot</code> was clicked. </p>
<p>Next, we add the animate property, which animates the image from the initial position to the position we set in the <code>visible</code> property. </p>
<p>Lastly, we add our exit property and set it to <code>exit</code>. This animates the image out of the screen when a new image enters.</p>
<p>There are lots of props you can use when working with Framer Motion. You can check the <a target="_blank" href="https://www.framer.com/motion/component/#props">documentation</a> to learn more about them.</p>
<p>And with that in place, our image carousel should be working perfectly.</p>
<p><img src="https://i.imgur.com/4VNWzsq.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-sliders-and-dots-animation">Sliders and Dots Animation</h3>
<p>We could stop here, but I just want to add a few animations to my slide directions and dots.</p>
<pre><code class="lang-jsx">  <span class="hljs-keyword">const</span> slidersVariants = {
    <span class="hljs-attr">hover</span>: {
      <span class="hljs-attr">scale</span>: <span class="hljs-number">1.2</span>,
      <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#ff00008e"</span>,
    },
  }; 
<span class="hljs-keyword">const</span> dotsVariants = {
    <span class="hljs-attr">initial</span>: {
      <span class="hljs-attr">y</span>: <span class="hljs-number">0</span>,
    },
    <span class="hljs-attr">animate</span>: {
      <span class="hljs-attr">y</span>: <span class="hljs-number">-10</span>,
      <span class="hljs-attr">scale</span>: <span class="hljs-number">1.3</span>,
      <span class="hljs-attr">transition</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"spring"</span>, <span class="hljs-attr">stiffness</span>: <span class="hljs-number">1000</span>, <span class="hljs-attr">damping</span>: <span class="hljs-string">"10"</span> },
    },
    <span class="hljs-attr">hover</span>: {
      <span class="hljs-attr">scale</span>: <span class="hljs-number">1.1</span>,
      <span class="hljs-attr">transition</span>: { <span class="hljs-attr">duration</span>: <span class="hljs-number">0.2</span> },
    },
  };
</code></pre>
<p>As usual, first we create our variants. For the <code>slidersVariants</code> we just add a hover property. For the <code>dotsVariants</code> we have three properties: initial, animate, and hover.</p>
<p>Just like we did with the <code>img</code> element, we will add <code>motion.</code> as a prefix to the element name in order to use Framer Motion.</p>
<pre><code class="lang-jsx">&lt;div className=<span class="hljs-string">"slide_direction"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">motion.div</span>
    <span class="hljs-attr">variants</span>=<span class="hljs-string">{slidersVariants}</span>
    <span class="hljs-attr">whileHover</span>=<span class="hljs-string">"hover"</span>
    <span class="hljs-attr">className</span>=<span class="hljs-string">"left"</span>
    <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handlePrevious}</span>
  &gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
      <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
      <span class="hljs-attr">height</span>=<span class="hljs-string">"20"</span>
      <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 96 960 960"</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">"20"</span>
    &gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M400 976 0 576l400-400 56 57-343 343 343 343-56 57Z"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">motion.div</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">motion.div</span>
    <span class="hljs-attr">variants</span>=<span class="hljs-string">{slidersVariants}</span>
    <span class="hljs-attr">whileHover</span>=<span class="hljs-string">"hover"</span>
    <span class="hljs-attr">className</span>=<span class="hljs-string">"right"</span>
    <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleNext}</span>
  &gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
      <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
      <span class="hljs-attr">height</span>=<span class="hljs-string">"20"</span>
      <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 96 960 960"</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">"20"</span>
    &gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"m304 974-56-57 343-343-343-343 56-57 400 400-400 400Z"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">motion.div</span>&gt;</span></span>
&lt;/div&gt;;
</code></pre>
<p>As you can see, we added our variants and set it equal to <code>slidersVariants</code>. Then we used a new property <code>whileHover</code> and set it equal to the over property we specified in our <code>slidersVariants</code> object.</p>
<pre><code class="lang-jsx">&lt;motion.div
  key={index}
  className={<span class="hljs-string">`dot <span class="hljs-subst">${currentIndex === index ? <span class="hljs-string">"active"</span> : <span class="hljs-string">""</span>}</span>`</span>}
  onClick={<span class="hljs-function">() =&gt;</span> handleDotClick(index)}
  initial=<span class="hljs-string">"initial"</span>
  animate={currentIndex === index ? <span class="hljs-string">"animate"</span> : <span class="hljs-string">""</span>}
  whileHover=<span class="hljs-string">"hover"</span>
  variants={dotsVariants}
&gt;&lt;/motion.div&gt;;
</code></pre>
<p>Here we didn't just add a whileHover prop. We also added an <code>initial</code> prop and an <code>animate</code> prop that animates the current image dot so it stands out. </p>
<p>In our <code>slidersVariants</code> object, we specified a transition type of spring which gives it the bouncy nature when the animation transition takes place.</p>
<p>Add all this together and our sleek Image Carousel is ready. Here is the final result:</p>
<p><img src="https://i.imgur.com/Bgghl7M.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Just for reference, this is the full code of the carousel component:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { motion, AnimatePresence } <span class="hljs-keyword">from</span> <span class="hljs-string">"framer-motion"</span>;

<span class="hljs-keyword">const</span> Carousel = <span class="hljs-function">(<span class="hljs-params">{ images }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [currentIndex, setCurrentIndex] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [direction, setDirection] = useState(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> slideVariants = {
    <span class="hljs-attr">hiddenRight</span>: {
      <span class="hljs-attr">x</span>: <span class="hljs-string">"100%"</span>,
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">0</span>,
    },
    <span class="hljs-attr">hiddenLeft</span>: {
      <span class="hljs-attr">x</span>: <span class="hljs-string">"-100%"</span>,
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">0</span>,
    },
    <span class="hljs-attr">visible</span>: {
      <span class="hljs-attr">x</span>: <span class="hljs-string">"0"</span>,
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">transition</span>: {
        <span class="hljs-attr">duration</span>: <span class="hljs-number">1</span>,
      },
    },
    <span class="hljs-attr">exit</span>: {
      <span class="hljs-attr">opacity</span>: <span class="hljs-number">0</span>,
      <span class="hljs-attr">scale</span>: <span class="hljs-number">0.8</span>,
      <span class="hljs-attr">transition</span>: {
        <span class="hljs-attr">duration</span>: <span class="hljs-number">0.5</span>,
      },
    },
  };
  <span class="hljs-keyword">const</span> slidersVariants = {
    <span class="hljs-attr">hover</span>: {
      <span class="hljs-attr">scale</span>: <span class="hljs-number">1.2</span>,
      <span class="hljs-attr">backgroundColor</span>: <span class="hljs-string">"#ff00008e"</span>,
    },
  };
  <span class="hljs-keyword">const</span> dotsVariants = {
    <span class="hljs-attr">initial</span>: {
      <span class="hljs-attr">y</span>: <span class="hljs-number">0</span>,
    },
    <span class="hljs-attr">animate</span>: {
      <span class="hljs-attr">y</span>: <span class="hljs-number">-10</span>,
      <span class="hljs-attr">scale</span>: <span class="hljs-number">1.2</span>,
      <span class="hljs-attr">transition</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"spring"</span>, <span class="hljs-attr">stiffness</span>: <span class="hljs-number">1000</span>, <span class="hljs-attr">damping</span>: <span class="hljs-string">"10"</span> },
    },
    <span class="hljs-attr">hover</span>: {
      <span class="hljs-attr">scale</span>: <span class="hljs-number">1.1</span>,
      <span class="hljs-attr">transition</span>: { <span class="hljs-attr">duration</span>: <span class="hljs-number">0.2</span> },
    },
  };

  <span class="hljs-keyword">const</span> handleNext = <span class="hljs-function">() =&gt;</span> {
    setDirection(<span class="hljs-string">"right"</span>);
    setCurrentIndex(<span class="hljs-function">(<span class="hljs-params">prevIndex</span>) =&gt;</span>
      prevIndex + <span class="hljs-number">1</span> === images.length ? <span class="hljs-number">0</span> : prevIndex + <span class="hljs-number">1</span>
    );
  };

  <span class="hljs-keyword">const</span> handlePrevious = <span class="hljs-function">() =&gt;</span> {
    setDirection(<span class="hljs-string">"left"</span>);

    setCurrentIndex(<span class="hljs-function">(<span class="hljs-params">prevIndex</span>) =&gt;</span>
      prevIndex - <span class="hljs-number">1</span> &lt; <span class="hljs-number">0</span> ? images.length - <span class="hljs-number">1</span> : prevIndex - <span class="hljs-number">1</span>
    );
  };

  <span class="hljs-keyword">const</span> handleDotClick = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
    setDirection(index &gt; currentIndex ? <span class="hljs-string">"right"</span> : <span class="hljs-string">"left"</span>);
    setCurrentIndex(index);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"carousel"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"carousel-images"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">AnimatePresence</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">motion.img</span>
            <span class="hljs-attr">key</span>=<span class="hljs-string">{currentIndex}</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">{images[currentIndex]}</span>
            <span class="hljs-attr">initial</span>=<span class="hljs-string">{direction</span> === <span class="hljs-string">"right"</span> ? "<span class="hljs-attr">hiddenRight</span>" <span class="hljs-attr">:</span> "<span class="hljs-attr">hiddenLeft</span>"}
            <span class="hljs-attr">animate</span>=<span class="hljs-string">"visible"</span>
            <span class="hljs-attr">exit</span>=<span class="hljs-string">"exit"</span>
            <span class="hljs-attr">variants</span>=<span class="hljs-string">{slideVariants}</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">AnimatePresence</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"slide_direction"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">motion.div</span>
            <span class="hljs-attr">variants</span>=<span class="hljs-string">{slidersVariants}</span>
            <span class="hljs-attr">whileHover</span>=<span class="hljs-string">"hover"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"left"</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handlePrevious}</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
              <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
              <span class="hljs-attr">height</span>=<span class="hljs-string">"20"</span>
              <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 96 960 960"</span>
              <span class="hljs-attr">width</span>=<span class="hljs-string">"20"</span>
            &gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M400 976 0 576l400-400 56 57-343 343 343 343-56 57Z"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">motion.div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">motion.div</span>
            <span class="hljs-attr">variants</span>=<span class="hljs-string">{slidersVariants}</span>
            <span class="hljs-attr">whileHover</span>=<span class="hljs-string">"hover"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"right"</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleNext}</span>
          &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
              <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
              <span class="hljs-attr">height</span>=<span class="hljs-string">"20"</span>
              <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 96 960 960"</span>
              <span class="hljs-attr">width</span>=<span class="hljs-string">"20"</span>
            &gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"m304 974-56-57 343-343-343-343 56-57 400 400-400 400Z"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">motion.div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"carousel-indicator"</span>&gt;</span>
        {images.map((_, index) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">motion.div</span>
            <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">dot</span> ${<span class="hljs-attr">currentIndex</span> === <span class="hljs-string">index</span> ? "<span class="hljs-attr">active</span>" <span class="hljs-attr">:</span> ""}`}
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> handleDotClick(index)}
            initial="initial"
            animate={currentIndex === index ? "animate" : ""}
            whileHover="hover"
            variants={dotsVariants}
          &gt;<span class="hljs-tag">&lt;/<span class="hljs-name">motion.div</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Carousel;
</code></pre>
<p>Check out the Git Repository on <a target="_blank" href="https://github.com/Cejay101/ImageCarousel">GitHub</a>.</p>
<p>Here is the site on <a target="_blank" href="https://image-carousel-cj.netlify.app/">Netlify</a>.</p>
<p><em>Just a note that there are accessibility issues with this code, and so it shouldn't be used in a production environment.</em></p>
<h2 id="heading-resources">Resources</h2>
<p>I understand that there might be some terms or syntax that might be unclear, especially if you are new to React or new to using Framer Motion. Here are some resources I would recommend if you want to learn more:</p>
<ul>
<li><a target="_blank" href="https://legacy.reactjs.org/docs">React Documentation</a></li>
<li><a target="_blank" href="https://www.framer.com/motion/">Framer Motion Documentation</a></li>
<li><a target="_blank" href="https://www.youtube.com/playlist?list=PL4cUxeGkcC9iHDnQfTHEVVceOEBsOf07i">Framer Motion Course</a></li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we explored the process of designing an engaging and responsive image carousel using the powerful combination of React and Framer Motion, an animation and gesture library. </p>
<p>By incorporating components like <code>motion</code> and <code>AnimationPresence</code>, we wear able to walk through the steps to build a visually appealing carousel. This carousel showcases our images and delivers smooth transitions between images with captivating animations for an enhanced user experience.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How CSS Spacing Works – A Guide for Web Developers ]]>
                </title>
                <description>
                    <![CDATA[ In this tutorial, we're going to talk about spacing in CSS spacing – sounds so basic, right? Well, it's not as basic as you might think.  Take, for instance, when you visit your favorite e-commerce site to scout for products. The first thing that wel... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/css-spacing-guide-for-web-devs/</link>
                <guid isPermaLink="false">66bc4c58b003837b7f4c9330</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Clinton Joy ]]>
                </dc:creator>
                <pubDate>Fri, 09 Jun 2023 16:26:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-08-at-10.32.24.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this tutorial, we're going to talk about spacing in CSS spacing – sounds so basic, right? Well, it's not as basic as you might think. </p>
<p>Take, for instance, when you visit your favorite e-commerce site to scout for products. The first thing that welcomes you to the platform is an intuitive design with a clear presentation of products. This gives you a great browsing experience.</p>
<p>Now take a second to imagine how your favorite e-commerce website would look if all the space separating products, descriptions, reviews, and other related items were eliminated. Trust me, it would only be a matter of time before you'd find a new favorite e-commerce website.</p>
<p>If navigating through a website becomes a hassle, people will go elsewhere. Efficiently scanning through a website would be nearly impossible if there wasn't a clear visual distinction between different products, important text, and images.</p>
<p>In this article, I will teach you how to better create a highly accessible and visually appealing website. I'll cover all you need to know about spacing in CSS and how you can implement it effectively. Without further ado, let’s dive right in.</p>
<h2 id="heading-what-is-css-spacing">What is CSS Spacing?</h2>
<p>CSS spacing is an essential feature that helps you arrange and organize every other element of your web application in a neat and sensible manner. This helps improve web accessibility and creates a better user experience.</p>
<p>To go more in-depth, CSS spacing refers to how you insert space within and between CSS elements on a web page. It plays a very important role in web design and is used to enhance readability, usability, and the overall aesthetic of a webpage. </p>
<p>Spacing consists of various parts, which include <code>padding</code>, <code>margins</code>, and <code>borders</code>. Each of these contributes to the spatial relationship between elements.</p>
<p><img src="https://hackmd.io/_uploads/H1IdUOVS3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image showing the difference between elements spaced properly and elements squished together.</em></p>
<p>In the image above, you can distinguish between the example with CSS spacing and the one without, given the definition I gave of what CSS spacing is. You can also likely see which of the two images is better structured, more aesthetically pleasing, and more readable. </p>
<p>This shows you how important CSS spacing is. With that being said, let’s talk more in-depth about the importance of CSS spacing.</p>
<h2 id="heading-importance-of-css-spacing">Importance of CSS Spacing</h2>
<p>We have already seen some benefits of CSS spacing and why it is important, but here are the main reasons why you should always consider CSS spacing whenever you are building a webpage:</p>
<ol>
<li>Enhancing Readability: With thoughtful CSS Spacing, there is a clear distinction between various elements and segments of your web page, which improves readability. You can make sure everything is spaced properly by adjusting margins, padding, and many other CSS properties.</li>
<li>Increasing User Engagement and Navigation: With proper CSS spacing, you can avoid cluttered web pages which discourage users from engaging with your webpage contents. It also directs the flow of information on a webpage, which gives users a sense of where their attention should be focused.</li>
<li>Facilitating Responsive Design: With good CSS spacing, you can account for minor changes when it comes to responsive designs. For instance, with a decent amount of padding, you can ensure your web page's elements don't overlap on different devices.</li>
<li>Emphasizing Important Elements: You can use CSS spacing to highlight key information on your web page. By having a little bit more than the regular amount of space, the user’s attention will simply be drawn to certain elements.</li>
<li>Adding Professional Aesthetics: In minimalist design, spacing is very important. It gives a more elegant and luxurious feeling to your webpage, giving attention to only the vital information on the page.</li>
</ol>
<h2 id="heading-types-of-css-spacing">Types of CSS Spacing</h2>
<p>When talking about the types of spacing in CSS, there are a lot of properties associated with it. They include, <code>margin</code>, <code>padding</code>, and <code>borders</code>. But overall, there are two main types of spacing:</p>
<ol>
<li>Internal Spacing</li>
<li>External spacing</li>
</ol>
<p>To completely understand each of these types of spacing, let’s consider this example:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-class">.box</span> {
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">2rem</span>;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid black;
      }

      <span class="hljs-selector-id">#box1</span> {
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">2rem</span>;
      }

      <span class="hljs-selector-id">#box2</span> {
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#9b59b6</span>;
        <span class="hljs-attribute">color</span>: white;
        <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">2rem</span>;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box1"</span>&gt;</span>Box 1<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"box2"</span>&gt;</span>Box 2<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Given the code above, we have two boxes that illustrate both internal and external spacing. As you can see, we added <code>padding: 2 rem</code>. This added <code>2 rem</code> of internal space to our boxes.</p>
<p>Also, to separate one box from the other, we added a <code>margin-bottom</code> to the first box. This results in that external space you see below our first box in the image below. We also added <code>2rem</code> worth of external space to the left side of our second box.</p>
<p>If you've noticed, the internal spacing increases the size of our element, while the external spacing either adjusts or changes the position of either the parent element or surrounding elements.</p>
<p><img src="https://hackmd.io/_uploads/HJG9254Hh.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration of internal space vs external space based on the above code.</em></p>
<h3 id="heading-difference-between-internal-and-external-css-spacing">Difference between Internal and External CSS Spacing</h3>
<p>Internal space is usually created with padding, and external space is usually created with margins. Here are a few differences between the two types of spacing:</p>
<table><thead><tr><th></th><th><span>Padding (Internal Spacing)</span></th><th><span>Margin (External Spacing)</span></th></tr></thead><tbody><tr><td><span>Purpose</span></td><td><span>Creates space within the borders of an element, between the content and the border.</span></td><td><span>Creates space outside the borders of an element, between the element and other surrounding elements.</span></td></tr><tr><td><span>Effect on Size</span></td><td><span>Increases the total width/height of an element.</span></td><td><span>Does not increase the size of the element itself. It affects the space around the element.</span></td></tr><tr><td><span>Interaction with Border</span></td><td><span>Lies within the border of an element. If a border is defined, padding extends from the inside edge of the border.</span></td><td><span>Lies outside the border of an element. If a border is defined, the margin starts from the outside edge of the border.</span></td></tr><tr><td><span>Background</span></td><td><span>Extends the background color/image of the element.</span></td><td><span>Does not extend the background color/image of the element; it’s always transparent.</span></td></tr><tr><td><span>Usage</span></td><td><span>To increase the readability and visual separation between the content and the border.</span></td><td><span>To control the position and layout of an element relative to others, and to create space between elements.</span></td></tr></tbody></table>

<h2 id="heading-the-css-box-model">The CSS Box Model</h2>
<p>To fully understand CSS spacing, you must understand the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model">CSS box model</a>. This is a fundamental concept in CSS that shows the layout of elements. Every element follows the box model, so it is essential that you know how it works.</p>
<p>There are four components that make up the box model, and they include:</p>
<ol>
<li>Content</li>
<li>Padding</li>
<li>Border</li>
<li>Margin</li>
</ol>
<p>The content is the core of the box model, and it is where the text, image, and so on of the element reside.</p>
<p>Padding is the internal space that surrounds the content. It's used to provide spacing between the content and the border. It also increases the dimension of the background of an element.</p>
<p>The border is the bridge between internal space and external space. It goes all around the padding, and its shape, size, and color are controlled by the border property. The main aim of the border property is to create a boundary around the element. It also adds aesthetics to the element.</p>
<p>The margin is the external space, and its main purpose is to create space between different elements. This is used to enhance readability and visual organization.</p>
<p>To estimate the total size of an element, you'll need to consider all these components. Full knowledge of the box model will give you the power to control the CSS spacing and alignment of elements on the page.</p>
<p>Let’s consider this code to illustrate how the box model works:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-tag">body</span> {
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">justify-content</span>: center;
        <span class="hljs-attribute">align-items</span>: center;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f2f2f2</span>;
        <span class="hljs-attribute">font-family</span>: Arial, sans-serif;
        <span class="hljs-attribute">color</span>: <span class="hljs-number">#333</span>;
      }

      <span class="hljs-selector-class">.box</span> {
        <span class="hljs-comment">/* Content */</span>
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">align-items</span>: center;
        <span class="hljs-attribute">justify-content</span>: center;

        <span class="hljs-comment">/* Padding */</span>
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;

        <span class="hljs-comment">/* Border */</span>
        <span class="hljs-attribute">border</span>: <span class="hljs-number">10px</span> solid <span class="hljs-number">#3498db</span>;

        <span class="hljs-comment">/* Margin */</span>
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">30px</span>;

        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#b65975</span>;
        <span class="hljs-attribute">color</span>: white;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span>&gt;</span>Box Model<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Seems like pretty self-explanatory code, right? As you can see, we tried as much as possible to use all the components of the box model. </p>
<p>We started off by defining the dimensions of the content component, giving it a width and height of <code>100px</code>. Using the Flexbox layout model, we aligned the content to the center.</p>
<p>Next, we added a padding of <code>20px</code>. This increased the inner spacing, which increased the dimension of the box, making the background larger.</p>
<p>You can see the blueish border, which goes around the padding. It separates the inner spacing from the outer spacing. It was set using the border property and has a size of <code>10px</code>.</p>
<p>Lastly, we have the margin set to <code>30px</code>. This is responsible for creating outer spacing that separates elements from each other.</p>
<p>Here is what our result looks like:</p>
<p><img src="https://hackmd.io/_uploads/Hy_WLeHHn.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration of CSS box model</em></p>
<p>As you can see in the image above, we have all the elements of a box model present. This may not always be the case, as most of these components can be manually assigned values or can also be totally removed.</p>
<h2 id="heading-css-spacing-in-other-css-layout-models">CSS Spacing in Other CSS Layout Models</h2>
<p>There are several other layout models you can use when designing your websites. And keep in mind that CSS spacing works a bit differently in these other models. </p>
<p>Firstly, let’s look at the other major layout models that are widely in use and how CSS spacing works when you're using them. They include:</p>
<ol>
<li>CSS Flexbox</li>
<li>CSS Grid</li>
</ol>
<h3 id="heading-css-flexbox">CSS Flexbox</h3>
<p>Explaining in detail how CSS Flexbox works is beyond the scope of this article – but if you want to learn more about it, you can read the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox">documentation</a>. You can also <a target="_blank" href="https://www.freecodecamp.org/news/learn-css-flexbox/">check out this crash course</a> on freeCodeCamp's YouTube channel.</p>
<p>Our main focus here will be on the <code>gap</code> property. You can use this property for both CSS Flexbox and CSS Grid. In CSS Flexbox, you use it to create space between each flex item, which lets you control the space between items.</p>
<p>Let’s take for instance this code:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-class">.container</span> {
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">gap</span>: <span class="hljs-number">20px</span>;
      }

      <span class="hljs-selector-class">.item</span> {
        <span class="hljs-attribute">background-color</span>: lightblue;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>Item 1<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>Item 2<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>Item 3<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In the code above, we have three flex items. We set a <code>gap</code> property of <code>20px</code>, which places a <code>20px</code> space in between each child.</p>
<p><img src="https://hackmd.io/_uploads/B1gOoxIrn.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration showing the gap between flex items</em></p>
<p>You can also use various other CSS properties in the CSS Flexbox model for CSS spacing. They include:</p>
<ol>
<li>Justify-content: This controls the spacing along the main-axis. The kind of spacing is determined by the value set on this property, such as <code>flex-start</code>, <code>flex-end</code>, <code>center</code>, <code>space-between</code>, <code>space-around</code>, and <code>space-evenly</code>.</li>
<li>Align content: This is kind of similar to the justify-content property, but it controls the spacing along the cross-axis instead. Here are some of the values we can use on the Align-content property: <code>flex-start</code>, <code>flex-end</code>, <code>center</code>, <code>space-between</code>, <code>space-around</code>, <code>space-evenly</code>, and <code>stretch</code>.</li>
<li>Flex-basis: This is used to determine the initial size of flex items, which allows you to create flex items of equal size.</li>
</ol>
<p>Here is an image that shows some of these properties and how their values function:</p>
<p><img src="https://hackmd.io/_uploads/HyT7-sLSh.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration showing justify-content, align-content, and flex-basis properties</em></p>
<h3 id="heading-css-grid">CSS Grid</h3>
<p>Spacing in the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout">Grid model</a> isn’t so different from the Flexbox model. Let’s explore some of the properties that control spacing in CSS grid.</p>
<ol>
<li>grid-gap: This property performs the same job as the gap property, which is to space the rows and columns of CSS grids. You can also use the gap property to perform this function, as it’s the newer way.</li>
<li>grid-row-gap and grid-column-gap: some times you don’t want a uniform gap between rows and columns. Instead, you can use these properties to define the size of the gap between grid rows and columns, respectively.</li>
</ol>
<p>To illustrate, consider this code:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.container</span> {
      <span class="hljs-attribute">display</span>: grid;
      <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-number">1</span>fr <span class="hljs-number">1</span>fr <span class="hljs-number">1</span>fr;
      <span class="hljs-attribute">grid-column-gap</span>: <span class="hljs-number">50px</span>;
      <span class="hljs-attribute">grid-row-gap</span>: <span class="hljs-number">20px</span>;
      <span class="hljs-attribute">background</span>: <span class="hljs-number">#6c1697</span>;
    }
</code></pre>
<p>Here we set the display property to grid. The grid is then set to have three equal-sized columns using <code>grid-template-columns: 1fr 1fr 1fr</code>.</p>
<p>We then used the <code>grid-column-gap</code> property to create a gap of 50px between the columns, while <code>grid-row-gap</code> creates a gap of 20px between the rows.</p>
<p>Below is the result we get from having six grid items:</p>
<p><img src="https://hackmd.io/_uploads/B1woWgDr2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration showing grid-row-gap and grid-column-gap properties</em></p>
<h2 id="heading-spacing-in-text">Spacing in Text</h2>
<p>When we discussed the box model, we classified text as part of the content component of the box model. Well, there are several properties you can use on text to add spacing in order to meet your specific needs. Some of these properties include:</p>
<ol>
<li>letter-spacing: This property is used to create space between each character in the text.</li>
<li>word-spacing: This property is used to create space between each word in the text.</li>
<li>line-height: This property is used to create vertical spacing between lines of text.</li>
<li>text-align: This property is used to control how text is positioned horizontally. The default value is <code>left</code> and the most-used value is <code>center</code>.</li>
<li>text-indent: This property is used to indent the first line of the block element, which simply creates a space at the start of the text.</li>
<li>white-space: This property defines how the text within your elements is displayed. The default value for this property is <code>normal</code> but when set to <code>no-wrap</code> the text just flows horizontally without wrapping up to begin a new line.</li>
</ol>
<p>Here is some code that shows how each of these properties operates:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-class">.text</span> {
        <span class="hljs-attribute">background-color</span>: lightblue;
      }
      <span class="hljs-selector-tag">p</span> {
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">18px</span>;
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">20px</span>;
      }

      <span class="hljs-selector-class">.letter-spacing-example</span> {
        <span class="hljs-attribute">letter-spacing</span>: <span class="hljs-number">5px</span>;
      }

      <span class="hljs-selector-class">.word-spacing-example</span> {
        <span class="hljs-attribute">word-spacing</span>: <span class="hljs-number">20px</span>;
      }

      <span class="hljs-selector-class">.line-height-example</span> {
        <span class="hljs-attribute">line-height</span>: <span class="hljs-number">10rem</span>;
      }
      <span class="hljs-selector-class">.text-align-example</span> {
        <span class="hljs-attribute">text-align</span>: center;
      }

      <span class="hljs-selector-class">.text-indent-example</span> {
        <span class="hljs-attribute">text-indent</span>: <span class="hljs-number">50px</span>;
      }

      <span class="hljs-selector-class">.white-space-example</span> {
        <span class="hljs-attribute">white-space</span>: nowrap;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"letter-spacing-example"</span>&gt;</span>
        This is an example of letter-spacing property. It adds space between
        each character.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"word-spacing-example"</span>&gt;</span>
        This is an example of word-spacing property. It adds space between each
        word.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"line-height-example"</span>&gt;</span>
        This is an example of line-height property. It creates vertical spacing
        between lines of text.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-align-example"</span>&gt;</span>
        This is an example of text-align property. It controls the horizontal
        alignment of text within an element.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-indent-example"</span>&gt;</span>
        This is an example of text-indent property. It indents the first line of
        the block element.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"white-space-example"</span>&gt;</span>
        This is an example of white-space property. It prevents the wrapping of text
        and causes it to overflow horizontally. Lorem ipsum dolor sit amet,
        consectetur adipisicing elit. Accusamus dolorem provident pariatur
        recusandae nulla numquam?
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In the code above, we created several divs with a class of text, each having a p tag with a class name that describes the property that the text will have. </p>
<p>The first p tag is used to illustrate the <code>letter-spacing</code> property, and we set a <code>5px</code> space between each letter. </p>
<p>Next, we have the <code>word-spacing</code> property, and with this property, we gave a <code>20px</code> gap between each word.</p>
<p>The <code>line-height</code> property here gives the p tag a <code>10rem</code> vertical gap.</p>
<p>And for the p tag with the <code>text-align</code> property value set to center, we have equal space on the left and right sides of the text.</p>
<p>Another property we illustrated was the <code>text-indent</code> property. We set its value to <code>50px</code>, and this well indents the text, giving it a <code>50px</code> space at the start of the first line of the text.</p>
<p>Last but not least, we set the last p tag to have a <code>white-space</code> property value of <code>no-wrap</code>," which makes the text flow in a horizontal line without ever wrapping to the next line.</p>
<p>Here is a screenshot of what this code produces when it appears in the browser:</p>
<p><img src="https://hackmd.io/_uploads/Sy9h5mvrh.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example of text spacing properties in action</em></p>
<h2 id="heading-use-case-how-to-create-a-review-form">Use Case: How to Create a Review Form</h2>
<p>We have discussed a lot of details about CSS spacing. Now to wrap it up, let’s build a simple review form so you see CSS spacing in action.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      * {
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
        <span class="hljs-attribute">box-sizing</span>: border-box;
        <span class="hljs-attribute">font-family</span>: Arial, sans-serif;
      }
      <span class="hljs-selector-tag">body</span> {
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f6f6f6</span>;
      }
      <span class="hljs-selector-class">.feedback-container</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">400px</span>;
        <span class="hljs-attribute">margin</span>: auto;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>;
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ffffff</span>;
        <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">0px</span> <span class="hljs-number">15px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.1</span>);
        <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">50px</span>;
      }
      <span class="hljs-selector-class">.feedback-title</span> {
        <span class="hljs-attribute">text-align</span>: center;
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">color</span>: <span class="hljs-number">#333333</span>;
        <span class="hljs-attribute">letter-spacing</span>: <span class="hljs-number">2.3px</span>;
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">24px</span>;
      }
      <span class="hljs-selector-class">.feedback-description</span> {
        <span class="hljs-attribute">text-align</span>: center;
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">color</span>: <span class="hljs-number">#666666</span>;
        <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.6</span>;
      }
      <span class="hljs-selector-class">.feedback-input</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span>;
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#dddddd</span>;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
      }
      <span class="hljs-selector-class">.feedback-button</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span>;
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#4caf50</span>;
        <span class="hljs-attribute">color</span>: white;
        <span class="hljs-attribute">border</span>: none;
        <span class="hljs-attribute">cursor</span>: pointer;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">18px</span>;
        <span class="hljs-attribute">font-weight</span>: bold;
      }
      <span class="hljs-selector-class">.feedback-button</span><span class="hljs-selector-pseudo">:hover</span> {
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#45a049</span>;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"feedback-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"feedback-title"</span>&gt;</span>REVIEW FORM<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"feedback-description"</span>&gt;</span>
        We value your feedback! Your comments help us to understand your needs
        better and improve our services. Please take a few moments to share your
        thoughts.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
          <span class="hljs-attr">class</span>=<span class="hljs-string">"feedback-input"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Your Name"</span>
          <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span>
          <span class="hljs-attr">required</span>
        /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>
          <span class="hljs-attr">class</span>=<span class="hljs-string">"feedback-input"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Your Email"</span>
          <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span>
          <span class="hljs-attr">required</span>
        /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span>
          <span class="hljs-attr">class</span>=<span class="hljs-string">"feedback-input"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Your Feedback"</span>
          <span class="hljs-attr">name</span>=<span class="hljs-string">"feedback"</span>
          <span class="hljs-attr">required</span>
        &gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"feedback-button"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The code above shows our review form. We have <code>h2</code> which holds the form title. Next, we have the description in a <code>p</code> tag. Last but not least, we have our form, which holds the input fields and a submit button. </p>
<p>In the code above, we have added our CSS spacing. You can see the properties such as the <code>margin</code>, <code>padding</code>, <code>line-height</code>, <code>letter-spacing</code>, and some other properties we talked about earlier and the values we gave to them.</p>
<p>If we run our code and view it in the browser, this is the result we get:</p>
<p><img src="https://hackmd.io/_uploads/S1X_k4vSh.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image showing the form with and without proper spacing</em></p>
<p>With our CSS Spacing, we have been able to align the <code>h2</code> and <code>p</code> to the center, and we have been able to make our input fields look presentable with the padding in the input fields. By applying margin, we have been able to separate elements from each other, like the <code>h2</code>, <code>p</code>, <code>form</code>, and the submit <code>button</code>.</p>
<p>From the image above, you can clearly tell which is the better version. CSS spacing makes the review form look better and is also easier to understand.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, CSS spacing is a fundamental aspect of web development, and mastering these concepts is essential for every front-end developer. </p>
<p>With proper use of <code>padding</code>, <code>margin</code>, and all the other spacing properties we talked about, you can create designs that are both intuitive and comfortable, guiding your user’s eyes smoothly from one element to another.</p>
<p>While CSS spacing may appear to be a simple concept at first glance, it requires a bit of practice to comfortably choose between spacing properties and use them correctly.</p>
<p>Always remember that good spacing breathes life into your pages, making them more readable, engaging, classy, and intuitive. Happy coding!</p>
<h2 id="heading-contact-information">Contact Information</h2>
<p>Feel free to connect with me on the following platforms:</p>
<ul>
<li>Twitter: <a target="_blank" href="https://www.twitter.com/clintonjoy10">@Clintonjoy10</a></li>
<li>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/clinton-joy-538804244/">Clinton joy</a></li>
<li>Email: clintonjoyfimie@gmail.com</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
