<?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[ Eric Hu - 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[ Eric Hu - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:29:53 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/huericnan/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Send HTTP Requests Using JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Nowadays, the interaction between web applications relies on HTTP. For instance, let's say you have an online shop application and you want to create a new product. You have to fill in all the necessary information and probably click on a button that... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-send-http-requests-using-javascript/</link>
                <guid isPermaLink="false">66bb8a946b3bd8d6bf25ae44</guid>
                
                    <category>
                        <![CDATA[ http ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eric Hu ]]>
                </dc:creator>
                <pubDate>Wed, 10 Jul 2024 17:06:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/js-http.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Nowadays, the interaction between web applications relies on <a target="_blank" href="https://www.freecodecamp.org/news/what-is-http/">HTTP</a>. For instance, let's say you have an online shop application and you want to create a new product. You have to fill in all the necessary information and probably click on a button that says "Create".</p>
<p>This action will send an HTTP request to the backend, along with all the necessary data, and the backend application will use that data to make changes to the database. After the action is complete, whether successful or not, an HTTP response will be sent back to the frontend, which will act accordingly based on the status of that response.</p>
<p>When these requests and responses are transferred back and forth, they need to follow a certain format so that both ends can understand each other. HTTP was created for this purpose. It is a standard network protocol that enables web applications to understand and communicate with each other.</p>
<h2 id="heading-what-are-the-http-request-methods">What Are the HTTP Request Methods?</h2>
<p>There are several methods you can use to send an HTTP request, and each of them serves a different purpose, as shown below:</p>
<h3 id="heading-the-get-method">The <code>GET</code> Method</h3>
<p>The <code>GET</code> method is used to request data and resources from the server. When you send a <code>GET</code> request, the query parameters are embedded in the URL in name/value pairs like this:</p>
<pre><code class="lang-text">http://example.com/index.html?name1=value1&amp;name2=value2
</code></pre>
<p>Note that the question mark (<code>?</code>) denotes the beginning of a list of parameters. Each parameter forms a key/value pair (<code>name=value</code>), and the ampersand (<code>&amp;</code>) is used to divide two different parameters.</p>
<h3 id="heading-the-post-method">The <code>POST</code> Method</h3>
<p>The <code>POST</code> method is used to send data to the server, either adding a new resource or updating an existing resource. The parameters are stored in the body of the HTTP request.</p>
<pre><code class="lang-text">POST /index.html HTTP/1.1
Host: example.com
name1=value1&amp;name2=value2
</code></pre>
<h3 id="heading-the-delete-method">The <code>DELETE</code> Method</h3>
<p>This method removes a resource from the server.</p>
<h3 id="heading-the-head-method">The <code>HEAD</code> Method</h3>
<p>The <code>HEAD</code> method works just like <code>GET</code> except that the HTTP response sent from the server will only contain the head but not the body. This means that if the server is "OK" with the request, it will give you a <code>200 OK</code> response but not the resource you requested. You can only retrieve the resource with the <code>GET</code> method.</p>
<p>This is very useful when you are testing whether the server works. Sometimes, the resource may take a long time to be transmitted, and for testing purposes, you only need a <code>200 OK</code> response to know that everything works properly.</p>
<h3 id="heading-the-put-method">The <code>PUT</code> Method</h3>
<p>The <code>PUT</code> method is used to update existing resources, and it is similar to the <code>POST</code> method with one small difference.</p>
<p>When you <code>PUT</code> a resource that already exists, the old resource will be overwritten. And making multiple identical <code>PUT</code> requests will have the same effect as making it once.</p>
<p>When you <code>POST</code> identical resources, that resource will be duplicated every time the request is made.</p>
<h2 id="heading-what-is-the-fetch-api">What is the Fetch API?</h2>
<p>For a long time, the JavaScript community lacked a standard way to send HTTP requests. Some people used <code>XMLHttpRequest</code>, aka AJAX, while others prefered external libraries such as Axios or jQuery.</p>
<p>The fetch API was introduced in 2015 as the modern, simplified, and standard way of making HTTP requests using JavaScript. It is natively supported, so there is no need to install any third-party libraries.</p>
<h2 id="heading-how-to-send-a-get-request-using-javascript">How to Send a GET Request Using JavaScript</h2>
<p>The fetch API is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promise-based</a>, which means that it offers a clean and concise syntax for writing asynchronous operations. For example, this is how you can send a <code>GET</code> request using the fetch API.</p>
<pre><code class="lang-javascript">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>)
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
    <span class="hljs-comment">// If the response is not 2xx, throw an error</span>
    <span class="hljs-keyword">if</span> (!response.ok) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Network response was not ok"</span>);
    }

    <span class="hljs-comment">// If the response is 200 OK, return the response in JSON format.</span>
    <span class="hljs-keyword">return</span> response.json();
  })
  .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(data)) <span class="hljs-comment">// You can continue to do something to the response.</span>
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Fetch error:"</span>, error)); <span class="hljs-comment">// In case of an error, it will be captured and logged.</span>
</code></pre>
<p>You can also include custom options with the request, such as custom headers, authorization tokens, and so on.</p>
<pre><code class="lang-javascript">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>, {
  <span class="hljs-attr">headers</span>: {
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
    <span class="hljs-string">"Authorization"</span>: <span class="hljs-string">"your-token-here"</span>,
  },
  <span class="hljs-attr">credentials</span>: <span class="hljs-string">"same-origin"</span>,
})
  .then(. . .);
</code></pre>
<h2 id="heading-how-to-send-a-post-request-using-javascript">How to Send a POST Request Using JavaScript</h2>
<p>When sending a <code>POST</code> request, things get a bit more complex because you need to send data to the server with the request body. This could get complicated depending on the kind of data you're sending and your specific use case.</p>
<p>For example, the following code sends JSON data to the backend:</p>
<pre><code class="lang-javascript">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
  <span class="hljs-attr">headers</span>: {
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
  },
  <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
    <span class="hljs-attr">name</span>: <span class="hljs-string">"John Doe"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"johndoe@example.com"</span>,
  }),
});
</code></pre>
<p>There are a few things you must pay attention here. First of all, you must explicitly specify the request method. If you leave this out, the default <code>GET</code> method will be used.</p>
<p>Also, the request body only accepts string data, so you must use the <code>stringify()</code> method to convert JSON into a string before assigning it to the request body.</p>
<p>This is also why it is important to include the <code>Content-Type</code> header, which lets whoever is on the receiving end know how to parse the request body.</p>
<p>However, things are usually more complex in practice. For example, when working with web forms, instead of JSON, you are likely using the <code>x-www-form-urlencoded</code> form encoding, in which case the request can be sent like this.</p>
<p>The following example assumes you understand what <a target="_blank" href="https://www.freecodecamp.org/news/dom-events-and-javascript-event-listeners/">event handlers</a> are.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"DOMContentLoaded"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"form"</span>);
  <span class="hljs-keyword">const</span> usernameInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"username"</span>);
  <span class="hljs-keyword">const</span> emailInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"email"</span>);

  <span class="hljs-keyword">const</span> formData = <span class="hljs-keyword">new</span> URLSearchParams();

  usernameInput.addEventListener(<span class="hljs-string">"input"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    formData.set(<span class="hljs-string">"username"</span>, usernameInput.value);
  });

  emailInput.addEventListener(<span class="hljs-string">"input"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    formData.set(<span class="hljs-string">"email"</span>, emailInput.value);
  });

  form.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
    event.preventDefault(); <span class="hljs-comment">// Prevent the default form submission action</span>

    <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      <span class="hljs-attr">body</span>: formData.toString(),
      <span class="hljs-attr">headers</span>: {
        <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/x-www-form-urlencoded"</span>,
      },
    });
  });
});
</code></pre>
<p>If you need to upload files to the backend, you'll need the <code>multipart/form-data</code> form encoding instead.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"DOMContentLoaded"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myForm"</span>);
  <span class="hljs-keyword">const</span> usernameInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"username"</span>);
  <span class="hljs-keyword">const</span> emailInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"email"</span>);
  <span class="hljs-keyword">const</span> pictureInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"picture"</span>);

  <span class="hljs-keyword">const</span> formData = <span class="hljs-keyword">new</span> FormData();

  usernameInput.addEventListener(<span class="hljs-string">"input"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    formData.set(<span class="hljs-string">"username"</span>, usernameInput.value);
  });

  emailInput.addEventListener(<span class="hljs-string">"input"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    formData.set(<span class="hljs-string">"email"</span>, emailInput.value);
  });

  pictureInput.addEventListener(<span class="hljs-string">"change"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    formData.set(<span class="hljs-string">"picture"</span>, pictureInput.files[<span class="hljs-number">0</span>]);
  });

  form.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
    event.preventDefault(); <span class="hljs-comment">// Prevent the default form submission</span>

    <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      <span class="hljs-attr">body</span>: formData,
    });
  });
});
</code></pre>
<p>Note that when using the <code>FormData()</code> to construct the request body, the <code>Content-Type</code> will be locked into <code>multipart/form-data</code>. In this case, it is not necessary to set a custom <code>Content-Type</code> header.</p>
<h2 id="heading-how-to-send-a-put-request-using-javascript">How to Send a PUT Request Using JavaScript</h2>
<p>The <code>PUT</code> request works similarly to <code>POST</code>, but you must remember to set <code>method</code> to <code>PUT</code>.</p>
<pre><code class="lang-javascript">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">"PUT"</span>,
  <span class="hljs-attr">headers</span>: {
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
  },
  <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
    <span class="hljs-attr">id</span>: <span class="hljs-string">"123"</span>
    <span class="hljs-attr">name</span>: <span class="hljs-string">"John Doe"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"johndoe@example.com"</span>,
  }),
});
</code></pre>
<p>Realistically, you'll have to provide an <code>id</code>, or any other key that enables you to locate the record to be updated in the backend.</p>
<h2 id="heading-how-to-send-a-delete-request-using-javascript">How to Send a DELETE Request Using JavaScript</h2>
<p>The <code>DELETE</code> request works similarly to <code>PUT</code>, but remember to set <code>method</code> to <code>DELETE</code>.</p>
<pre><code class="lang-javascript">fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users/123"</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">"DELETE"</span>,
});
</code></pre>
<p>And similarly, remember to provide an <code>id</code> so that the backend application knows which record to delete.</p>
<h2 id="heading-how-to-send-a-request-using-xmlhttprequest-ajax">How to Send a Request Using XMLHttpRequest (AJAX)</h2>
<p>Besides <code>fetch()</code>, it is also possible to make an HTTP request using <code>XMLHttpRequest</code>. The following example demonstrates how to make a <code>GET</code> request to the endpoint <code>https://jsonplaceholder.typicode.com</code></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> xhr = <span class="hljs-keyword">new</span> XMLHttpRequest();
xhr.open(<span class="hljs-string">"GET"</span>, <span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>, <span class="hljs-literal">true</span>);
xhr.onload = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> (xhr.status &gt;= <span class="hljs-number">200</span> &amp;&amp; xhr.status &lt; <span class="hljs-number">300</span>) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.parse(xhr.responseText));
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error:"</span>, xhr.statusText);
  }
};
xhr.onerror = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Request failed"</span>);
};
xhr.send();
</code></pre>
<p>The syntax is a bit more complex, as <code>XMLHttpRequest</code> relies on callback functions to work with asynchronous operations, which means it is easy to lead to what is known as the callback hell, where you have layers upon layers of callback functions, making your code base difficult to read and maintain.</p>
<p>However, <code>XMLHttpRequest</code> does have some advantages. Due to the fact that <code>XMLHttpRequest</code> is much older compared to <code>fetch()</code>, it is more widely supported. You should consider using <code>XMLHttpRequest</code> when your web app needs to be compatible with older browsers.</p>
<h2 id="heading-how-to-send-a-request-using-external-libraries">How to Send a Request Using External Libraries</h2>
<p>Aside from the built-in methods, you can also send HTTP requests using third-party libraries. For instance, this is how you can send a <code>GET</code> request using jQuery:</p>
<pre><code class="lang-javascript">$.get(<span class="hljs-string">"https://api.example.com/data"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">data</span>) </span>{
  <span class="hljs-built_in">console</span>.log(data);
}).fail(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">error</span>) </span>{
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error:"</span>, error);
});
</code></pre>
<p><a target="_blank" href="https://jquery.com/">jQuery</a> is one of the most popular JavaScript libraries. It aims to fix the part of JavaScript that is difficult to use, and it has been pretty successful at that.</p>
<p>In recent years, jQuery has lost some popularity as vanilla JavaScript has improved over the years and the problems that used to bother people have been fixed. It is no longer the go-to choice for creating JavaScript applications, especially for newer developers.</p>
<p>Alternatively, you could go with Axios, which is a promise-based HTTP client just like <code>fetch()</code>, and it has been people's favorite for a very long time before <code>fetch()</code> came.</p>
<pre><code class="lang-javascript">axios
  .get(<span class="hljs-string">"https://api.example.com/data"</span>)
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(response.data))
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Axios error:"</span>, error));
</code></pre>
<p><a target="_blank" href="https://axios-http.com/docs/intro">Axios</a> and <code>fetch()</code> have very similar syntax as they are both promise-based. The main difference between them is that <code>fetch()</code> is built-in, while Axios requires you to install an external library. However, Axios is much more feature-rich, as it comes with request/response interceptors, automatic JSON handling, and built-in timeouts.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>We introduced four different ways you could send HTTP requests using JavaScript in this tutorial. It is up to you to decide which is best for your project.</p>
<p>The fetch API is the modern and standard way of making HTTP requests using JavaScript. It has a relatively simple syntax, which makes your project easier to maintain.</p>
<p><code>XMLHttpRequest</code> is the legacy method of sending HTTP requests. It is generally not recommended for use in new projects, but if your project needs to be compatible with legacy browsers, <code>XMLHttpRequest</code> might still come in handy.</p>
<p>jQuery is an external package that can do a lot of things, including sending HTTP requests. Although the significance of jQuery has been fading in recent years, it is still used in many older projects, and you might encounter it in your work as a JavaScript developer.</p>
<p>Axios is a third-party library used to send HTTP requests. It has a very similar syntax to the fetch API but comes with a lot more advanced features. It is up to you to decide if you need these features. If not, it is generally recommended to use <code>fetch()</code> instead.</p>
<p>To learn more about JavaScript and web development, visit <a target="_blank" href="https://www.thedevspace.io">thedevspace.io</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Manipulate Strings in JavaScript – With Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ String manipulation is a common task for programmers, whether it is extracting information from the string, converting letter cases, joining strings, or trimming extra white spaces. This tutorial covers various methods and techniques for manipulating... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-manipulate-strings-in-javascript/</link>
                <guid isPermaLink="false">66bb8a905d242388375d3869</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eric Hu ]]>
                </dc:creator>
                <pubDate>Fri, 24 May 2024 21:46:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/js-string.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>String manipulation is a common task for programmers, whether it is extracting information from the string, converting letter cases, joining strings, or trimming extra white spaces.</p>
<p>This tutorial covers various methods and techniques for manipulating strings using JavaScript, offering you a comprehensive guide on how to work with strings in your JavaScript applications.</p>
<h2 id="heading-how-to-extract-a-character-from-a-string-in-javascript"><strong>How to Extract a Character from a String in JavaScript</strong></h2>
<p>Let's start by talking about how to extract a single character from a string. JavaScript offers three different methods for this purpose: <code>charAt()</code>, <code>at()</code>, and <code>charCodeAt()</code>.</p>
<h3 id="heading-how-to-use-charatindex">How to Use <code>charAt(index)</code></h3>
<p>The <code>charAt()</code> method accepts an index, and returns the character at that index.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"Hello World!"</span>;

<span class="hljs-built_in">console</span>.log(str.charAt(<span class="hljs-number">0</span>));
<span class="hljs-built_in">console</span>.log(str.charAt(<span class="hljs-number">8</span>));
<span class="hljs-built_in">console</span>.log(str.charAt(<span class="hljs-number">16</span>));
</code></pre>
<pre><code class="lang-text">H
r
</code></pre>
<p>If the index is out of range, <code>charAt()</code> will return an empty string (<code>""</code>).</p>
<h3 id="heading-how-to-use-atindex">How to Use <code>at(index)</code></h3>
<p>The <code>at()</code> method was added to JavaScript with ES2022, and it is very similar to <code>charAt()</code>. You pass it an index, and the method returns the character at that index.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"Hello World!"</span>;

<span class="hljs-built_in">console</span>.log(str.at(<span class="hljs-number">0</span>));
<span class="hljs-built_in">console</span>.log(str.at(<span class="hljs-number">8</span>));
<span class="hljs-built_in">console</span>.log(str.at(<span class="hljs-number">16</span>));
</code></pre>
<pre><code class="lang-text">H
r
undefined
</code></pre>
<p>When the index is out of range, <code>at()</code> will return <code>undefined</code> instead of an empty string.</p>
<p>Another difference is that <code>at()</code> allows for negative indexing, meaning index <code>-1</code> returns the last character of the string, <code>-2</code> returns the second last character, and so on.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"Hello World!"</span>;

<span class="hljs-built_in">console</span>.log(str.at(<span class="hljs-number">-1</span>));
<span class="hljs-built_in">console</span>.log(str.at(<span class="hljs-number">-2</span>));
</code></pre>
<pre><code class="lang-text">!
d
</code></pre>
<p>Before <code>at()</code>, the only way to do this was through the <code>length</code> property.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"Hello World!"</span>;

<span class="hljs-built_in">console</span>.log(str.charAt(str.length - <span class="hljs-number">1</span>)); <span class="hljs-comment">// The last character</span>
<span class="hljs-built_in">console</span>.log(str.charAt(str.length - <span class="hljs-number">2</span>)); <span class="hljs-comment">// The second last character</span>
</code></pre>
<pre><code class="lang-text">!
d
</code></pre>
<h3 id="heading-how-to-use-charcodeatindex">How to Use <code>charCodeAt(index)</code></h3>
<p>The <code>charCodeAt()</code> method returns the <a target="_blank" href="https://en.wikipedia.org/wiki/UTF-16">UTF-16</a> code of the character at the specified index.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"Hello World!"</span>;

<span class="hljs-built_in">console</span>.log(str.charCodeAt(<span class="hljs-number">0</span>));
<span class="hljs-built_in">console</span>.log(str.charCodeAt(<span class="hljs-number">4</span>));
</code></pre>
<pre><code class="lang-text">72
111
</code></pre>
<h2 id="heading-how-to-extract-a-substring-in-javascript"><strong>How to Extract a Substring in JavaScript</strong></h2>
<p>Besides extracting a single character, JavaScript also allows you to extract a substring using methods <code>substring()</code> and <code>slice()</code>.</p>
<h3 id="heading-how-to-use-substringstart-end">How to Use <code>substring(start, end)</code></h3>
<p><code>substring()</code> extracts a substring based on the provided <code>start</code> (inclusive) and <code>end</code> (exclusive) indexes, and returns the substring as a new string.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.substring(<span class="hljs-number">0</span>, <span class="hljs-number">4</span>));
</code></pre>
<pre><code class="lang-text">Java
</code></pre>
<p>The <code>end</code> index can be left out, in which case the substring will be extracted from <code>start</code> to the end of the string.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.substring(<span class="hljs-number">4</span>));
</code></pre>
<pre><code class="lang-text">Script
</code></pre>
<h3 id="heading-how-to-use-slicestart-end">How to Use <code>slice(start, end)</code></h3>
<p><code>slice()</code> is very similar to <code>substring()</code>. It also extracts a substring based on the provided <code>start</code> and <code>end</code> indexes, and returns the substring as a new string.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.slice(<span class="hljs-number">0</span>, <span class="hljs-number">4</span>));
</code></pre>
<pre><code class="lang-text">Java
</code></pre>
<p>The <code>end</code> index can also be omitted.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.slice(<span class="hljs-number">4</span>));
</code></pre>
<pre><code class="lang-text">Script
</code></pre>
<p>The difference is that <code>slice()</code> accepts negative indexes. For example, the following example extracts the substring from index <code>-10</code> to <code>-6</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.slice(<span class="hljs-number">-10</span>, <span class="hljs-number">-6</span>));
</code></pre>
<pre><code class="lang-text">Java
</code></pre>
<h2 id="heading-how-to-convert-a-string-to-upper-or-lower-case-in-javascript"><strong>How to Convert a String to Upper or Lower Case in JavaScript</strong></h2>
<p>The methods <code>toUpperCase()</code> and <code>toLowerCase()</code> convert the string to upper or lower case.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.toUpperCase());
<span class="hljs-built_in">console</span>.log(str.toLowerCase());
</code></pre>
<pre><code class="lang-text">JAVASCRIPT
javascript
</code></pre>
<h2 id="heading-how-to-join-two-strings-together-in-javascript"><strong>How to Join Two Strings Together in JavaScript</strong></h2>
<p>The easiest way to join two strings together is using the <code>+</code> operator:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str1 = <span class="hljs-string">"Hello"</span>;
<span class="hljs-keyword">const</span> str2 = <span class="hljs-string">"World!"</span>;

<span class="hljs-keyword">const</span> str3 = str1 + <span class="hljs-string">" "</span> + str2;

<span class="hljs-built_in">console</span>.log(str3);
</code></pre>
<pre><code class="lang-text">Hello World!
</code></pre>
<p>Alternatively, you can use the <code>concat()</code> method:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str1 = <span class="hljs-string">"Hello"</span>;
<span class="hljs-keyword">const</span> str2 = <span class="hljs-string">"World!"</span>;

<span class="hljs-keyword">const</span> str3 = str1.concat(<span class="hljs-string">" "</span>, str2);

<span class="hljs-built_in">console</span>.log(str3);
</code></pre>
<pre><code class="lang-text">Hello World!
</code></pre>
<p>Or you can use <a target="_blank" href="https://www.freecodecamp.org/news/template-literals-in-javascript/">template literals</a>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str1 = <span class="hljs-string">"Hello"</span>;
<span class="hljs-keyword">const</span> str2 = <span class="hljs-string">"World!"</span>;

<span class="hljs-keyword">const</span> str3 = <span class="hljs-string">`<span class="hljs-subst">${str1}</span> <span class="hljs-subst">${str2}</span>`</span>;

<span class="hljs-built_in">console</span>.log(str3);
</code></pre>
<pre><code class="lang-text">Hello World!
</code></pre>
<h2 id="heading-how-to-trim-extra-white-spaces-from-a-string-in-javascript"><strong>How to Trim Extra White Spaces from a String in JavaScript</strong></h2>
<p>When working with strings that came from external sources, such as parsed from a webpage or received from user input, a common problem you might encounter is the leading and trailing white spaces.</p>
<p>JavaScript offers three different methods that allow you to easily remove the extra white spaces and keep only the useful information.</p>
<p>The <code>trimStart()</code> method removes the leading white spaces, including spaces, tabs, and line breaks. The <code>trimEnd()</code> method removes trailing white spaces, and <code>trim()</code> removes white spaces from both ends.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"  \n\tHello World!\t\n  "</span>;

<span class="hljs-built_in">console</span>.log(str.trimStart());
<span class="hljs-built_in">console</span>.log(str.trimEnd());
<span class="hljs-built_in">console</span>.log(str.trim());
</code></pre>
<pre><code class="lang-text">Hello World!


 Hello World!
Hello World!
</code></pre>
<h2 id="heading-how-to-add-padding-to-a-string-in-javascript"><strong>How to Add Padding to a String in JavaScript</strong></h2>
<p>The methods <code>padStart()</code> and <code>padEnd()</code> can be used to pad characters or substrings at the beginning or the end of the original string.</p>
<p>Both methods take two arguments, <code>length</code> and a substring. The substring will be repeated multiple times, until the resulting string reaches the target length.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"123"</span>;

<span class="hljs-built_in">console</span>.log(str.padStart(<span class="hljs-number">5</span>, <span class="hljs-string">"0"</span>));
<span class="hljs-built_in">console</span>.log(str.padEnd(<span class="hljs-number">5</span>, <span class="hljs-string">"0"</span>));
</code></pre>
<pre><code class="lang-text">00123
12300
</code></pre>
<p>If the substring is causing the resulting string to exceed the target length, then only a part of that substring will be used.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"123"</span>;

<span class="hljs-built_in">console</span>.log(str.padStart(<span class="hljs-number">8</span>, <span class="hljs-string">"ok"</span>));
</code></pre>
<pre><code class="lang-text">okoko123
</code></pre>
<p>Notice that the substring <code>"ok"</code> is repeated twice, but for the third time, it causes the resulting string to exceed the length limit, so only <code>"o"</code> is used for the final padding.</p>
<h2 id="heading-how-to-repeat-a-string-in-javascript"><strong>How to Repeat a String in JavaScript</strong></h2>
<p><code>repeat()</code> returns a new string, with the specified number of copies of the original string.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"123"</span>;

<span class="hljs-built_in">console</span>.log(str.repeat(<span class="hljs-number">3</span>));
</code></pre>
<pre><code class="lang-text">123123123
</code></pre>
<h2 id="heading-how-to-split-string-into-an-array-in-javascript"><strong>How to Split String into an Array in JavaScript</strong></h2>
<p>The <code>split()</code> method splits the string based on the given character, and returns the result in an array. This method is most useful when you need to extract information from a URL. </p>
<p>For example, this is how you can extract the slug of a blog post:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> url = <span class="hljs-string">"http://www.example.com/blog/example-article"</span>;

<span class="hljs-keyword">let</span> arr = url.split(<span class="hljs-string">"/"</span>);
<span class="hljs-built_in">console</span>.log(arr);

<span class="hljs-keyword">let</span> slug = arr[<span class="hljs-number">4</span>];
<span class="hljs-built_in">console</span>.log(slug);
</code></pre>
<pre><code class="lang-text">[ 'http:', '', 'www.example.com', 'blog', 'example-article' ]
example-article
</code></pre>
<h2 id="heading-how-to-search-in-a-string-in-javascript"><strong>How to Search in a String in JavaScript</strong></h2>
<p>You can also search for a character or substring using JavaScript.</p>
<h3 id="heading-how-to-use-indexof-and-lastindexof">How to Use <code>indexOf()</code> and <code>lastIndexOf()</code></h3>
<p>The <code>indexOf()</code> method returns the index of the <strong>first</strong> occurrence of the given character.</p>
<p>The <code>lastIndexOf()</code> methods returns the index of the <strong>last</strong> occurrence of the given character.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"Hello World"</span>;

<span class="hljs-built_in">console</span>.log(str.indexOf(<span class="hljs-string">"l"</span>));
<span class="hljs-built_in">console</span>.log(str.lastIndexOf(<span class="hljs-string">"l"</span>));
</code></pre>
<pre><code class="lang-text">2
9
</code></pre>
<p>Both methods will return -1 if a match is not found.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"Hello World"</span>;

<span class="hljs-built_in">console</span>.log(str.indexOf(<span class="hljs-string">"x"</span>));
<span class="hljs-built_in">console</span>.log(str.lastIndexOf(<span class="hljs-string">"x"</span>));
</code></pre>
<pre><code class="lang-text">-1
-1
</code></pre>
<h3 id="heading-how-to-use-includes">How to Use <code>includes()</code></h3>
<p>The <code>includes()</code> method tests if the string contains the given character or substring. It returns <code>true</code> if the substring is found, otherwise <code>false</code> will be returned.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.includes(<span class="hljs-string">"S"</span>));
<span class="hljs-built_in">console</span>.log(str.includes(<span class="hljs-string">"Script"</span>));
<span class="hljs-built_in">console</span>.log(str.includes(<span class="hljs-string">"script"</span>));
</code></pre>
<pre><code class="lang-text">true
true
false
</code></pre>
<h3 id="heading-how-to-use-startswith-and-endswith">How to Use <code>startsWith()</code> and <code>endsWith()</code></h3>
<p>As the names suggest, these two methods test if the given substring is found at the beginning or the end of the string.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript"</span>;

<span class="hljs-built_in">console</span>.log(str.startsWith(<span class="hljs-string">"Java"</span>));
<span class="hljs-built_in">console</span>.log(str.endsWith(<span class="hljs-string">"Java"</span>));

<span class="hljs-built_in">console</span>.log(str.startsWith(<span class="hljs-string">"Script"</span>));
<span class="hljs-built_in">console</span>.log(str.endsWith(<span class="hljs-string">"Script"</span>));
</code></pre>
<pre><code class="lang-text">true
false
false
true
</code></pre>
<h2 id="heading-how-to-search-in-a-string-using-regex-in-javascript"><strong>How to Search in a String using Regex in JavaScript</strong></h2>
<p>But what if you need something more powerful? For example, the <code>indexOf()</code> and <code>lastIndexOf()</code> methods only return the first and last occurrences of the substring, but what if you need to search for all of them?</p>
<p>Or what if, instead of a substring, you need to search for a pattern, such as a phone number or a price tag?</p>
<p>This can be achieved by combining the string methods with <a target="_blank" href="https://www.thedevspace.io/course/javascript-regular-expressions">Regex</a>, which stands for regular expression. It is a programming tool that allows you to describe patterns in a string. Regex has a very cryptic syntax, but can be very useful sometimes.</p>
<h3 id="heading-how-to-use-search">How to Use <code>search()</code></h3>
<p>The <code>search()</code> method works similarly to <code>indexOf()</code> we just discussed. It also returns the <strong>first</strong> occurrence of the matched substring or pattern, except that <code>search()</code> allows you to pass a regular expression.</p>
<p>The following example, <code>/(?&lt;=\$)\d\d?\d?\d?/</code>, searches for a price tag in the string, which should start with a dollar sign (<code>$</code>), and be followed by 1 to 4 numeric digits.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"The laptop costs $1500. The tablet costs $1000."</span>;

<span class="hljs-built_in">console</span>.log(str.search(<span class="hljs-string">"1500"</span>));
<span class="hljs-built_in">console</span>.log(str.search(<span class="hljs-regexp">/(?&lt;=\$)\d\d?\d?\d?/</span>));
<span class="hljs-built_in">console</span>.log(str.search(<span class="hljs-regexp">/(?&lt;=\$)\d\d?\d?\d?/g</span>));
</code></pre>
<pre><code class="lang-text">18
18
18
</code></pre>
<p>Notice that the global flag (<code>g</code>) has no effect on <code>search()</code>, and it still returns the first occurrence of the match.</p>
<h3 id="heading-how-to-use-match-and-matchall">How to Use <code>match()</code> and <code>matchAll()</code></h3>
<p>Compared to <code>search()</code>, the <code>match()</code> method returns much more information that you can work with, such as the actual substring that matches the pattern, the index where the match is found, and more.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"The laptop costs $1500. The tablet costs $1000."</span>;

<span class="hljs-built_in">console</span>.log(str.match(<span class="hljs-regexp">/(?&lt;=\$)\d\d?\d?\d?/</span>));
<span class="hljs-built_in">console</span>.log(str.match(<span class="hljs-regexp">/(?&lt;=\$)\d\d?\d?\d?/g</span>));
</code></pre>
<pre><code class="lang-text">[
 '1500',
 index: 18,
 input: 'The laptop costs $1500. The tablet costs $1000.',
 groups: undefined
]
[ '1500', '1000' ]
</code></pre>
<p>By including a global flag, you can make <code>match()</code> return all matched substrings, instead of just the first one.</p>
<p>There is also a <code>matchAll()</code> method that forces you to use the global flag. Without it, the method will return a <code>TypeError</code>.</p>
<p><code>matchAll()</code> will return an <a target="_blank" href="https://www.thedevspace.io/course/javascript-objects#iterating-over-an-object">iterable object</a>, which you can iterate over using a <code>for of</code> loop.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"This laptop costs $1500. The tablet costs $1000."</span>;

<span class="hljs-keyword">const</span> prices = str.matchAll(<span class="hljs-regexp">/(?&lt;=\$)\d\d\d\d/g</span>);

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> price <span class="hljs-keyword">of</span> prices) {
  <span class="hljs-built_in">console</span>.log(price);
}
</code></pre>
<pre><code class="lang-text">[
 '1500',
 index: 19,
 input: 'This laptop costs $1500. The tablet costs $1000.',
 groups: undefined
]
[
 '1000',
 index: 43,
 input: 'This laptop costs $1500. The tablet costs $1000.',
 groups: undefined
]
</code></pre>
<h2 id="heading-how-to-replace-a-string-pattern-in-javascript"><strong>How to Replace a String Pattern in JavaScript</strong></h2>
<p>Lastly, the <code>replace()</code> method allows you to match for a pattern, and then replace the matched substrings with a new string. For example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> str = <span class="hljs-string">"JavaScript javaScript Javascript"</span>;

<span class="hljs-built_in">console</span>.log(str.replace(<span class="hljs-regexp">/JAVASCRIPT/i</span>, <span class="hljs-string">"javascript"</span>));
<span class="hljs-built_in">console</span>.log(str.replace(<span class="hljs-regexp">/JAVASCRIPT/gi</span>, <span class="hljs-string">"javascript"</span>));
</code></pre>
<pre><code class="lang-text">javascript javaScript Javascript
javascript javascript javascript
</code></pre>
<p>By default, <code>replace()</code> only matches and replaces the first occurrence of the pattern, but with the global flag, you can replace all matched patterns.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this tutorial, we explored various methods you can use to work with strings in JavaScript. We also covered how to use regular expressions to match for string patterns.</p>
<p>As a brief summary, here are the methods we discussed in this tutorial:</p>
<ul>
<li><code>charAt(index)</code>: Extracts the character at the specified index from a string.</li>
<li><code>at(index)</code>: Retrieves the character at the specified index, supports negative indexing.</li>
<li><code>charCodeAt(index)</code>: Returns the UTF-16 code of the character at the specified index.</li>
<li><code>substring(start, end)</code>: Extracts a part of the string between the start (inclusive) and end indexes (exclusive).</li>
<li><code>slice(start, end)</code>: Similar to <code>substring()</code>, extracts a part of the string between start (inclusive) and end indexes (exclusive), but supports negative indexing.</li>
<li><code>toUpperCase()</code>: Converts all letters in the string to uppercase.</li>
<li><code>toLowerCase()</code>: Converts all letters in the string to lowercase.</li>
<li><code>concat()</code>: Joins two or more strings together.</li>
<li><code>trimStart()</code>: Removes whitespace from the beginning of a string. Including spaces, tabs, and newlines.</li>
<li><code>trimEnd()</code>: Removes whitespace from the end of a string.</li>
<li><code>trim()</code>: Removes whitespace from both ends of a string.</li>
<li><code>padStart(length, substring)</code>: Pads the start of a string with another string (multiple times, if needed) until the resulting string reaches the given length.</li>
<li><code>padEnd(length, substring)</code>: Pads the end of the string with another string (multiple times, if needed) until the resulting string reaches the given length.</li>
<li><code>repeat(count)</code>: Returns a new string which contains the specified number of copies of the original string.</li>
<li><code>split(separator)</code>: Splits the string into an array of substrings, using the specified separator to determine where to make the split.</li>
<li><code>indexOf(searchValue)</code>: Returns the index of the first occurrence of the specified substring. Returns -1 if not found.</li>
<li><code>lastIndexOf(searchValue)</code>: Returns the index of the last occurrence of the specified substring. Returns -1 if not found.</li>
<li><code>includes(searchValue)</code>: Determines whether the string contains the specified substring, returning <code>true</code> or <code>false</code>.</li>
<li><code>startsWith(searchValue)</code>: Checks if the string begins with the specified substring.</li>
<li><code>endsWith(searchValue)</code>: Checks if the string ends with the specified substring.</li>
<li><code>search(regexp)</code>: Search for a string pattern, which could be defined by a Regex. Returns the index of the first occurrence of the match or -1 if not found.</li>
<li><code>match(regexp)</code>: Search for a string pattern, which is defined by a Regex. If a global flag is included, it will return all occurrences of the pattern.</li>
<li><code>matchAll(regexp)</code>: Returns an iterable object containing all results matching a string against a global regular expression.</li>
<li><code>replace(regexp, newSubstr)</code>: Replaces occurrences of a pattern (specified by a regular expression) with a new substring.</li>
</ul>
<p>If you want to learn more about JavaScript and web development, check out my new course at <a target="_blank" href="https://www.thedevspace.io/">TheDevSpace.io</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create Custom CSS Animations with Examples ]]>
                </title>
                <description>
                    <![CDATA[ Animations are a crucial component of modern web design. They enable you to create dynamic and engaging web elements that attract more customers and drive more sales. In this article, we will discuss how to create cool custom animations using CSS. Pr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-custom-css-animations/</link>
                <guid isPermaLink="false">66bb8a8d7a6500a14ba5b774</guid>
                
                    <category>
                        <![CDATA[ animations ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eric Hu ]]>
                </dc:creator>
                <pubDate>Tue, 09 Jan 2024 21:59:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Animations are a crucial component of modern web design. They enable you to create dynamic and engaging web elements that attract more customers and drive more sales.</p>
<p>In this article, we will discuss how to create cool custom animations using CSS.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before going forward with this article, make sure you have basic knowledge of HTML and CSS. </p>
<p>I'll assume you are familiar with <a target="_blank" href="https://www.freecodecamp.org/news/use-css-selectors-to-style-webpage/">CSS selectors</a>, defining element <a target="_blank" href="https://www.w3schools.com/css/css_dimension.asp">size</a> and <a target="_blank" href="https://www.w3schools.com/css/css_colors.asp">color</a>, <a target="_blank" href="https://www.ericsdevblog.com/courses/html-css/4/">positioning elements</a>, <a target="_blank" href="https://www.freecodecamp.org/news/css-opacity/">adjusting opacity</a>, and <a target="_blank" href="https://www.freecodecamp.org/news/complete-guide-to-css-transform-functions-and-properties/">transforming elements</a>.</p>
<h2 id="heading-how-to-create-your-first-css-animation">How to Create Your First CSS Animation</h2>
<p>Let's start by preparing an HTML element.</p>
<pre><code class="lang-html"><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">"square"</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>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.square</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">background-color</span>: purple;

  <span class="hljs-comment">/* Center the element */</span>
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">50%</span>;
  <span class="hljs-attribute">left</span>: <span class="hljs-number">50%</span>;
  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>);
}
</code></pre>
<p>Lines 7 to 10 demonstrate a commonly used method to <a target="_blank" href="https://www.ericsdevblog.com/posts/how-to-center-a-div-in-css/">center an element using CSS</a>. Here's the result of the above code:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/square-center.png" alt="square center" width="600" height="400" loading="lazy">
<em>Centered square</em></p>
<p>Before we start crafting the animation, you must first think about what kind of effect you wish to achieve. </p>
<p>For example, for this tutorial, I want to create a bouncing effect for the square. This means I need to create an animation based on the <code>top</code> property so that the square can move up and down.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@keyframes</span> bounce {
  0% {
    <span class="hljs-attribute">top</span>: <span class="hljs-number">90%</span>;
  }
  100% {
    <span class="hljs-attribute">top</span>: <span class="hljs-number">10%</span>;
  }
}
</code></pre>
<p>To define an animation, you need to use the <code>@keyframes</code> rule, which allows you to define keyframes in the animation process. </p>
<p>The keyframes are set with percentage values, starting from <code>0%</code> and finishing with <code>100%</code>. For instance, in our example, the animation will start from <code>top: 90%;</code>, and end with <code>top: 10%;</code>, and after that, it will reset back to <code>50%</code>.</p>
<p>And, of course, you need to tie the <code>bounce</code> animation with the square (<code>animation-name</code>) and also tell the browser how long you want this animation to last (<code>animation-duration</code>). Here's how you do that:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.square</span> {
  . . .
  <span class="hljs-attribute">animation-name</span>: bounce;
  <span class="hljs-attribute">animation-duration</span>: <span class="hljs-number">2s</span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/bounce-1.gif" alt="square moves up" width="600" height="400" loading="lazy">
<em>A square moving up</em></p>
<h2 id="heading-how-to-add-multiple-keyframes">How to Add Multiple Keyframes</h2>
<p>But as you can see, the square starts from the bottom, moves to the top, and then resets back to the center. That is not exactly a bouncing effect. So, how can we make the square move back down?</p>
<p>To do that, you can set up a third keyframe like this:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@keyframes</span> bounce {
  0% {
    <span class="hljs-attribute">top</span>: <span class="hljs-number">90%</span>;
  }
  50% {
    <span class="hljs-attribute">top</span>: <span class="hljs-number">10%</span>;
  }
  100% {
    <span class="hljs-attribute">top</span>: <span class="hljs-number">90%</span>;
  }
}
</code></pre>
<p>This way, the square will start from the bottom (<code>top: 90%;</code>), move to the top (<code>top: 10%;</code>), and then move back down (<code>top: 90%;</code>).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/bounce-2.gif" alt="square moves up and then down" width="600" height="400" loading="lazy">
<em>The square moving up and then back down</em></p>
<h2 id="heading-how-to-create-a-repeat-animation">How to Create a Repeat Animation</h2>
<p>There is one problem that still needs to be solved. The animation only plays once. In practice, you might want your animation to repeat several times to create the effect that the square is actually bouncing. </p>
<p>Instead of creating more keyframes, which is not easy, you can define an <code>animation-iteration-count</code> property and specify the number of times you want the animation to repeat.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.square</span> {
  . . .
  <span class="hljs-attribute">animation-name</span>: bounce;
  <span class="hljs-attribute">animation-duration</span>: <span class="hljs-number">2s</span>;
  <span class="hljs-attribute">animation-iteration-count</span>: <span class="hljs-number">5</span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/bounce-3.gif" alt="repeat animation 5 times" width="600" height="400" loading="lazy">
<em>The square moving up and down for five times</em></p>
<p>And if you want the animation to last indefinitely, simply specify <code>infinite</code>.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.square</span> {
  . . .
  <span class="hljs-attribute">animation-name</span>: bounce;
  <span class="hljs-attribute">animation-duration</span>: <span class="hljs-number">2s</span>;
  <span class="hljs-attribute">animation-iteration-count</span>: infinite;
}
</code></pre>
<h2 id="heading-how-to-use-a-timing-function-for-smoother-animation">How to Use a Timing Function for Smoother Animation</h2>
<p>Finally, the bouncing effect started working, but there is still room for improvement. The movement of the square seems a bit unnatural. The bouncing effect would look better if you could smooth out the movement.</p>
<p>This can be achieved with a timing function. By default, the browser will assume a <code>linear</code> timing function, which means the animation will have constant speed from start to end. But you can change that using the <code>animation-timing-function</code> property, like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.square</span> {
  . . .
  <span class="hljs-attribute">animation-name</span>: bounce;
  <span class="hljs-attribute">animation-duration</span>: <span class="hljs-number">2s</span>;
  <span class="hljs-attribute">animation-iteration-count</span>: infinite;
  <span class="hljs-attribute">animation-timing-function</span>: ease-in-out;
}
</code></pre>
<p>By specifying <code>ease-in-out</code>, you are telling the browser to start the animation slowly and also end it gradually. As a result, the entire animation will look a lot smoother.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/bounce-4.gif" alt="ease in out" width="600" height="400" loading="lazy">
<em><code>ease-in-out</code> making the square move smoothly</em></p>
<h3 id="heading-the-cubic-bezier-curve">The Cubic Bezier curve</h3>
<p>The value <code>ease-in-out</code> actually represents a mathematical equation called <a target="_blank" href="https://www.w3schools.com/cssref/func_cubic-bezier.php">Cubic Bezier</a>. I will spare you the complex mathematical definitions, and you only need to know that the function defines a curve with four control points. </p>
<p><a target="_blank" href="https://cubic-bezier.com/">cubic-bezier.com</a> is an online tool that allows you to customize the curve by simply dragging the control points.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/cubic-bezier.png" alt="cubic bezier" width="600" height="400" loading="lazy">
<em>A Cubic Bezier curve</em></p>
<p>The points control the shape of the curve, and the slope of the curve then controls the speed of the animation. For example, the above graph indicates the animation will start slowly, accelerate, and then end smoothly.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.square</span> {
  . . .
  <span class="hljs-attribute">animation-name</span>: bounce;
  <span class="hljs-attribute">animation-duration</span>: <span class="hljs-number">2s</span>;
  <span class="hljs-attribute">animation-iteration-count</span>: infinite;
  <span class="hljs-attribute">animation-timing-function</span>: <span class="hljs-built_in">cubic-bezier</span>(<span class="hljs-number">0.17</span>, <span class="hljs-number">0.67</span>, <span class="hljs-number">0.8</span>, <span class="hljs-number">0.36</span>);
}
</code></pre>
<p>In most cases, you don't have to define a customized Cubic Bezier curve. There are several predefined curves that should be enough for most use cases.</p>
<p><code>ease</code> represents the curve <code>cubic-bezier(0.25, 0.1, 0.25, 1)</code>. The animation will start by slowly accelerating and then decelerate to stop.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/ease.png" alt="ease" width="600" height="400" loading="lazy">
<em>Cubic Bezier curve for ease</em></p>
<p><code>ease-in</code> represents the curve <code>cubic-bezier(0.42, 0, 1, 1)</code>. The animation will start smoothly and then stop rather abruptly.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/ease-in.png" alt="ease in" width="600" height="400" loading="lazy">
<em>Cubic Bezier curve for ease-in</em></p>
<p><code>ease-out</code> represents the curve <code>cubic-bezier(0, 0, 0.58, 1)</code>. The animation will start abruptly and then slow down to stop smoothly.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/ease-out.png" alt="ease out" width="600" height="400" loading="lazy">
<em>Cubic Bezier curve for ease-out</em></p>
<p><code>ease-in-out</code> represents the curve <code>cubic-bezier(0.42, 0, 0.58, 1)</code>. The animation will be smooth on both ends.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/ease-in-out.png" alt="ease in out" width="600" height="400" loading="lazy">
<em>Cubic Bezier curve for ease-in-out</em></p>
<h3 id="heading-the-steps-function">The <code>steps()</code> function</h3>
<p>Besides the smooth curve, you can also specify a stepping function. The function <code>steps()</code> takes two arguments. The first one specifies the number of steps, and the second one sets the point at which the change occurs within the step, either start or end.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.square</span> {
  . . .
  <span class="hljs-attribute">animation-name</span>: bounce;
  <span class="hljs-attribute">animation-duration</span>: <span class="hljs-number">2s</span>;
  <span class="hljs-attribute">animation-iteration-count</span>: infinite;
  <span class="hljs-attribute">animation-timing-function</span>: <span class="hljs-built_in">steps</span>(<span class="hljs-number">5</span>, start);
}
</code></pre>
<p>In this case, the animation will be divided into five steps, and for each step, the change will happen at the beginning of the step.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/bounce-5.gif" alt="5 steps" width="600" height="400" loading="lazy">
<em>A demo for the steps function</em></p>
<p>There are also two shortcuts available for the <code>steps()</code> function. <code>step-start</code> corresponds to <code>steps(1, start)</code>, and <code>step-end</code> corresponds to <code>steps(1, end)</code>.</p>
<h2 id="heading-how-to-combine-multiple-animations">How to Combine Multiple Animations</h2>
<p>So far, we've covered all the fundamentals you should understand to create CSS animations. And now, it is time to get more creative.</p>
<p>Our previous examples all focused on changing the <code>top</code> property in order to create the bounce effect. You can, in fact, combine multiple properties in one animation. For example, you can create a pulse effect by changing the element's shape and opacity together.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@keyframes</span> pulse {
  0% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>) <span class="hljs-built_in">scale</span>(<span class="hljs-number">1</span>);
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
  }
  50% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>) <span class="hljs-built_in">scale</span>(<span class="hljs-number">1.2</span>);
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.7</span>;
  }
  100% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>) <span class="hljs-built_in">scale</span>(<span class="hljs-number">1</span>);
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
  }
}
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.ball</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">background-color</span>: purple;
  <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">50%</span>;
  <span class="hljs-attribute">left</span>: <span class="hljs-number">50%</span>;
  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>);

  <span class="hljs-attribute">animation</span>: pulse <span class="hljs-number">2s</span> ease-in-out infinite;
}
</code></pre>
<p>Also note that the animation properties can be combined into a shortcut, <code>animation</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/pulse.gif" alt="pulse" width="600" height="400" loading="lazy">
<em>The pulse effect animation</em></p>
<h2 id="heading-other-animation-related-properties">Other Animation-Related Properties</h2>
<p>Besides the animation properties we have discussed so far, there are some miscellaneous properties we should talk about. They can also be useful sometimes. </p>
<p>First of all, there is the <code>animation-direction</code> property, which defines how the animation will be played. The property accepts four different values:</p>
<ul>
<li><code>normal</code>: The animation is played forward.</li>
<li><code>reverse</code>: The animation is played backward.</li>
<li><code>alternate</code>: The animation is played forward first, then backward. It only works when <code>animation-iteration-count</code> is more than 1.</li>
<li><code>alternate-reverse</code>: The animation is played backward first, then forward.</li>
</ul>
<p>By default, the animation will start playing immediately after the page is loaded. But you can change that with the <code>animation-delay</code> property, which specifies how long you wish to wait before the animation starts.</p>
<p>Lastly, the <code>animation-fill-mode</code> property determines how the element will be displayed before and after the animation is played. By default, the element will not retain any styles from the animation. After the animation stops, the element will reset to normal.</p>
<p>When <code>animation-fill-mode</code> is set to <code>forwards</code>, the element will retain the styles from the last keyframe of the animation after the animation is played.</p>
<p>When set to <code>backwards</code>, the element will take on the styles from the first keyframe of the animation as soon as the animation is played.</p>
<p>When set to <code>both</code>, the element will retain the styles from the first keyframe before the animation starts (behaves like <code>backwards</code>), and it will also retain the styles from the last keyframe after the animation is finished (like <code>forwards</code>).</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This tutorial covered everything you need to know to start creating CSS animations using the <code>@keyframes</code> rule.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@keyframes</span> pulse {
  0% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>) <span class="hljs-built_in">scale</span>(<span class="hljs-number">1</span>);
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
  }
  50% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>) <span class="hljs-built_in">scale</span>(<span class="hljs-number">1.2</span>);
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.7</span>;
  }
  100% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>, -<span class="hljs-number">50%</span>) <span class="hljs-built_in">scale</span>(<span class="hljs-number">1</span>);
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
  }
}
</code></pre>
<p>We also went over several animation-related CSS properties:</p>
<ul>
<li><code>animation-duration</code>: Defines how long the animation will last.</li>
<li><code>animation-iteration-count</code>: Defines how many times the animation will repeat.</li>
<li><code>animation-timing-function</code>: Specifies the timing function, which controls the speed at which the animation is played.</li>
<li><code>animation-direction</code>: The direction in which the animation is played.</li>
<li><code>animation-delay</code>: The delay before the animation begins.</li>
<li><code>animation-fill-mode</code>: Whether or not to retain styles from the animation after it is finished.</li>
</ul>
<p>For further readings on HTML and CSS, check out this course series -&gt; <a target="_blank" href="https://www.ericsdevblog.com/courses/html-css/">HTML &amp; CSS: A Practical Guide</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
